From 524948e871017a22785d9fe019fbab91232d0856 Mon Sep 17 00:00:00 2001 From: Arun Menon Date: Thu, 13 Jun 2013 18:09:42 -0700 Subject: mm-video: rename B-family OMX component This change is needed to support both legacy and v4l2 interfaces to co-exist in hardware/qcom/media. *rename B-family mm-video as mm-video-v4l2. Change-Id: I25ed7be76a58b543e03723b4b6932ac886fbf1c6 --- Android.mk | 2 +- mm-video-v4l2/Android.mk | 6 + mm-video-v4l2/DivxDrmDecrypt/Android.mk | 29 + mm-video-v4l2/DivxDrmDecrypt/inc/DivXDrmDecrypt.h | 49 + .../DivxDrmDecrypt/src/DivXDrmDecrypt.cpp | 98 + mm-video-v4l2/vidc/common/inc/extra_data_handler.h | 114 + .../vidc/common/inc/vidc_color_converter.h | 53 + .../vidc/common/src/extra_data_handler.cpp | 510 + .../vidc/common/src/vidc_color_converter.cpp | 154 + mm-video-v4l2/vidc/vdec/Android.mk | 230 + mm-video-v4l2/vidc/vdec/inc/Map.h | 237 + mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h | 70 + mm-video-v4l2/vidc/vdec/inc/frameparser.h | 105 + mm-video-v4l2/vidc/vdec/inc/h264_utils.h | 479 + mm-video-v4l2/vidc/vdec/inc/hevc_utils.h | 146 + mm-video-v4l2/vidc/vdec/inc/message_queue.h | 78 + mm-video-v4l2/vidc/vdec/inc/mp4_utils.h | 170 + mm-video-v4l2/vidc/vdec/inc/omx_vdec.h | 989 ++ mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h | 961 ++ mm-video-v4l2/vidc/vdec/inc/power_module.h | 42 + mm-video-v4l2/vidc/vdec/inc/qtypes.h | 90 + mm-video-v4l2/vidc/vdec/inc/queue.h | 39 + mm-video-v4l2/vidc/vdec/inc/ts_parser.h | 88 + mm-video-v4l2/vidc/vdec/src/frameparser.cpp | 688 ++ mm-video-v4l2/vidc/vdec/src/h264_utils.cpp | 1700 ++++ mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp | 228 + mm-video-v4l2/vidc/vdec/src/message_queue.c | 178 + mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp | 302 + mm-video-v4l2/vidc/vdec/src/omx_vdec.cpp | 9978 ++++++++++++++++++++ mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp | 9516 +++++++++++++++++++ mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp | 9668 +++++++++++++++++++ mm-video-v4l2/vidc/vdec/src/power_module.cpp | 54 + mm-video-v4l2/vidc/vdec/src/queue.c | 128 + mm-video-v4l2/vidc/vdec/src/ts_parser.cpp | 268 + mm-video-v4l2/vidc/vdec/test/decoder_driver_test.c | 1198 +++ mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp | 4543 +++++++++ mm-video-v4l2/vidc/venc/Android.mk | 172 + mm-video-v4l2/vidc/venc/inc/camera_test.h | 58 + mm-video-v4l2/vidc/venc/inc/fb_test.h | 48 + mm-video-v4l2/vidc/venc/inc/omx_video_base.h | 621 ++ mm-video-v4l2/vidc/venc/inc/omx_video_common.h | 85 + mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h | 89 + mm-video-v4l2/vidc/venc/inc/queue.h | 80 + mm-video-v4l2/vidc/venc/inc/venc_util.h | 53 + mm-video-v4l2/vidc/venc/inc/video_encoder_device.h | 172 + .../vidc/venc/inc/video_encoder_device_v4l2.h | 344 + mm-video-v4l2/vidc/venc/inc/video_encoder_test.h | 76 + mm-video-v4l2/vidc/venc/src/omx_video_base.cpp | 4983 ++++++++++ mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp | 1933 ++++ .../vidc/venc/src/video_encoder_device.cpp | 3235 +++++++ .../vidc/venc/src/video_encoder_device_v4l2.cpp | 3214 +++++++ mm-video-v4l2/vidc/venc/test/camera_test.cpp | 93 + mm-video-v4l2/vidc/venc/test/fb_test.c | 48 + mm-video-v4l2/vidc/venc/test/queue.c | 174 + mm-video-v4l2/vidc/venc/test/venc_test.cpp | 2442 +++++ mm-video-v4l2/vidc/venc/test/venc_util.c | 51 + mm-video-v4l2/vidc/venc/test/video_encoder_test.c | 1064 +++ mm-video/Android.mk | 6 - mm-video/DivxDrmDecrypt/Android.mk | 29 - mm-video/DivxDrmDecrypt/inc/DivXDrmDecrypt.h | 49 - mm-video/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp | 98 - mm-video/vidc/common/inc/extra_data_handler.h | 114 - mm-video/vidc/common/inc/vidc_color_converter.h | 53 - mm-video/vidc/common/src/extra_data_handler.cpp | 510 - mm-video/vidc/common/src/vidc_color_converter.cpp | 154 - mm-video/vidc/vdec/Android.mk | 230 - mm-video/vidc/vdec/inc/Map.h | 237 - mm-video/vidc/vdec/inc/decoder_driver_test.h | 70 - mm-video/vidc/vdec/inc/frameparser.h | 105 - mm-video/vidc/vdec/inc/h264_utils.h | 479 - mm-video/vidc/vdec/inc/hevc_utils.h | 146 - mm-video/vidc/vdec/inc/message_queue.h | 78 - mm-video/vidc/vdec/inc/mp4_utils.h | 170 - mm-video/vidc/vdec/inc/omx_vdec.h | 989 -- mm-video/vidc/vdec/inc/omx_vdec_hevc.h | 961 -- mm-video/vidc/vdec/inc/power_module.h | 42 - mm-video/vidc/vdec/inc/qtypes.h | 90 - mm-video/vidc/vdec/inc/queue.h | 39 - mm-video/vidc/vdec/inc/ts_parser.h | 88 - mm-video/vidc/vdec/src/frameparser.cpp | 688 -- mm-video/vidc/vdec/src/h264_utils.cpp | 1700 ---- mm-video/vidc/vdec/src/hevc_utils.cpp | 228 - mm-video/vidc/vdec/src/message_queue.c | 178 - mm-video/vidc/vdec/src/mp4_utils.cpp | 302 - mm-video/vidc/vdec/src/omx_vdec.cpp | 9978 -------------------- mm-video/vidc/vdec/src/omx_vdec_hevc.cpp | 9516 ------------------- mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp | 9668 ------------------- mm-video/vidc/vdec/src/power_module.cpp | 54 - mm-video/vidc/vdec/src/queue.c | 128 - mm-video/vidc/vdec/src/ts_parser.cpp | 268 - mm-video/vidc/vdec/test/decoder_driver_test.c | 1198 --- mm-video/vidc/vdec/test/omx_vdec_test.cpp | 4543 --------- mm-video/vidc/venc/Android.mk | 172 - mm-video/vidc/venc/inc/camera_test.h | 58 - mm-video/vidc/venc/inc/fb_test.h | 48 - mm-video/vidc/venc/inc/omx_video_base.h | 621 -- mm-video/vidc/venc/inc/omx_video_common.h | 85 - mm-video/vidc/venc/inc/omx_video_encoder.h | 89 - mm-video/vidc/venc/inc/queue.h | 80 - mm-video/vidc/venc/inc/venc_util.h | 53 - mm-video/vidc/venc/inc/video_encoder_device.h | 172 - mm-video/vidc/venc/inc/video_encoder_device_v4l2.h | 344 - mm-video/vidc/venc/inc/video_encoder_test.h | 76 - mm-video/vidc/venc/src/omx_video_base.cpp | 4983 ---------- mm-video/vidc/venc/src/omx_video_encoder.cpp | 1933 ---- mm-video/vidc/venc/src/video_encoder_device.cpp | 3235 ------- .../vidc/venc/src/video_encoder_device_v4l2.cpp | 3214 ------- mm-video/vidc/venc/test/camera_test.cpp | 93 - mm-video/vidc/venc/test/fb_test.c | 48 - mm-video/vidc/venc/test/queue.c | 174 - mm-video/vidc/venc/test/venc_test.cpp | 2442 ----- mm-video/vidc/venc/test/venc_util.c | 51 - mm-video/vidc/venc/test/video_encoder_test.c | 1064 --- 113 files changed, 62222 insertions(+), 62222 deletions(-) create mode 100755 mm-video-v4l2/Android.mk create mode 100755 mm-video-v4l2/DivxDrmDecrypt/Android.mk create mode 100755 mm-video-v4l2/DivxDrmDecrypt/inc/DivXDrmDecrypt.h create mode 100755 mm-video-v4l2/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp create mode 100644 mm-video-v4l2/vidc/common/inc/extra_data_handler.h create mode 100644 mm-video-v4l2/vidc/common/inc/vidc_color_converter.h create mode 100644 mm-video-v4l2/vidc/common/src/extra_data_handler.cpp create mode 100644 mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp create mode 100755 mm-video-v4l2/vidc/vdec/Android.mk create mode 100755 mm-video-v4l2/vidc/vdec/inc/Map.h create mode 100755 mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h create mode 100755 mm-video-v4l2/vidc/vdec/inc/frameparser.h create mode 100755 mm-video-v4l2/vidc/vdec/inc/h264_utils.h create mode 100644 mm-video-v4l2/vidc/vdec/inc/hevc_utils.h create mode 100755 mm-video-v4l2/vidc/vdec/inc/message_queue.h create mode 100644 mm-video-v4l2/vidc/vdec/inc/mp4_utils.h create mode 100644 mm-video-v4l2/vidc/vdec/inc/omx_vdec.h create mode 100644 mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h create mode 100644 mm-video-v4l2/vidc/vdec/inc/power_module.h create mode 100755 mm-video-v4l2/vidc/vdec/inc/qtypes.h create mode 100755 mm-video-v4l2/vidc/vdec/inc/queue.h create mode 100755 mm-video-v4l2/vidc/vdec/inc/ts_parser.h create mode 100755 mm-video-v4l2/vidc/vdec/src/frameparser.cpp create mode 100644 mm-video-v4l2/vidc/vdec/src/h264_utils.cpp create mode 100644 mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp create mode 100755 mm-video-v4l2/vidc/vdec/src/message_queue.c create mode 100644 mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp create mode 100644 mm-video-v4l2/vidc/vdec/src/omx_vdec.cpp create mode 100644 mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp create mode 100644 mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp create mode 100644 mm-video-v4l2/vidc/vdec/src/power_module.cpp create mode 100755 mm-video-v4l2/vidc/vdec/src/queue.c create mode 100644 mm-video-v4l2/vidc/vdec/src/ts_parser.cpp create mode 100755 mm-video-v4l2/vidc/vdec/test/decoder_driver_test.c create mode 100644 mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp create mode 100644 mm-video-v4l2/vidc/venc/Android.mk create mode 100755 mm-video-v4l2/vidc/venc/inc/camera_test.h create mode 100755 mm-video-v4l2/vidc/venc/inc/fb_test.h create mode 100644 mm-video-v4l2/vidc/venc/inc/omx_video_base.h create mode 100755 mm-video-v4l2/vidc/venc/inc/omx_video_common.h create mode 100644 mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h create mode 100755 mm-video-v4l2/vidc/venc/inc/queue.h create mode 100755 mm-video-v4l2/vidc/venc/inc/venc_util.h create mode 100644 mm-video-v4l2/vidc/venc/inc/video_encoder_device.h create mode 100644 mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h create mode 100755 mm-video-v4l2/vidc/venc/inc/video_encoder_test.h create mode 100644 mm-video-v4l2/vidc/venc/src/omx_video_base.cpp create mode 100644 mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp create mode 100644 mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp create mode 100644 mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp create mode 100755 mm-video-v4l2/vidc/venc/test/camera_test.cpp create mode 100755 mm-video-v4l2/vidc/venc/test/fb_test.c create mode 100755 mm-video-v4l2/vidc/venc/test/queue.c create mode 100644 mm-video-v4l2/vidc/venc/test/venc_test.cpp create mode 100755 mm-video-v4l2/vidc/venc/test/venc_util.c create mode 100755 mm-video-v4l2/vidc/venc/test/video_encoder_test.c delete mode 100755 mm-video/Android.mk delete mode 100755 mm-video/DivxDrmDecrypt/Android.mk delete mode 100755 mm-video/DivxDrmDecrypt/inc/DivXDrmDecrypt.h delete mode 100755 mm-video/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp delete mode 100644 mm-video/vidc/common/inc/extra_data_handler.h delete mode 100644 mm-video/vidc/common/inc/vidc_color_converter.h delete mode 100644 mm-video/vidc/common/src/extra_data_handler.cpp delete mode 100644 mm-video/vidc/common/src/vidc_color_converter.cpp delete mode 100755 mm-video/vidc/vdec/Android.mk delete mode 100755 mm-video/vidc/vdec/inc/Map.h delete mode 100755 mm-video/vidc/vdec/inc/decoder_driver_test.h delete mode 100755 mm-video/vidc/vdec/inc/frameparser.h delete mode 100755 mm-video/vidc/vdec/inc/h264_utils.h delete mode 100644 mm-video/vidc/vdec/inc/hevc_utils.h delete mode 100755 mm-video/vidc/vdec/inc/message_queue.h delete mode 100644 mm-video/vidc/vdec/inc/mp4_utils.h delete mode 100644 mm-video/vidc/vdec/inc/omx_vdec.h delete mode 100644 mm-video/vidc/vdec/inc/omx_vdec_hevc.h delete mode 100644 mm-video/vidc/vdec/inc/power_module.h delete mode 100755 mm-video/vidc/vdec/inc/qtypes.h delete mode 100755 mm-video/vidc/vdec/inc/queue.h delete mode 100755 mm-video/vidc/vdec/inc/ts_parser.h delete mode 100755 mm-video/vidc/vdec/src/frameparser.cpp delete mode 100644 mm-video/vidc/vdec/src/h264_utils.cpp delete mode 100644 mm-video/vidc/vdec/src/hevc_utils.cpp delete mode 100755 mm-video/vidc/vdec/src/message_queue.c delete mode 100644 mm-video/vidc/vdec/src/mp4_utils.cpp delete mode 100644 mm-video/vidc/vdec/src/omx_vdec.cpp delete mode 100644 mm-video/vidc/vdec/src/omx_vdec_hevc.cpp delete mode 100644 mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp delete mode 100644 mm-video/vidc/vdec/src/power_module.cpp delete mode 100755 mm-video/vidc/vdec/src/queue.c delete mode 100644 mm-video/vidc/vdec/src/ts_parser.cpp delete mode 100755 mm-video/vidc/vdec/test/decoder_driver_test.c delete mode 100644 mm-video/vidc/vdec/test/omx_vdec_test.cpp delete mode 100644 mm-video/vidc/venc/Android.mk delete mode 100755 mm-video/vidc/venc/inc/camera_test.h delete mode 100755 mm-video/vidc/venc/inc/fb_test.h delete mode 100644 mm-video/vidc/venc/inc/omx_video_base.h delete mode 100755 mm-video/vidc/venc/inc/omx_video_common.h delete mode 100644 mm-video/vidc/venc/inc/omx_video_encoder.h delete mode 100755 mm-video/vidc/venc/inc/queue.h delete mode 100755 mm-video/vidc/venc/inc/venc_util.h delete mode 100644 mm-video/vidc/venc/inc/video_encoder_device.h delete mode 100644 mm-video/vidc/venc/inc/video_encoder_device_v4l2.h delete mode 100755 mm-video/vidc/venc/inc/video_encoder_test.h delete mode 100644 mm-video/vidc/venc/src/omx_video_base.cpp delete mode 100644 mm-video/vidc/venc/src/omx_video_encoder.cpp delete mode 100644 mm-video/vidc/venc/src/video_encoder_device.cpp delete mode 100644 mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp delete mode 100755 mm-video/vidc/venc/test/camera_test.cpp delete mode 100755 mm-video/vidc/venc/test/fb_test.c delete mode 100755 mm-video/vidc/venc/test/queue.c delete mode 100644 mm-video/vidc/venc/test/venc_test.cpp delete mode 100755 mm-video/vidc/venc/test/venc_util.c delete mode 100755 mm-video/vidc/venc/test/video_encoder_test.c diff --git a/Android.mk b/Android.mk index b0beaac7..e5611ce9 100644 --- a/Android.mk +++ b/Android.mk @@ -5,7 +5,7 @@ include $(QCOM_MEDIA_ROOT)/libstagefrighthw/Android.mk endif ifneq ($(filter msm8610 msm8226 msm8974 msm8960 msm8660 msm7630_surf apq8084 mpq8092,$(TARGET_BOARD_PLATFORM)),) -include $(QCOM_MEDIA_ROOT)/mm-video/Android.mk +include $(QCOM_MEDIA_ROOT)/mm-video-v4l2/Android.mk endif ifneq ($(filter msm8610 msm8226 msm8974 msm8960 apq8084 mpq8092,$(TARGET_BOARD_PLATFORM)),) diff --git a/mm-video-v4l2/Android.mk b/mm-video-v4l2/Android.mk new file mode 100755 index 00000000..2d0a5335 --- /dev/null +++ b/mm-video-v4l2/Android.mk @@ -0,0 +1,6 @@ +OMX_VIDEO_PATH := $(call my-dir) +include $(CLEAR_VARS) + +include $(OMX_VIDEO_PATH)/vidc/vdec/Android.mk +include $(OMX_VIDEO_PATH)/vidc/venc/Android.mk +include $(OMX_VIDEO_PATH)/DivxDrmDecrypt/Android.mk diff --git a/mm-video-v4l2/DivxDrmDecrypt/Android.mk b/mm-video-v4l2/DivxDrmDecrypt/Android.mk new file mode 100755 index 00000000..38862260 --- /dev/null +++ b/mm-video-v4l2/DivxDrmDecrypt/Android.mk @@ -0,0 +1,29 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +#=============================================================================== +# Deploy the headers that can be exposed +#=============================================================================== + +LOCAL_COPY_HEADERS_TO := mm-video-v4l2/DivxDrmDecrypt +LOCAL_COPY_HEADERS := inc/DivXDrmDecrypt.h + +LOCAL_CFLAGS := \ + -D_ANDROID_ + +LOCAL_SRC_FILES:= \ + src/DivXDrmDecrypt.cpp + +LOCAL_C_INCLUDES:= \ + $(LOCAL_PATH)/inc \ + $(TARGET_OUT_HEADERS)/mm-core/omxcore + +LOCAL_PRELINK_MODULE:= false + +LOCAL_MODULE:= libdivxdrmdecrypt +LOCAL_MODULE_TAGS := optional + +LOCAL_SHARED_LIBRARIES := liblog libdl + +LOCAL_LDLIBS += +include $(BUILD_SHARED_LIBRARY) diff --git a/mm-video-v4l2/DivxDrmDecrypt/inc/DivXDrmDecrypt.h b/mm-video-v4l2/DivxDrmDecrypt/inc/DivXDrmDecrypt.h new file mode 100755 index 00000000..4b0b707d --- /dev/null +++ b/mm-video-v4l2/DivxDrmDecrypt/inc/DivXDrmDecrypt.h @@ -0,0 +1,49 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#ifndef __DIVXDRMDECRYPT_H__ +#define __DIVXDRMDECRYPT_H__ + +#include + +//Abstract base class of API to decrypt DRM content. +class DivXDrmDecrypt +{ +public: + static DivXDrmDecrypt* Create(); + virtual OMX_ERRORTYPE Init() = 0; + virtual OMX_ERRORTYPE Decrypt(OMX_BUFFERHEADERTYPE* buffer) = 0; + inline virtual ~DivXDrmDecrypt() {} +}; + +//.so file should provide a function with the name createDivXDrmDecrypt with +//prototype of DivXDrmDecryptFactory. +static const char* MEDIA_CREATE_DIVX_DRM_DECRYPT = "createDivXDrmDecrypt"; +typedef DivXDrmDecrypt* (*DivXDrmDecryptFactory)(); + +#endif //__DIVXDRMDECRYPT_H__ diff --git a/mm-video-v4l2/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp b/mm-video-v4l2/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp new file mode 100755 index 00000000..ff4a382a --- /dev/null +++ b/mm-video-v4l2/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp @@ -0,0 +1,98 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#include "DivXDrmDecrypt.h" +#include // for dlopen/dlclose + +//#define LOG_NDEBUG 0 +#define LOG_TAG "DivXDrmDecrypt" +#ifdef _ANDROID_ +#include +#else +#include +#define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args) +#endif /* _ANDROID_ */ + +static const char* DIVX_DRM_SHIM_LIB = "libSHIMDivxDrm.so"; + +void* getDecryptHandle() { + static void* decryptLib = NULL; + static bool decryptLibOpened = false; + + if(decryptLibOpened) { + return decryptLib; + } + + decryptLib = ::dlopen(DIVX_DRM_SHIM_LIB, RTLD_NOW); + decryptLibOpened = true; + + if (decryptLib == NULL) { + ALOGE("Failed to open DIVX_DRM_SHIM_LIB \n"); + } + + return decryptLib; +} + +DivXDrmDecryptFactory DrmDecryptFactoryFunction() { + static DivXDrmDecryptFactory drmDecryptFactoryFunction = NULL; + static bool alreadyTriedToFindFactoryFunction = false; + + if(alreadyTriedToFindFactoryFunction) { + return drmDecryptFactoryFunction; + } + + void *pDecryptLib = getDecryptHandle(); + if (pDecryptLib == NULL) { + return NULL; + } + + drmDecryptFactoryFunction = (DivXDrmDecryptFactory) dlsym(pDecryptLib, MEDIA_CREATE_DIVX_DRM_DECRYPT); + alreadyTriedToFindFactoryFunction = true; + + if(!drmDecryptFactoryFunction) { + ALOGE(" dlsym for DrmDecrypt factory function failed \n"); + } + + return drmDecryptFactoryFunction; +} + + + +DivXDrmDecrypt* DivXDrmDecrypt::Create() { + DivXDrmDecryptFactory drmCreateFunc = DrmDecryptFactoryFunction(); + if( drmCreateFunc == NULL ) { + return NULL; + } + + DivXDrmDecrypt* decrypt = drmCreateFunc(); + if( decrypt == NULL ) { + ALOGE(" failed to instantiate DrmDecoder \n"); + } + return decrypt; +} + diff --git a/mm-video-v4l2/vidc/common/inc/extra_data_handler.h b/mm-video-v4l2/vidc/common/inc/extra_data_handler.h new file mode 100644 index 00000000..c7b6e7bb --- /dev/null +++ b/mm-video-v4l2/vidc/common/inc/extra_data_handler.h @@ -0,0 +1,114 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#ifndef __EXTRA_DATA_HANDLER_H__ +#define __EXTRA_DATA_HANDLER_H__ + +#include +#include +#include +#include +#include "OMX_QCOMExtns.h" +#include +#include + + +#ifdef _ANDROID_ +extern "C"{ +#include +} +#ifdef ENABLE_DEBUG_LOW +#undef DEBUG_PRINT_LOW +#define DEBUG_PRINT_LOW ALOGE +#else +#undef DEBUG_PRINT_LOW +#define DEBUG_PRINT_LOW +#endif +#ifdef ENABLE_DEBUG_HIGH +#undef DEBUG_PRINT_HIGH +#define DEBUG_PRINT_HIGH ALOGE +#else +#undef DEBUG_PRINT_HIGH +#define DEBUG_PRINT_HIGH +#endif +#ifdef ENABLE_DEBUG_ERROR +#undef DEBUG_PRINT_ERROR +#define DEBUG_PRINT_ERROR ALOGE +#else +#undef DEBUG_PRINT_ERROR +#define DEBUG_PRINT_ERROR +#endif + +#else //_ANDROID_ +#undef DEBUG_PRINT_LOW +#undef DEBUG_PRINT_HIGH +#undef DEBUG_PRINT_ERROR +#define DEBUG_PRINT_LOW printf +#define DEBUG_PRINT_HIGH printf +#define DEBUG_PRINT_ERROR printf +#endif // _ANDROID_ + +#define SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT 0x2D +#define H264_START_CODE 0x01 +#define NAL_TYPE_SEI 0x06 +#define VDEC_OMX_SEI 0x7F000007 +#define FRAME_PACK_SIZE 18 +#define H264_EMULATION_BYTE 0x03 +class extra_data_handler +{ +public: + extra_data_handler(); + ~extra_data_handler(); + OMX_U32 parse_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr); + OMX_U32 create_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr); + OMX_U32 get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); + OMX_U32 set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); +private: + OMX_QCOM_FRAME_PACK_ARRANGEMENT frame_packing_arrangement; + OMX_U8 *rbsp_buf; + OMX_U32 bit_ptr; + OMX_U32 byte_ptr; + OMX_U32 pack_sei; + OMX_U32 sei_payload_type; + OMX_U32 d_u(OMX_U32 num_bits); + OMX_U32 d_ue(); + OMX_U32 parse_frame_pack(OMX_U32 payload_size); + OMX_S32 parse_rbsp(OMX_U8 *buf, OMX_U32 len); + OMX_S32 parse_sei(OMX_U8 *buffer, OMX_U32 buffer_length); + OMX_U32 e_u(OMX_U32 symbol, OMX_U32 num_bits); + OMX_U32 e_ue(OMX_U32 symbol); + OMX_U32 create_frame_pack(); + OMX_S32 create_rbsp(OMX_U8 *buf, OMX_U32 nalu_type); + OMX_U32 create_sei(OMX_U8 *buffer); + OMX_S32 parse_sliceinfo(OMX_BUFFERHEADERTYPE *pBufHdr, + OMX_OTHER_EXTRADATATYPE *pExtra); + OMX_S32 parse_ltrinfo(OMX_BUFFERHEADERTYPE *pBufHdr, + OMX_OTHER_EXTRADATATYPE *pExtra); +}; + +#endif diff --git a/mm-video-v4l2/vidc/common/inc/vidc_color_converter.h b/mm-video-v4l2/vidc/common/inc/vidc_color_converter.h new file mode 100644 index 00000000..bbfbdaea --- /dev/null +++ b/mm-video-v4l2/vidc/common/inc/vidc_color_converter.h @@ -0,0 +1,53 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include +#include "C2DColorConverter.h" + +using namespace android; +class omx_c2d_conv { +public: + omx_c2d_conv(); + ~omx_c2d_conv(); + bool init(); + void destroy(); + bool open(unsigned int height,unsigned int width, + ColorConvertFormat src, + ColorConvertFormat dest); + bool convert(int src_fd, void *src_base, void *src_viraddr, + int dest_fd, void *dest_base, void *dest_viraddr); + bool get_buffer_size(int port,unsigned int &buf_size); + int get_src_format(); + void close(); +private: + C2DColorConverterBase *c2dcc; + void *mLibHandle; + ColorConvertFormat src_format; + createC2DColorConverter_t *mConvertOpen; + destroyC2DColorConverter_t *mConvertClose; +}; diff --git a/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp b/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp new file mode 100644 index 00000000..aa3b563b --- /dev/null +++ b/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp @@ -0,0 +1,510 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#include "extra_data_handler.h" + +extra_data_handler::extra_data_handler() +{ + rbsp_buf = (OMX_U8 *) calloc(1,100); + memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement)); + frame_packing_arrangement.cancel_flag = 1; + pack_sei = false; + sei_payload_type = -1; +} + +extra_data_handler::~extra_data_handler() +{ + if(rbsp_buf) { + free(rbsp_buf); + rbsp_buf = NULL; + } +} + +OMX_U32 extra_data_handler::d_u(OMX_U32 num_bits) +{ + OMX_U32 rem_bits = num_bits, bins = 0, shift = 0; + + while(rem_bits >= bit_ptr) { + DEBUG_PRINT_LOW("\nIn %s() bit_ptr/byte_ptr :%d/%d/%x", __func__, bit_ptr, + byte_ptr, rbsp_buf[byte_ptr]); + bins <<= shift; + shift = (8-bit_ptr); + bins |= ((rbsp_buf[byte_ptr] << shift) & 0xFF) >> shift; + rem_bits -= bit_ptr; + bit_ptr = 8; + byte_ptr ++; + } + DEBUG_PRINT_LOW("\nIn %s() bit_ptr/byte_ptr :%d/%d/%x", __func__, bit_ptr, + byte_ptr, rbsp_buf[byte_ptr]); + + if (rem_bits) { + bins <<= rem_bits; + bins |= ((rbsp_buf[byte_ptr] << (8-bit_ptr)) & 0xFF) >> (8-rem_bits); + bit_ptr -= rem_bits; + if (bit_ptr == 0) { + bit_ptr = 8; + byte_ptr++; + } + } + DEBUG_PRINT_LOW("\nIn %s() bit_ptr/byte_ptr :%d/%d/%x", __func__, bit_ptr, + byte_ptr, rbsp_buf[byte_ptr]); + + DEBUG_PRINT_LOW("\nIn %s() bin/num_bits : %x/%d", __func__, bins, num_bits); + return bins; +} + +OMX_U32 extra_data_handler::d_ue() +{ + OMX_S32 lead_zeros = -1; + OMX_U32 symbol, bit; + do{ + bit = d_u(1); + lead_zeros++; + }while (!bit); + + symbol = ((1 << lead_zeros) - 1) + d_u(lead_zeros); + + DEBUG_PRINT_LOW("\nIn %s() symbol : %d", __func__,symbol); + return symbol; +} + +OMX_U32 extra_data_handler::parse_frame_pack(OMX_U32 payload_size) +{ + frame_packing_arrangement.id = d_ue(); + frame_packing_arrangement.cancel_flag = d_u(1); + if(!frame_packing_arrangement.cancel_flag) { + frame_packing_arrangement.type = d_u(7); + frame_packing_arrangement.quincunx_sampling_flag = d_u(1); + frame_packing_arrangement.content_interpretation_type = d_u(6); + frame_packing_arrangement.spatial_flipping_flag = d_u(1); + frame_packing_arrangement.frame0_flipped_flag = d_u(1); + frame_packing_arrangement.field_views_flag = d_u(1); + frame_packing_arrangement.current_frame_is_frame0_flag = d_u(1); + frame_packing_arrangement.frame0_self_contained_flag = d_u(1); + frame_packing_arrangement.frame1_self_contained_flag = d_u(1); + + if(!frame_packing_arrangement.quincunx_sampling_flag && + frame_packing_arrangement.type != 5) { + frame_packing_arrangement.frame0_grid_position_x = d_u(4); + frame_packing_arrangement.frame0_grid_position_y = d_u(4); + frame_packing_arrangement.frame1_grid_position_x = d_u(4); + frame_packing_arrangement.frame1_grid_position_y = d_u(4); + } + frame_packing_arrangement.reserved_byte = d_u(8); + frame_packing_arrangement.repetition_period = d_ue(); + } + frame_packing_arrangement.extension_flag = d_u(1); + + return 1; +} + +OMX_S32 extra_data_handler::parse_rbsp(OMX_U8 *buf, OMX_U32 len) +{ + OMX_U32 i = 3, j=0, startcode; + OMX_U32 nal_unit_type, nal_ref_idc, forbidden_zero_bit; + + bit_ptr = 8; + byte_ptr = 0; + + startcode = buf[0] << 16 | buf[1] <<8 | buf[2]; + + if (!startcode) { + startcode |= buf[i++]; + } + if(startcode != H264_START_CODE) { + DEBUG_PRINT_ERROR("\nERROR: In %s() Start code not found", __func__); + return -1; + } + forbidden_zero_bit = (buf[i] & 0x80) >>7; + if(forbidden_zero_bit) { + DEBUG_PRINT_ERROR("\nERROR: In %s() Non-zero forbidden bit", __func__); + return -1; + } + nal_ref_idc = (buf[i] & 0x60) >>5; + DEBUG_PRINT_LOW("\nIn %s() nal_ref_idc ; %d", __func__, nal_ref_idc); + + nal_unit_type = (buf[i++] & 0x1F); + + while(ieType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoLTRInfo; + pLTR = (OMX_U32* )pExtra + 5; + DEBUG_PRINT_HIGH("ExtraData LTR ID %d", *pLTR, 0, 0); + return 0; +} +/*====================================================================== + Slice Information will be available as below (each line is of 4 bytes) + | number of slices | + | 1st slice offset | + | 1st slice size | + | .. | + | Nth slice offset | + | Nth slice size | +======================================================================*/ +OMX_S32 extra_data_handler::parse_sliceinfo( + OMX_BUFFERHEADERTYPE *pBufHdr, OMX_OTHER_EXTRADATATYPE *pExtra) +{ + OMX_U32 slice_offset = 0, slice_size = 0, total_size = 0; + OMX_U8 *pBuffer = (OMX_U8 *)pBufHdr->pBuffer; + OMX_U32 *data = (OMX_U32 *)pExtra->data; + OMX_U32 num_slices = *data; + DEBUG_PRINT_LOW("number of slices = %d", num_slices); + if ((4 + num_slices * 8) != (OMX_U32)pExtra->nDataSize) { + DEBUG_PRINT_ERROR("unknown error in slice info extradata"); + return -1; + } + for (int i = 0; i < num_slices; i++) { + slice_offset = (OMX_U32)(*(data + (i*2 + 1))); + if ((*(pBuffer + slice_offset + 0) != 0x00) || + (*(pBuffer + slice_offset + 1) != 0x00) || + (*(pBuffer + slice_offset + 2) != 0x00) || + (*(pBuffer + slice_offset + 3) != H264_START_CODE)) { + DEBUG_PRINT_ERROR("found 0x%x instead of start code at offset[%d] " + "for slice[%d]", (OMX_U32)(*(OMX_U32 *)(pBuffer + slice_offset)), + slice_offset, i); + return -1; + } + if (slice_offset != total_size) { + DEBUG_PRINT_ERROR("offset of slice number %d is not correct " + "or previous slice size is not correct", i); + return -1; + } + slice_size = (OMX_U32)(*(data + (i*2 + 2))); + total_size += slice_size; + DEBUG_PRINT_LOW("slice number %d offset/size = %d/%d", + i, slice_offset, slice_size); + } + if (pBufHdr->nFilledLen != total_size) { + DEBUG_PRINT_ERROR("frame_size[%d] is not equal to " + "total slices size[%d]", pBufHdr->nFilledLen, total_size); + return -1; + } + return 0; +} + +OMX_U32 extra_data_handler::parse_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr) +{ + DEBUG_PRINT_LOW("In %s() flags: 0x%x", __func__,buf_hdr->nFlags); + + if (buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) { + + OMX_OTHER_EXTRADATATYPE *extra_data = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(buf_hdr->pBuffer + buf_hdr->nOffset + + buf_hdr->nFilledLen + 3)&(~3)); + + while(extra_data && + ((OMX_U32)extra_data > (OMX_U32)buf_hdr->pBuffer) && + ((OMX_U32)extra_data < (OMX_U32)buf_hdr->pBuffer + buf_hdr->nAllocLen)) { + + DEBUG_PRINT_LOW("extradata(0x%x): nSize = 0x%x, eType = 0x%x," + " nDataSize = 0x%x", (unsigned)extra_data, extra_data->nSize, + extra_data->eType, extra_data->nDataSize); + + if ((extra_data->eType == VDEC_EXTRADATA_NONE) || + (extra_data->eType == VEN_EXTRADATA_NONE)) { + DEBUG_PRINT_LOW("No more extradata available"); + extra_data->eType = OMX_ExtraDataNone; + break; + } + else if (extra_data->eType == VDEC_EXTRADATA_SEI) { + DEBUG_PRINT_LOW("Extradata SEI of size %d found, " + "parsing it", extra_data->nDataSize); + parse_sei(extra_data->data, extra_data->nDataSize); + } + else if (extra_data->eType == VEN_EXTRADATA_QCOMFILLER) { + DEBUG_PRINT_LOW("Extradata Qcom Filler found, skip %d bytes", + extra_data->nSize); + } + else if (extra_data->eType == VEN_EXTRADATA_SLICEINFO) { + DEBUG_PRINT_LOW("Extradata SliceInfo of size %d found, " + "parsing it", extra_data->nDataSize); + parse_sliceinfo(buf_hdr, extra_data); + } +#ifndef _MSM8974_ + else if (extra_data->eType == VEN_EXTRADATA_LTRINFO) { + DEBUG_PRINT_LOW("Extradata LTRInfo of size %d found, " + "parsing it", extra_data->nDataSize); + parse_ltrinfo(buf_hdr, extra_data); + } +#endif + else { + DEBUG_PRINT_ERROR("Unknown extradata(0x%x) found, nSize = 0x%x, " + "eType = 0x%x, nDataSize = 0x%x", (unsigned)extra_data, + extra_data->nSize, extra_data->eType, extra_data->nDataSize); + buf_hdr->nFlags &= ~(OMX_BUFFERFLAG_EXTRADATA); + break; + } + extra_data = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) extra_data) + + extra_data->nSize); + } + } + return 1; +} + +OMX_U32 extra_data_handler::get_frame_pack_data( + OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack) +{ + DEBUG_PRINT_LOW("\n%s:%d get frame data", __func__, __LINE__); + memcpy(&frame_pack->id,&frame_packing_arrangement.id, + FRAME_PACK_SIZE*sizeof(OMX_U32)); + return 1; +} + +OMX_U32 extra_data_handler::set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT + *frame_pack) +{ + DEBUG_PRINT_LOW("\n%s:%d set frame data", __func__, __LINE__); + memcpy(&frame_packing_arrangement.id, &frame_pack->id, + FRAME_PACK_SIZE*sizeof(OMX_U32)); + pack_sei = true; + sei_payload_type = SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT; + return 1; +} + +OMX_U32 extra_data_handler::e_u(OMX_U32 symbol, OMX_U32 num_bits) +{ + OMX_U32 rem_bits = num_bits, shift; + + DEBUG_PRINT_LOW("\n%s bin : %x/%d", __func__, symbol, num_bits); + + while(rem_bits >= bit_ptr) { + shift = rem_bits - bit_ptr; + rbsp_buf[byte_ptr] |= (symbol >> shift); + symbol = (symbol << (32 - shift)) >> (32 - shift); + rem_bits -= bit_ptr; + DEBUG_PRINT_LOW("\n%sstream byte/rem_bits %x/%d", __func__, + rbsp_buf[byte_ptr], rem_bits); + byte_ptr ++; + bit_ptr = 8; + } + + if(rem_bits) { + shift = bit_ptr - rem_bits; + rbsp_buf[byte_ptr] |= (symbol << shift); + bit_ptr -= rem_bits; + DEBUG_PRINT_LOW("\n%s 2 stream byte/rem_bits %x", __func__, + rbsp_buf[byte_ptr], rem_bits); + if(bit_ptr == 0) { + bit_ptr = 8; + byte_ptr++; + } + } + return 1; +} + +OMX_U32 extra_data_handler::e_ue(OMX_U32 symbol) +{ + OMX_U32 i, sym_len, sufix_len, info; + OMX_U32 nn =(symbol + 1) >> 1; + + DEBUG_PRINT_LOW("\n%s bin : %x", __func__, symbol); + + for(i=0; i < 33 && nn != 0; i++) + nn >>= 1; + + sym_len = ((i << 1) + 1); + info = symbol + 1 - (1 << i); + sufix_len = (1 << (sym_len >>1)); + info = sufix_len | (info & (sufix_len - 1)); + e_u(info, sym_len); + return 1; +} + +OMX_U32 extra_data_handler::create_frame_pack() +{ + e_ue(frame_packing_arrangement.id); + e_u(frame_packing_arrangement.cancel_flag, 1); + if(!frame_packing_arrangement.cancel_flag) { + e_u(frame_packing_arrangement.type, 7); + e_u(frame_packing_arrangement.quincunx_sampling_flag, 1); + e_u(frame_packing_arrangement.content_interpretation_type, 6); + e_u(frame_packing_arrangement.spatial_flipping_flag, 1); + e_u(frame_packing_arrangement.frame0_flipped_flag, 1); + e_u(frame_packing_arrangement.field_views_flag, 1); + e_u(frame_packing_arrangement.current_frame_is_frame0_flag, 1); + e_u(frame_packing_arrangement.frame0_self_contained_flag, 1); + e_u(frame_packing_arrangement.frame1_self_contained_flag, 1); + if(!frame_packing_arrangement.quincunx_sampling_flag && + frame_packing_arrangement.type != 5) { + e_u(frame_packing_arrangement.frame0_grid_position_x, 4); + e_u(frame_packing_arrangement.frame0_grid_position_y, 4); + e_u(frame_packing_arrangement.frame1_grid_position_x, 4); + e_u(frame_packing_arrangement.frame1_grid_position_y, 4); + } + e_u(frame_packing_arrangement.reserved_byte, 8); + e_ue(frame_packing_arrangement.repetition_period); + } + e_u(frame_packing_arrangement.extension_flag, 1); + return 1; +} + +OMX_S32 extra_data_handler::create_rbsp(OMX_U8 *buf, OMX_U32 nalu_type) +{ + OMX_U32 i, j = 7; + for(i = 0;i < 3;i++) + *buf++ = 0x00; + *buf++ = H264_START_CODE; + *buf++ = nalu_type; + *buf++ = (sei_payload_type & 0x000000FF); + *buf++ = byte_ptr - 1; //payload will contain 1 byte of rbsp_trailing_bits + //that shouldn't be taken into account + + for(i = 0;i < byte_ptr ;i += 2) { + *buf++ = rbsp_buf[i]; + j++; + if(i+1 < byte_ptr) { + *buf++ = rbsp_buf[i+1]; + j++; + if(!(rbsp_buf[i] + rbsp_buf[i+1])) { + *buf++ = H264_EMULATION_BYTE; + j++; + } + } + } + + DEBUG_PRINT_LOW("\n%s rbsp length %d", __func__, j); + return j; +} + +OMX_U32 extra_data_handler::create_sei(OMX_U8 *buffer) +{ + OMX_U32 i, ret_val = 0; + + byte_ptr = 0; + bit_ptr = 8; + + if(sei_payload_type == SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT) { + create_frame_pack(); + + if(bit_ptr != 8) { + e_u(1,1); + if(bit_ptr != 8) + e_u(0,bit_ptr); + } + + //Payload will have been byte aligned by now, + //insert the rbsp trailing bits + e_u(1, 1); + e_u(0, 7); + + ret_val = create_rbsp(buffer, NAL_TYPE_SEI); + } + + pack_sei = false; + sei_payload_type = -1; + + return ret_val; +} + +OMX_U32 extra_data_handler::create_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr) +{ + OMX_U8 *buffer = (OMX_U8 *) ((unsigned)(buf_hdr->pBuffer + + buf_hdr->nOffset + buf_hdr->nFilledLen)); + OMX_U32 msg_size; + + if(buf_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + DEBUG_PRINT_LOW("\n%s:%d create extra data with config", __func__, + __LINE__); + if(pack_sei) { + msg_size = create_sei(buffer); + if( msg_size > 0) + buf_hdr->nFilledLen += msg_size; + } + } + return 1; +} + diff --git a/mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp b/mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp new file mode 100644 index 00000000..e75dd3ca --- /dev/null +++ b/mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp @@ -0,0 +1,154 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include +#include +#include "vidc_color_converter.h" +#undef DEBUG_PRINT_LOW +#undef DEBUG_PRINT_HIGH +#undef DEBUG_PRINT_ERROR + +#define DEBUG_PRINT_LOW ALOGV +#define DEBUG_PRINT_HIGH ALOGE +#define DEBUG_PRINT_ERROR ALOGE + +omx_c2d_conv::omx_c2d_conv() +{ + c2dcc = NULL; + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; + src_format = NV12_2K; +} + +bool omx_c2d_conv::init() { + bool status = true; + if(mLibHandle || mConvertOpen || mConvertClose) { + DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice"); + status = false; + } + if(status) { + mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); + if(mLibHandle){ + mConvertOpen = (createC2DColorConverter_t *) + dlsym(mLibHandle,"createC2DColorConverter"); + mConvertClose = (destroyC2DColorConverter_t *) + dlsym(mLibHandle,"destroyC2DColorConverter"); + if(!mConvertOpen || !mConvertClose) + status = false; + } else + status = false; + } + if(!status && mLibHandle){ + dlclose(mLibHandle); + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; + } + return status; +} + +bool omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, + int dest_fd, void *dest_base, void *dest_viraddr) +{ + int result; + if(!src_viraddr || !dest_viraddr || !c2dcc || !dest_base || !src_base){ + DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); + return false; + } + result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, + dest_fd, dest_base, dest_viraddr); + DEBUG_PRINT_LOW("\n Color convert status %d",result); + return ((result < 0)?false:true); +} + +bool omx_c2d_conv::open(unsigned int height,unsigned int width, + ColorConvertFormat src, ColorConvertFormat dest) +{ + bool status = false; + if(!c2dcc) { + c2dcc = mConvertOpen(width, height, width, height, + src,dest,0,0); + if(c2dcc) { + src_format = src; + status = true; + } else + DEBUG_PRINT_ERROR("\n mConvertOpen failed"); + } + return status; +} +void omx_c2d_conv::close() +{ + if(mLibHandle) { + if(mConvertClose && c2dcc) + mConvertClose(c2dcc); + c2dcc = NULL; + } +} + +void omx_c2d_conv::destroy() +{ + DEBUG_PRINT_ERROR("\n Destroy C2D instance"); + if(mLibHandle) { + if(mConvertClose && c2dcc) + mConvertClose(c2dcc); + dlclose(mLibHandle); + } + c2dcc = NULL; + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; +} +omx_c2d_conv::~omx_c2d_conv() +{ + destroy(); +} +int omx_c2d_conv::get_src_format() +{ + int format = -1; + if(src_format == NV12_2K) { + format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; + } else if(src_format == RGBA8888) { + format = HAL_PIXEL_FORMAT_RGBA_8888; + } + return format; +} +bool omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) +{ + int cret = 0; + bool ret = false; + C2DBuffReq bufferreq; + if(c2dcc){ + bufferreq.size = 0; + cret = c2dcc->getBuffReq(port,&bufferreq); + DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret); + ret = (cret)?false:true; + buf_size = bufferreq.size; + } + return ret; +} diff --git a/mm-video-v4l2/vidc/vdec/Android.mk b/mm-video-v4l2/vidc/vdec/Android.mk new file mode 100755 index 00000000..97ff2973 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/Android.mk @@ -0,0 +1,230 @@ +ifneq ($(BUILD_TINY_ANDROID),true) + +ROOT_DIR := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_PATH:= $(ROOT_DIR) + +# --------------------------------------------------------------------------------- +# Common definitons +# --------------------------------------------------------------------------------- + +libOmxVdec-def := -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\) +libOmxVdec-def += -D__align=__alignx +libOmxVdec-def += -Dinline=__inline +libOmxVdec-def += -g -O3 +libOmxVdec-def += -DIMAGE_APPS_PROC +libOmxVdec-def += -D_ANDROID_ +libOmxVdec-def += -DCDECL +libOmxVdec-def += -DT_ARM +libOmxVdec-def += -DNO_ARM_CLZ +libOmxVdec-def += -UENABLE_DEBUG_LOW +libOmxVdec-def += -DENABLE_DEBUG_HIGH +libOmxVdec-def += -DENABLE_DEBUG_ERROR +libOmxVdec-def += -UINPUT_BUFFER_LOG +libOmxVdec-def += -UOUTPUT_BUFFER_LOG +ifeq ($(TARGET_BOARD_PLATFORM),msm8660) +libOmxVdec-def += -DMAX_RES_1080P +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libOmxVdec-def += -DTEST_TS_FROM_SEI +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8960) +libOmxVdec-def += -DMAX_RES_1080P +libOmxVdec-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libOmxVdec-def += -D_MSM8960_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8974) +libOmxVdec-def += -DMAX_RES_1080P +libOmxVdec-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libOmxVdec-def += -D_MSM8974_ +libOmxVdec-def += -D_HEVC_USE_ADSP_HEAP_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm7627a) +libOmxVdec-def += -DMAX_RES_720P +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm7630_surf) +libOmxVdec-def += -DMAX_RES_720P +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8610) +libOmxVdec-def += -DMAX_RES_1080P +libOmxVdec-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libOmxVdec-def += -DSMOOTH_STREAMING_DISABLED +libOmxVdec-def += -DH264_PROFILE_LEVEL_CHECK +libOmxVdec-def += -D_MSM8974_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8226) +libOmxVdec-def += -DMAX_RES_1080P +libOmxVdec-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libOmxVdec-def += -D_MSM8974_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),apq8084) +libOmxVdec-def += -DMAX_RES_1080P +libOmxVdec-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libOmxVdec-def += -D_MSM8974_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),mpq8092) +libOmxVdec-def += -DMAX_RES_1080P +libOmxVdec-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libOmxVdec-def += -D_MSM8974_ +endif +libOmxVdec-def += -D_ANDROID_ICS_ + +ifeq ($(TARGET_USES_ION),true) +libOmxVdec-def += -DUSE_ION +endif + +ifneq ($(call is-platform-sdk-version-at-least,18),true) +libOmxVdec-def += -DANDROID_JELLYBEAN_MR1=1 +endif + +vdec-inc = $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include + +# --------------------------------------------------------------------------------- +# Make the Shared library (libOmxVdec) +# --------------------------------------------------------------------------------- + +include $(CLEAR_VARS) +LOCAL_PATH:= $(ROOT_DIR) + +libmm-vdec-inc := bionic/libc/include +libmm-vdec-inc += bionic/libstdc++/include +libmm-vdec-inc += $(LOCAL_PATH)/inc +libmm-vdec-inc += $(OMX_VIDEO_PATH)/vidc/common/inc +libmm-vdec-inc += hardware/qcom/media/mm-core/inc +#DRM include - Interface which loads the DRM library +libmm-vdec-inc += $(OMX_VIDEO_PATH)/DivxDrmDecrypt/inc +libmm-vdec-inc += hardware/qcom/display/libgralloc +libmm-vdec-inc += hardware/qcom/display/libgenlock +libmm-vdec-inc += frameworks/native/include/media/openmax +libmm-vdec-inc += frameworks/native/include/media/hardware +libmm-vdec-inc += $(vdec-inc) +libmm-vdec-inc += hardware/qcom/display/libqdutils +libmm-vdec-inc += hardware/qcom/media/libc2dcolorconvert +libmm-vdec-inc += hardware/qcom/display/libcopybit +libmm-vdec-inc += frameworks/av/include/media/stagefright + + +LOCAL_MODULE := libOmxVdec +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := $(libOmxVdec-def) +LOCAL_C_INCLUDES += $(libmm-vdec-inc) + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils libdl + +LOCAL_SHARED_LIBRARIES += libgenlock +LOCAL_SHARED_LIBRARIES += libdivxdrmdecrypt +LOCAL_SHARED_LIBRARIES += libqdMetaData + +LOCAL_SRC_FILES := src/frameparser.cpp +LOCAL_SRC_FILES += src/h264_utils.cpp +LOCAL_SRC_FILES += src/ts_parser.cpp +LOCAL_SRC_FILES += src/mp4_utils.cpp +ifeq ($(call is-board-platform-in-list,msm8974 msm8610 msm8226 apq8084 mpq8092),true) +LOCAL_SRC_FILES += src/omx_vdec_msm8974.cpp +else +LOCAL_SHARED_LIBRARIES += libhardware +libmm-vdec-inc += hardware/qcom/display/libhwcomposer +LOCAL_SRC_FILES += src/power_module.cpp +LOCAL_SRC_FILES += src/omx_vdec.cpp +endif + +LOCAL_SRC_FILES += ../common/src/extra_data_handler.cpp +LOCAL_SRC_FILES += ../common/src/vidc_color_converter.cpp +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + +include $(BUILD_SHARED_LIBRARY) + + +# --------------------------------------------------------------------------------- +# Make the Shared library (libOmxVdecHevc) +# --------------------------------------------------------------------------------- + +include $(CLEAR_VARS) +LOCAL_PATH:= $(ROOT_DIR) + +ifeq ($(call is-board-platform-in-list,msm8974 msm8610 apq8084 mpq8092),true) + +LOCAL_MODULE := libOmxVdecHevc +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := $(libOmxVdec-def) +LOCAL_C_INCLUDES += $(libmm-vdec-inc) + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils libdl + +LOCAL_SHARED_LIBRARIES += libgenlock +LOCAL_SHARED_LIBRARIES += libdivxdrmdecrypt +LOCAL_SHARED_LIBRARIES += libqdMetaData + +LOCAL_SRC_FILES := src/frameparser.cpp +LOCAL_SRC_FILES += src/h264_utils.cpp +LOCAL_SRC_FILES += src/ts_parser.cpp +LOCAL_SRC_FILES += src/mp4_utils.cpp + +LOCAL_SRC_FILES += src/omx_vdec_hevc.cpp +LOCAL_SRC_FILES += src/hevc_utils.cpp + +LOCAL_SRC_FILES += ../common/src/extra_data_handler.cpp +LOCAL_SRC_FILES += ../common/src/vidc_color_converter.cpp +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + +include $(BUILD_SHARED_LIBRARY) + +endif + +# --------------------------------------------------------------------------------- +# Make the apps-test (mm-vdec-omx-test) +# --------------------------------------------------------------------------------- +include $(CLEAR_VARS) + +mm-vdec-test-inc := hardware/qcom/media/mm-core/inc +mm-vdec-test-inc += $(LOCAL_PATH)/inc +mm-vdec-test-inc += $(vdec-inc) + +LOCAL_MODULE := mm-vdec-omx-test +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := $(libOmxVdec-def) +LOCAL_C_INCLUDES := $(mm-vdec-test-inc) + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := libutils libOmxCore libOmxVdec libbinder libcutils + +LOCAL_SRC_FILES := src/queue.c +LOCAL_SRC_FILES += test/omx_vdec_test.cpp +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + +include $(BUILD_EXECUTABLE) + +# --------------------------------------------------------------------------------- +# Make the driver-test (mm-video-driver-test) +# --------------------------------------------------------------------------------- +include $(CLEAR_VARS) + +mm-vdec-drv-test-inc := hardware/qcom/media/mm-core/inc +mm-vdec-drv-test-inc += $(LOCAL_PATH)/inc +mm-vdec-drv-test-inc += $(vdec-inc) + +LOCAL_MODULE := mm-video-driver-test +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := $(libOmxVdec-def) +LOCAL_C_INCLUDES := $(mm-vdec-drv-test-inc) +LOCAL_PRELINK_MODULE := false + +LOCAL_SRC_FILES := src/message_queue.c +LOCAL_SRC_FILES += test/decoder_driver_test.c +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + +include $(BUILD_EXECUTABLE) + +endif #BUILD_TINY_ANDROID + +# --------------------------------------------------------------------------------- +# END +# --------------------------------------------------------------------------------- diff --git a/mm-video-v4l2/vidc/vdec/inc/Map.h b/mm-video-v4l2/vidc/vdec/inc/Map.h new file mode 100755 index 00000000..6d5873e0 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/Map.h @@ -0,0 +1,237 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef _MAP_H_ +#define _MAP_H_ + +#include +using namespace std; + +template +class Map +{ + struct node + { + T data; + T2 data2; + node* prev; + node* next; + node(T t, T2 t2,node* p, node* n) : + data(t), data2(t2), prev(p), next(n) {} + }; + node* head; + node* tail; + node* tmp; + unsigned size_of_list; + static Map *m_self; +public: + Map() : head( NULL ), tail ( NULL ),tmp(head),size_of_list(0) {} + bool empty() const { return ( !head || !tail ); } + operator bool() const { return !empty(); } + void insert(T,T2); + void show(); + int size(); + T2 find(T); // Return VALUE + T find_ele(T);// Check if the KEY is present or not + T2 begin(); //give the first ele + bool erase(T); + bool eraseall(); + bool isempty(); + ~Map() + { + while(head) + { + node* temp(head); + head=head->next; + size_of_list--; + delete temp; + } + } +}; + +template +T2 Map::find(T d1) +{ + tmp = head; + while(tmp) + { + if(tmp->data == d1) + { + return tmp->data2; + } + tmp = tmp->next; + } + return 0; +} + +template +T Map::find_ele(T d1) +{ + tmp = head; + while(tmp) + { + if(tmp->data == d1) + { + return tmp->data; + } + tmp = tmp->next; + } + return 0; +} + +template +T2 Map::begin() +{ + tmp = head; + if(tmp) + { + return (tmp->data2); + } + return 0; +} + +template +void Map::show() +{ + tmp = head; + while(tmp) + { + printf("%d-->%d\n",tmp->data,tmp->data2); + tmp = tmp->next; + } +} + +template +int Map::size() +{ + int count =0; + tmp = head; + while(tmp) + { + tmp = tmp->next; + count++; + } + return count; +} + +template +void Map::insert(T data, T2 data2) +{ + tail = new node(data, data2,tail, NULL); + if( tail->prev ) + tail->prev->next = tail; + + if( empty() ) + { + head = tail; + tmp=head; + } + tmp = head; + size_of_list++; +} + +template +bool Map::erase(T d) +{ + bool found = false; + tmp = head; + node* prevnode = tmp; + node *tempnode; + + while(tmp) + { + if((head == tail) && (head->data == d)) + { + found = true; + tempnode = head; + head = tail = NULL; + delete tempnode; + break; + } + if((tmp ==head) && (tmp->data ==d)) + { + found = true; + tempnode = tmp; + tmp = tmp->next; + tmp->prev = NULL; + head = tmp; + tempnode->next = NULL; + delete tempnode; + break; + } + if((tmp == tail) && (tmp->data ==d)) + { + found = true; + tempnode = tmp; + prevnode->next = NULL; + tmp->prev = NULL; + tail = prevnode; + delete tempnode; + break; + } + if(tmp->data == d) + { + found = true; + prevnode->next = tmp->next; + tmp->next->prev = prevnode->next; + tempnode = tmp; + //tmp = tmp->next; + delete tempnode; + break; + } + prevnode = tmp; + tmp = tmp->next; + } + if(found)size_of_list--; + return found; +} + +template +bool Map::eraseall() +{ + node *tempnode; + tmp = head; + while(head) + { + tempnode = head; + tempnode->next = NULL; + head = head->next; + delete tempnode; + } + tail = head = NULL; + return true; +} + + +template +bool Map::isempty() +{ + if(!size_of_list) return true; + else return false; +} + +#endif // _MAP_H_ diff --git a/mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h b/mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h new file mode 100755 index 00000000..b3afafeb --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h @@ -0,0 +1,70 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include +#include +#include "message_queue.h" +#include +#include +#include +#include +#include +#include +#include +#include + +struct video_decoder_context +{ + enum vdec_codec decoder_format; + enum vdec_output_fromat output_format; + struct vdec_picsize video_resoultion; + struct vdec_allocatorproperty input_buffer; + struct vdec_allocatorproperty output_buffer; + struct vdec_bufferpayload **ptr_inputbuffer; + struct vdec_bufferpayload **ptr_outputbuffer; + struct vdec_output_frameinfo **ptr_respbuffer; + struct video_queue_context queue_context; + int video_driver_fd; + + FILE * inputBufferFile; + FILE * outputBufferFile; + + pthread_t videothread_id; + pthread_t asyncthread_id; + sem_t sem_synchronize; +}; + +int init_decoder ( struct video_decoder_context *init_decode ); +int allocate_buffer ( enum vdec_buffer, + struct video_decoder_context *decode_context + ); +int free_buffer ( enum vdec_buffer, + struct video_decoder_context *decode_context + ); +int start_decoding (struct video_decoder_context *decode_context); +int stop_decoding (struct video_decoder_context *decode_context); +int deinit_decoder (struct video_decoder_context *init_decode); diff --git a/mm-video-v4l2/vidc/vdec/inc/frameparser.h b/mm-video-v4l2/vidc/vdec/inc/frameparser.h new file mode 100755 index 00000000..186c0397 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/frameparser.h @@ -0,0 +1,105 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef FRAMEPARSER_H +#define FRAMEPARSER_H + +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "h264_utils.h" +//#include + +enum codec_type +{ + CODEC_TYPE_MPEG4 = 0, + CODEC_TYPE_DIVX = 0, + CODEC_TYPE_H263 = 1, + CODEC_TYPE_H264 = 2, + CODEC_TYPE_VC1 = 3, + CODEC_TYPE_MPEG2 = 4, +#ifdef _MSM8974_ + CODEC_TYPE_VP8 = 5, + CODEC_TYPE_HEVC, +#endif + CODEC_TYPE_MAX +}; + +enum state_start_code_parse +{ + A0, + A1, + A2, + A3, + A4, + A5 +}; + +enum state_nal_parse +{ + NAL_LENGTH_ACC, + NAL_PARSING +}; + +class frame_parse +{ + +public: + H264_Utils *mutils; + int init_start_codes (codec_type codec_type_parse); + int parse_sc_frame (OMX_BUFFERHEADERTYPE *source, + OMX_BUFFERHEADERTYPE *dest , + OMX_U32 *partialframe); + int init_nal_length (unsigned int nal_length); + int parse_h264_nallength (OMX_BUFFERHEADERTYPE *source, + OMX_BUFFERHEADERTYPE *dest , + OMX_U32 *partialframe); + void flush (); + frame_parse (); + ~frame_parse (); + +private: + /*Variables for Start code based Parsing*/ + enum state_start_code_parse parse_state; + unsigned char *start_code; + unsigned char *mask_code; + unsigned char last_byte_h263; + unsigned char last_byte; + bool header_found; + bool skip_frame_boundary; + + /*Variables for NAL Length Parsing*/ + enum state_nal_parse state_nal; + unsigned int nal_length; + unsigned int accum_length; + unsigned int bytes_tobeparsed; + /*Functions to support additional start code parsing*/ + void parse_additional_start_code(OMX_U8 *psource, OMX_U32 *parsed_length); + void check_skip_frame_boundary(OMX_U32 *partial_frame); + void update_skip_frame(); +}; + +#endif /* FRAMEPARSER_H */ diff --git a/mm-video-v4l2/vidc/vdec/inc/h264_utils.h b/mm-video-v4l2/vidc/vdec/inc/h264_utils.h new file mode 100755 index 00000000..8006bb2a --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/h264_utils.h @@ -0,0 +1,479 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef H264_UTILS_H +#define H264_UTILS_H + +/*======================================================================== + + O p e n M M + U t i l i t i e s a n d H e l p e r R o u t i n e s + +*//** @file H264_Utils.h +This module contains H264 video decoder utilities and helper routines. + +*//*====================================================================== */ + +/* ======================================================================= + + INCLUDE FILES FOR MODULE + +========================================================================== */ +#include +#include "Map.h" +#include "qtypes.h" +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" + +#define STD_MIN(x,y) (((x) < (y)) ? (x) : (y)) + +#define OMX_CORE_720P_HEIGHT 720 +#define OMX_CORE_720P_WIDTH 1280 + +#define PANSCAN_HDLR + +/* ======================================================================= + + DATA DECLARATIONS + +========================================================================== */ + +/* ----------------------------------------------------------------------- +** Constant / Define Declarations +** ----------------------------------------------------------------------- */ +// Common format block header definitions +#define MT_VIDEO_META_STREAM_HEADER 0x00 +#define MT_VIDEO_MEDIA_STREAM_HEADER 0x01 +#define MT_VIDEO_META_MEDIA_STREAM_HEADER 0x02 + +// H.264 format block header definitions +#define MT_VIDEO_H264_ACCESS_UNIT_FORMAT 0x00 +#define MT_VIDEO_H264_NAL_FORMT 0x01 +#define MT_VIDEO_H264_BYTE_FORMAT 0x02 +#define MT_VIDEO_H264_BYTE_STREAM_FORMAT 0x00 +#define MT_VIDEO_H264_NAL_UNIT_STREAM_FORMAT 0x01 +#define MT_VIDEO_H264_FORMAT_BLOCK_HEADER_SIZE 18 + +// MPEG-4 format block header definitions +#define MT_VIDEO_MPEG4_VOP_FORMAT 0x00 +#define MT_VIDEO_MPEG4_SLICE_FORMAT 0x01 +#define MT_VIDEO_MPEG4_BYTE_FORMAT 0x02 +#define MT_VIDEO_MPEG4_FORMAT_BLOCK_HEADER_SIZE 15 + +// H.263 format block header definitions +#define MT_VIDEO_H263_PICTURE_FORMAT 0x00 +#define MT_VIDEO_H263_GOB_FORMAT 0x01 +#define MT_VIDEO_H263_SLICE_STRUCTURED_FORMAT 0x02 +#define MT_VIDEO_H263_BYTE_FORMAT 0x03 +#define MT_VIDEO_H263_FORMAT_BLOCK_HEADER_SIZE 16 + +/* ======================================================================= +** Function Declarations +** ======================================================================= */ + +/* ----------------------------------------------------------------------- +** Type Declarations +** ----------------------------------------------------------------------- */ + +// This type is used when parsing an H.264 bitstream to collect H.264 NAL +// units that need to go in the meta data. +struct H264ParamNalu { + uint32 picSetID; + uint32 seqSetID; + uint32 picOrderCntType; + bool frameMbsOnlyFlag; + bool picOrderPresentFlag; + uint32 picWidthInMbsMinus1; + uint32 picHeightInMapUnitsMinus1; + uint32 log2MaxFrameNumMinus4; + uint32 log2MaxPicOrderCntLsbMinus4; + bool deltaPicOrderAlwaysZeroFlag; + //std::vector nalu; + uint32 nalu; + uint32 crop_left; + uint32 crop_right; + uint32 crop_top; + uint32 crop_bot; +}; +//typedef map H264ParamNaluSet; +typedef Map H264ParamNaluSet; + +typedef enum { + NALU_TYPE_UNSPECIFIED = 0, + NALU_TYPE_NON_IDR, + NALU_TYPE_PARTITION_A, + NALU_TYPE_PARTITION_B, + NALU_TYPE_PARTITION_C, + NALU_TYPE_IDR, + NALU_TYPE_SEI, + NALU_TYPE_SPS, + NALU_TYPE_PPS, + NALU_TYPE_ACCESS_DELIM, + NALU_TYPE_EOSEQ, + NALU_TYPE_EOSTREAM, + NALU_TYPE_FILLER_DATA, + NALU_TYPE_RESERVED, +} NALU_TYPE; + +// NAL header information +typedef struct { + uint32 nal_ref_idc; + uint32 nalu_type; + uint32 forbidden_zero_bit; +} NALU; + +// This structure contains persistent information about an H.264 stream as it +// is parsed. +//struct H264StreamInfo { +// H264ParamNaluSet pic; +// H264ParamNaluSet seq; +//}; + +class extra_data_parser; + +class RbspParser +/****************************************************************************** + ** This class is used to convert an H.264 NALU (network abstraction layer + ** unit) into RBSP (raw byte sequence payload) and extract bits from it. + *****************************************************************************/ +{ +public: + RbspParser (const uint8 *begin, const uint8 *end); + + virtual ~RbspParser (); + + uint32 next (); + void advance (); + uint32 u (uint32 n); + uint32 ue (); + int32 se (); + +private: + const uint8 *begin, *end; + int32 pos; + uint32 bit; + uint32 cursor; + bool advanceNeeded; +}; + +class H264_Utils +{ +public: + H264_Utils(); + ~H264_Utils(); + void initialize_frame_checking_environment(); + void allocate_rbsp_buffer(uint32 inputBufferSize); + bool isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_BOOL &isNewFrame); + uint32 nalu_type; + +private: + boolean extract_rbsp(OMX_IN OMX_U8 *buffer, + OMX_IN OMX_U32 buffer_length, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_U8 *rbsp_bistream, + OMX_OUT OMX_U32 *rbsp_length, + OMX_OUT NALU *nal_unit); + + unsigned m_height; + unsigned m_width; + H264ParamNaluSet pic; + H264ParamNaluSet seq; + uint8 *m_rbspBytes; + NALU m_prv_nalu; + bool m_forceToStichNextNAL; + bool m_au_data; +}; + +class perf_metrics +{ + public: + perf_metrics() : + start_time(0), + proc_time(0), + active(false) + { + }; + ~perf_metrics() {}; + void start(); + void stop(); + void end(OMX_U32 units_cntr = 0); + void reset(); + OMX_U64 processing_time_us(); + private: + inline OMX_U64 get_act_time(); + OMX_U64 start_time; + OMX_U64 proc_time; + bool active; +}; + +#define EMULATION_PREVENTION_THREE_BYTE 0x03 +#define MAX_CPB_COUNT 32 +#define NO_PAN_SCAN_BIT 0x00000100 +#define MAX_PAN_SCAN_RECT 3 +#define VALID_TS(ts) ((ts < LLONG_MAX)? true : false) +#define NALU_TYPE_VUI (NALU_TYPE_RESERVED + 1) + +enum SEI_PAYLOAD_TYPE +{ + BUFFERING_PERIOD = 0, + PIC_TIMING, + PAN_SCAN_RECT, + FILLER_PAYLOAD, + USER_DATA_REGISTERED_ITU_T_T35, + USER_DATA_UNREGISTERED, + RECOVERY_POINT, + DEC_REF_PIC_MARKING_REPETITION, + SPARE_PIC, + SCENE_INFO, + SUB_SEQ_INFO, + SUB_SEQ_LAYER_CHARACTERISTICS, + SUB_SEQ_CHARACTERISTICS, + FULL_FRAME_FREEZE, + FULL_FRAME_FREEZE_RELEASE, + FULL_FRAME_SNAPSHOT, + PROGRESSIVE_REFINEMENT_SEGMENT_START, + PROGRESSIVE_REFINEMENT_SEGMENT_END, + SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT = 0x2D +}; + +typedef struct +{ + OMX_U32 cpb_cnt; + OMX_U8 bit_rate_scale; + OMX_U8 cpb_size_scale; + OMX_U32 bit_rate_value[MAX_CPB_COUNT]; + OMX_U32 cpb_size_value[MAX_CPB_COUNT]; + OMX_U8 cbr_flag[MAX_CPB_COUNT]; + OMX_U8 initial_cpb_removal_delay_length; + OMX_U8 cpb_removal_delay_length; + OMX_U8 dpb_output_delay_length; + OMX_U8 time_offset_length; +} h264_hrd_param; + +typedef struct +{ + OMX_U32 aspect_ratio_idc; + OMX_U32 aspect_ratio_x; + OMX_U32 aspect_ratio_y; +} h264_aspect_ratio_info; + +typedef struct +{ + OMX_U8 aspect_ratio_info_present_flag; + h264_aspect_ratio_info aspect_ratio_info; + OMX_U8 timing_info_present_flag; + OMX_U32 num_units_in_tick; + OMX_U32 time_scale; + OMX_U8 fixed_frame_rate_flag; + OMX_U8 nal_hrd_parameters_present_flag; + h264_hrd_param nal_hrd_parameters; + OMX_U8 vcl_hrd_parameters_present_flag; + h264_hrd_param vcl_hrd_parameters; + OMX_U8 low_delay_hrd_flag; + OMX_U8 pic_struct_present_flag; + OMX_S64 fixed_fps_prev_ts; +} h264_vui_param; + +typedef struct +{ + OMX_U32 cpb_removal_delay; + OMX_U32 dpb_output_delay; + OMX_U8 pic_struct; + OMX_U32 num_clock_ts; + bool clock_ts_flag; + OMX_U8 ct_type; + OMX_U32 nuit_field_based_flag; + OMX_U8 counting_type; + OMX_U8 full_timestamp_flag; + OMX_U8 discontinuity_flag; + OMX_U8 cnt_dropped_flag; + OMX_U32 n_frames; + OMX_U32 seconds_value; + OMX_U32 minutes_value; + OMX_U32 hours_value; + OMX_S32 time_offset; + bool is_valid; +} h264_sei_pic_timing; + +typedef struct +{ + OMX_U32 initial_cpb_removal_delay[MAX_CPB_COUNT]; + OMX_U32 initial_cpb_removal_delay_offset[MAX_CPB_COUNT]; + OMX_U32 au_cntr; + OMX_S64 reference_ts; + bool is_valid; +} h264_sei_buf_period; + +typedef struct +{ + OMX_U32 rect_id; + OMX_U8 rect_cancel_flag; + OMX_U32 cnt; + OMX_S32 rect_left_offset[MAX_PAN_SCAN_RECT]; + OMX_S32 rect_right_offset[MAX_PAN_SCAN_RECT]; + OMX_S32 rect_top_offset[MAX_PAN_SCAN_RECT]; + OMX_S32 rect_bottom_offset[MAX_PAN_SCAN_RECT]; + OMX_U32 rect_repetition_period; +} h264_pan_scan; + +#ifdef PANSCAN_HDLR +template +class omx_dl_list +{ +public: + omx_dl_list() { head = tail = NULL; } ; + ~omx_dl_list() {}; + void add_multiple(NODE_STRUCT *data_arr, int data_num); + NODE_STRUCT *remove_first(); + NODE_STRUCT *remove_last(); + void add_last(NODE_STRUCT *data_ptr); + NODE_STRUCT *watch_first(); + NODE_STRUCT *watch_last(); +private: + NODE_STRUCT *head, *tail; +}; + +class panscan_handler +{ +public: + panscan_handler(); + ~panscan_handler(); + bool initialize(int num_data); + h264_pan_scan *get_free(); + h264_pan_scan *get_populated(OMX_S64 frame_ts); + void update_last(OMX_S64 frame_ts); +private: + typedef struct PANSCAN_NODE + { + h264_pan_scan pan_scan_param; + OMX_S64 start_ts, end_ts; + bool active; + PANSCAN_NODE *next, *prev; + } PANSCAN_NODE; + omx_dl_list panscan_used; + omx_dl_list panscan_free; + PANSCAN_NODE *panscan_data; +}; + +#if 1 // Debug panscan data + +#define PRINT_PANSCAN_PARAM(H264_PARAM) +#define PRINT_PANSCAN_DATA(NODE) + +#else + +#define PRINT_PANSCAN_PARAM(H264_PARAM) \ +do {\ + ALOGE("%s(): left_off(%ld) right_off(%ld) top_off(%ld) bottom_off(%ld)",\ + __FUNCTION__,\ + (H264_PARAM).rect_left_offset[0],\ + (H264_PARAM).rect_right_offset[0],\ + (H264_PARAM).rect_top_offset[0],\ + (H264_PARAM).rect_bottom_offset[0]);\ +}while(0) + +#define PRINT_PANSCAN_DATA(NODE) \ +do {\ + if (NODE) {\ + ALOGE("%s(): PANSCAN DATA start_ts(%lld) end_ts(%lld)", __FUNCTION__,\ + (NODE)->start_ts, (NODE)->end_ts);\ + PRINT_PANSCAN_PARAM(NODE->pan_scan_param);\ + }\ +}while(0) + +#endif // End debug panscan data + +#endif + +class h264_stream_parser +{ + public: + h264_stream_parser(); + ~h264_stream_parser(); + void reset(); + void fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp); + void fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio); + void parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, + OMX_U32 nal_type = NALU_TYPE_UNSPECIFIED, + bool enable_emu_sc = true); + OMX_S64 process_ts_with_sei_vui(OMX_S64 timestamp); + void get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); + bool is_mbaff(); + void get_frame_rate(OMX_U32 *frame_rate); +#ifdef PANSCAN_HDLR + void update_panscan_data(OMX_S64 timestamp); +#endif + private: + void init_bitstream(OMX_U8* data, OMX_U32 size); + OMX_U32 extract_bits(OMX_U32 n); + inline bool more_bits(); + void read_word(); + OMX_U32 uev(); + OMX_S32 sev(); + OMX_S32 iv(OMX_U32 n_bits); + void parse_sps(); + void parse_vui(bool vui_in_extradata = true); + void aspect_ratio_info(); + void hrd_parameters(h264_hrd_param *hrd_param); + void parse_sei(); + void sei_buffering_period(); + void sei_picture_timing(); + void sei_pan_scan(); + void scaling_list(OMX_U32 size_of_scaling_list); + + void print_pan_data(h264_pan_scan *pan_scan_param); + void print_frame_pack(); + + OMX_U32 get_nal_unit_type(OMX_U32 *nal_unit_type); + OMX_S64 calculate_buf_period_ts(OMX_S64 timestamp); + OMX_S64 calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor); + void parse_frame_pack(); + + OMX_U32 curr_32_bit; + OMX_U32 bits_read; + OMX_U32 zero_cntr; + OMX_U32 emulation_code_skip_cntr; + OMX_U8* bitstream; + OMX_U32 bitstream_bytes; + OMX_U32 frame_rate; + bool emulation_sc_enabled; + + h264_vui_param vui_param; + h264_sei_buf_period sei_buf_period; + h264_sei_pic_timing sei_pic_timing; +#ifdef PANSCAN_HDLR + panscan_handler *panscan_hdl; +#else + h264_pan_scan panscan_param; +#endif + OMX_QCOM_FRAME_PACK_ARRANGEMENT frame_packing_arrangement; + bool mbaff_flag; +}; + +#endif /* H264_UTILS_H */ diff --git a/mm-video-v4l2/vidc/vdec/inc/hevc_utils.h b/mm-video-v4l2/vidc/vdec/inc/hevc_utils.h new file mode 100644 index 00000000..6482ee47 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/hevc_utils.h @@ -0,0 +1,146 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + + +#ifndef HEVC_UTILS_H +#define HEVC_UTILS_H + +/*======================================================================== + + O p e n M M + U t i l i t i e s a n d H e l p e r R o u t i n e s + +*//** @file HEVC_Utils.h +This module contains H264 video decoder utilities and helper routines. + +*//*====================================================================== */ + +/* ======================================================================= + + INCLUDE FILES FOR MODULE + +========================================================================== */ +#include +#include +#include "Map.h" +#include "qtypes.h" +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" + + +class HEVC_Utils +{ +public: + HEVC_Utils(); + ~HEVC_Utils(); + + enum { + NAL_UNIT_CODED_SLICE_TRAIL_N, // 0 + NAL_UNIT_CODED_SLICE_TRAIL_R, // 1 + NAL_UNIT_CODED_SLICE_TSA_N, // 2 + NAL_UNIT_CODED_SLICE_TLA, // 3 + NAL_UNIT_CODED_SLICE_STSA_N, // 4 + NAL_UNIT_CODED_SLICE_STSA_R, // 5 + NAL_UNIT_CODED_SLICE_RADL_N, // 6 + NAL_UNIT_CODED_SLICE_DLP, // 7 + NAL_UNIT_CODED_SLICE_RASL_N, // 8 + NAL_UNIT_CODED_SLICE_TFD, // 9 + NAL_UNIT_RESERVED_10, + NAL_UNIT_RESERVED_11, + NAL_UNIT_RESERVED_12, + NAL_UNIT_RESERVED_13, + NAL_UNIT_RESERVED_14, + NAL_UNIT_RESERVED_15, + NAL_UNIT_CODED_SLICE_BLA, // 16 + NAL_UNIT_CODED_SLICE_BLANT, // 17 + NAL_UNIT_CODED_SLICE_BLA_N_LP, // 18 + NAL_UNIT_CODED_SLICE_IDR, // 19 + NAL_UNIT_CODED_SLICE_IDR_N_LP, // 20 + NAL_UNIT_CODED_SLICE_CRA, // 21 + NAL_UNIT_RESERVED_22, + NAL_UNIT_RESERVED_23, + NAL_UNIT_RESERVED_24, + NAL_UNIT_RESERVED_25, + NAL_UNIT_RESERVED_26, + NAL_UNIT_RESERVED_27, + + NAL_UNIT_RESERVED_28, + NAL_UNIT_RESERVED_29, + NAL_UNIT_RESERVED_30, + NAL_UNIT_RESERVED_31, + + NAL_UNIT_VPS, // 32 + NAL_UNIT_SPS, // 33 + NAL_UNIT_PPS, // 34 + NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35 + NAL_UNIT_EOS, // 36 + NAL_UNIT_EOB, // 37 + NAL_UNIT_FILLER_DATA, // 38 + NAL_UNIT_SEI, // 39 Prefix SEI + NAL_UNIT_SEI_SUFFIX, // 40 Suffix SEI + + NAL_UNIT_RESERVED_41, + NAL_UNIT_RESERVED_42, + NAL_UNIT_RESERVED_43, + NAL_UNIT_RESERVED_44, + NAL_UNIT_RESERVED_45, + NAL_UNIT_RESERVED_46, + NAL_UNIT_RESERVED_47, + NAL_UNIT_UNSPECIFIED_48, + NAL_UNIT_UNSPECIFIED_49, + NAL_UNIT_UNSPECIFIED_50, + NAL_UNIT_UNSPECIFIED_51, + NAL_UNIT_UNSPECIFIED_52, + NAL_UNIT_UNSPECIFIED_53, + NAL_UNIT_UNSPECIFIED_54, + NAL_UNIT_UNSPECIFIED_55, + NAL_UNIT_UNSPECIFIED_56, + NAL_UNIT_UNSPECIFIED_57, + NAL_UNIT_UNSPECIFIED_58, + NAL_UNIT_UNSPECIFIED_59, + NAL_UNIT_UNSPECIFIED_60, + NAL_UNIT_UNSPECIFIED_61, + NAL_UNIT_UNSPECIFIED_62, + NAL_UNIT_UNSPECIFIED_63, + NAL_UNIT_INVALID, + }; + + + void initialize_frame_checking_environment(); + bool isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_BOOL &isNewFrame); + +private: + + bool m_forceToStichNextNAL; + bool m_au_data; + uint32 nalu_type; +}; + +#endif /* HEVC_UTILS_H */ diff --git a/mm-video-v4l2/vidc/vdec/inc/message_queue.h b/mm-video-v4l2/vidc/vdec/inc/message_queue.h new file mode 100755 index 00000000..d5924e6a --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/message_queue.h @@ -0,0 +1,78 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef QUEUE_H +#define QUEUE_H + +#include +#include +#include +#include + +/* Message Queue structure */ +struct video_msgq +{ + /* Command to be executed */ + unsigned int cmd; + + unsigned int status; + + /* Client-specific data */ + void *clientdata; +}; + + +/* Thread & Message Queue information */ +struct video_queue_context +{ + /* Message Queue related members */ + pthread_mutex_t mutex; + sem_t sem_message; + int commandq_size; + int dataq_size; + struct video_msgq *ptr_dataq; + struct video_msgq *ptr_cmdq; + int write_dataq ; + int read_dataq; + int write_comq ; + int read_comq ; + +}; + +int check_if_queue_empty ( unsigned int queuetocheck,void* queuecontext ); + +struct video_msgq * queue_get_cmd ( void* queuecontext ); + +int queue_post_cmdq ( void *queuecontext, + struct video_msgq *post_msg + ); + +int queue_post_dataq ( void *queuecontext, + struct video_msgq *post_msg + ); + +#endif /* QUEUE_H */ diff --git a/mm-video-v4l2/vidc/vdec/inc/mp4_utils.h b/mm-video-v4l2/vidc/vdec/inc/mp4_utils.h new file mode 100644 index 00000000..9a435bf7 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/mp4_utils.h @@ -0,0 +1,170 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef MP4_UTILS_H +#define MP4_UTILS_H +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +typedef signed long long int64; +typedef unsigned int uint32; /* Unsigned 32 bit value */ +typedef unsigned short uint16; /* Unsigned 16 bit value */ +typedef unsigned char uint8; /* Unsigned 8 bit value */ + +typedef int int32; /* Signed 32 bit value */ +typedef signed short int16; /* Signed 16 bit value */ +typedef signed char int8; /* Signed 8 bit value */ + +typedef unsigned char byte; /* Unsigned 8 bit value type. */ +#define SIMPLE_PROFILE_LEVEL0 0x08 +#define SIMPLE_PROFILE_LEVEL1 0x01 +#define SIMPLE_PROFILE_LEVEL2 0x02 +#define SIMPLE_PROFILE_LEVEL3 0x03 +#define SIMPLE_PROFILE_LEVEL4A 0x04 +#define SIMPLE_PROFILE_LEVEL5 0x05 +#define SIMPLE_PROFILE_LEVEL6 0x06 +#define SIMPLE_PROFILE_LEVEL0B 0x09 + +#define SIMPLE_SCALABLE_PROFILE_LEVEL0 0x10 +#define SIMPLE_SCALABLE_PROFILE_LEVEL1 0x11 +#define SIMPLE_SCALABLE_PROFILE_LEVEL2 0x12 + +#define SIMPLE_SCALABLE_PROFILE_LEVEL0 0x10 +#define SIMPLE_SCALABLE_PROFILE_LEVEL1 0x11 +#define SIMPLE_SCALABLE_PROFILE_LEVEL2 0x12 +#define ADVANCED_SIMPLE_PROFILE_LEVEL0 0xF0 +#define ADVANCED_SIMPLE_PROFILE_LEVEL1 0xF1 +#define ADVANCED_SIMPLE_PROFILE_LEVEL2 0xF2 +#define ADVANCED_SIMPLE_PROFILE_LEVEL3 0xF3 +#define ADVANCED_SIMPLE_PROFILE_LEVEL4 0xF4 +#define ADVANCED_SIMPLE_PROFILE_LEVEL5 0xF5 + +#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x000001B0 +#define MP4ERROR_SUCCESS 0 + +#define VIDEO_OBJECT_LAYER_START_CODE_MASK 0xFFFFFFF0 +#define VIDEO_OBJECT_LAYER_START_CODE 0x00000120 +#define VOP_START_CODE_MASK 0xFFFFFFFF +#define VOP_START_CODE 0x000001B6 +#define GOV_START_CODE 0x000001B3 +#define SHORT_HEADER_MASK 0xFFFFFC00 +#define SHORT_HEADER_START_MARKER 0x00008000 +#define SHORT_HEADER_START_CODE 0x00008000 +#define SPARK1_START_CODE 0x00008400 +#define MPEG4_SHAPE_RECTANGULAR 0x00 +#define EXTENDED_PAR 0xF +#define SHORT_VIDEO_START_MARKER 0x20 +#define MP4_INVALID_VOL_PARAM (0x0001) // unsupported VOL parameter +#define MP4ERROR_UNSUPPORTED_UFEP -1068 +#define MP4ERROR_UNSUPPORTED_SOURCE_FORMAT -1069 +#define MASK(x) (0xFFFFFFFF >> (32 - (x))) +#define VISUAL_OBJECT_TYPE_VIDEO_ID 0x1 +#define VISUAL_OBJECT_START_CODE 0x000001B5 +#define VIDEO_OBJECT_START_CODE_MASK 0xFFFFFFE0 +#define VIDEO_OBJECT_START_CODE 0x00000100 + +#define RESERVED_OBJECT_TYPE 0x0 +#define SIMPLE_OBJECT_TYPE 0x1 +#define SIMPLE_SCALABLE_OBJECT_TYPE 0x2 +#define CORE_OBJECT_TYPE 0x3 +#define MAIN_OBJECT_TYPE 0x4 +#define N_BIT_OBJECT_TYPE 0x5 +#define BASIC_ANIMATED_2D_TEXTURE 0x6 +#define ANIMATED_2D_MESH 0x7 +#define ADVANCED_SIMPLE 0x11 + + +#define SIMPLE_L1_MAX_VBVBUFFERSIZE 10 /* VBV Max Buffer size=10 (p. 498) */ +#define SIMPLE_L1_MAX_BITRATE 160 /* is is 64kpbs or 160 400bits/sec units */ +#define SIMPLE_L2_MAX_VBVBUFFERSIZE 40 /* VBV Max Buffer size = 40 */ +#define SIMPLE_L2_MAX_BITRATE 320 /* 320 400bps units = 128kpbs */ +#define SIMPLE_L3_MAX_VBVBUFFERSIZE 40 /* VBV Max Buffer size = 40 */ +#define SIMPLE_L3_MAX_BITRATE 960 /* 960 400bps units = 384kpbs */ + +/* The MP4 decoder currently supports Simple Profile@L3 */ +#define MAX_VBVBUFFERSIZE (SIMPLE_L3_MAX_VBVBUFFERSIZE) +#define MAX_BITRATE (SIMPLE_L3_MAX_BITRATE) + +#define MAX_QUANTPRECISION 9 +#define MIN_QUANTPRECISION 3 + +#define MP4_VGA_WIDTH 640 +#define MP4_VGA_HEIGHT 480 +#define MP4_WVGA_WIDTH 800 +#define MP4_WVGA_HEIGHT 480 +#define MP4_720P_WIDTH 1280 +#define MP4_720P_HEIGHT 720 + +#define MP4_MAX_DECODE_WIDTH MP4_720P_WIDTH +#define MP4_MAX_DECODE_HEIGHT MP4_720P_HEIGHT + +typedef struct { + unsigned char *data; + unsigned long int numBytes; +} mp4StreamType; + +#define MAX_FRAMES_IN_CHUNK 10 +#define VOP_START_CODE 0x000001B6 +#define VOL_START_CODE 0x000001B0 + +typedef enum VOPTYPE +{ + NO_VOP = -1, // bitstream contains no VOP. + MPEG4_I_VOP = 0, // bitstream contains an MPEG4 I-VOP + MPEG4_P_VOP = 1, // bitstream contains an MPEG4 P-VOP + MPEG4_B_VOP = 2, // bitstream contains an MPEG4 B-VOP + MPEG4_S_VOP = 3, // bitstream contains an MPEG4 S-VOP +} VOP_TYPE; + +typedef struct +{ + uint32 timestamp_increment; + uint32 offset; + uint32 size; + VOP_TYPE vopType; +} mp4_frame_info_type; + +class MP4_Utils { +private: + struct posInfoType { + uint8 *bytePtr; + uint8 bitPos; + }; + + posInfoType m_posInfo; + byte *m_dataBeginPtr; + unsigned int vop_time_resolution; + bool vop_time_found; + uint16 m_SrcWidth, m_SrcHeight; // Dimensions of the source clip +public: + MP4_Utils(); + ~MP4_Utils(); + int16 populateHeightNWidthFromShortHeader(mp4StreamType * psBits); + bool parseHeader(mp4StreamType * psBits); + static uint32 read_bit_field(posInfoType * posPtr, uint32 size); + bool is_notcodec_vop(unsigned char *pbuffer, unsigned int len); +}; +#endif diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h new file mode 100644 index 00000000..c7877549 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h @@ -0,0 +1,989 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef __OMX_VDEC_H__ +#define __OMX_VDEC_H__ +/*============================================================================ + O p e n M A X Component + Video Decoder + +*//** @file comx_vdec.h + This module contains the class definition for openMAX decoder component. + +*//*========================================================================*/ + +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +static ptrdiff_t x; + +#ifdef _ANDROID_ +#ifdef MAX_RES_720P +#define LOG_TAG "OMX-VDEC-720P" +#elif MAX_RES_1080P +#define LOG_TAG "OMX-VDEC-1080P" +#else +#define LOG_TAG "OMX-VDEC" +#endif + +#ifdef USE_ION +#include +//#include +//#else +#endif +#include +#include +extern "C"{ +#include +} +#include +#include +#define TIMEOUT 5000 + +#else //_ANDROID_ +#define DEBUG_PRINT_LOW printf +#define DEBUG_PRINT_HIGH printf +#define DEBUG_PRINT_ERROR printf +#endif // _ANDROID_ + +#ifdef _MSM8974_ +#define DEBUG_PRINT_LOW +#define DEBUG_PRINT_HIGH printf +#define DEBUG_PRINT_ERROR printf +#endif + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +#include +#endif + +#include + +#if defined (_ANDROID_ICS_) +#include +#endif + +#include +#ifndef PC_DEBUG +#include +#endif +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "qc_omx_component.h" +#include +#include +#include "frameparser.h" +#ifdef MAX_RES_1080P +#include "mp4_utils.h" +#endif +#include +#include "extra_data_handler.h" +#include "ts_parser.h" +#include "vidc_color_converter.h" +extern "C" { + OMX_API void * get_omx_component_factory_fn(void); +} + +#ifdef _ANDROID_ + using namespace android; +#ifdef USE_ION + class VideoHeap : public MemoryHeapBase + { + public: + VideoHeap(int devicefd, size_t size, void* base,struct ion_handle *handle,int mapfd); + virtual ~VideoHeap() {} + private: + int m_ion_device_fd; + struct ion_handle *m_ion_handle; + }; +#else + // local pmem heap object + class VideoHeap : public MemoryHeapBase + { + public: + VideoHeap(int fd, size_t size, void* base); + virtual ~VideoHeap() {} + }; +#endif +#endif // _ANDROID_ +////////////////////////////////////////////////////////////////////////////// +// Module specific globals +////////////////////////////////////////////////////////////////////////////// +#define OMX_SPEC_VERSION 0x00000101 + + +////////////////////////////////////////////////////////////////////////////// +// Macros +////////////////////////////////////////////////////////////////////////////// +#define PrintFrameHdr(bufHdr) DEBUG_PRINT("bufHdr %x buf %x size %d TS %d\n",\ + (unsigned) bufHdr,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp) + +// BitMask Management logic +#define BITS_PER_BYTE 32 +#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE) +#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE) +#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE)) +#define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ + &= ~(BITMASK_FLAG(mIndex)) +#define BITMASK_SET(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ + |= BITMASK_FLAG(mIndex) +#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) +#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) == 0x0) +#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) +#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) == 0x0) + +#define OMX_CORE_CONTROL_CMDQ_SIZE 100 +#define OMX_CORE_QCIF_HEIGHT 144 +#define OMX_CORE_QCIF_WIDTH 176 +#define OMX_CORE_VGA_HEIGHT 480 +#define OMX_CORE_VGA_WIDTH 640 +#define OMX_CORE_WVGA_HEIGHT 480 +#define OMX_CORE_WVGA_WIDTH 800 + +#define DESC_BUFFER_SIZE (8192 * 16) + +#ifdef _ANDROID_ +#define MAX_NUM_INPUT_OUTPUT_BUFFERS 32 +#endif + +#define OMX_FRAMEINFO_EXTRADATA 0x00010000 +#define OMX_INTERLACE_EXTRADATA 0x00020000 +#define OMX_TIMEINFO_EXTRADATA 0x00040000 +#define OMX_PORTDEF_EXTRADATA 0x00080000 +#define OMX_EXTNUSER_EXTRADATA 0x00100000 +#define DRIVER_EXTRADATA_MASK 0x0000FFFF + +#define OMX_INTERLACE_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ + sizeof(OMX_STREAMINTERLACEFORMAT) + 3)&(~3)) +#define OMX_FRAMEINFO_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ + sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO) + 3)&(~3)) +#define OMX_PORTDEF_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ + sizeof(OMX_PARAM_PORTDEFINITIONTYPE) + 3)&(~3)) + +// Define next macro with required values to enable default extradata, +// VDEC_EXTRADATA_MB_ERROR_MAP +// OMX_INTERLACE_EXTRADATA +// OMX_FRAMEINFO_EXTRADATA +// OMX_TIMEINFO_EXTRADATA + +//#define DEFAULT_EXTRADATA (OMX_FRAMEINFO_EXTRADATA|OMX_INTERLACE_EXTRADATA) + +enum port_indexes +{ + OMX_CORE_INPUT_PORT_INDEX =0, + OMX_CORE_OUTPUT_PORT_INDEX =1 +}; +#ifdef USE_ION +struct vdec_ion +{ + int ion_device_fd; + struct ion_fd_data fd_ion_data; + struct ion_allocation_data ion_alloc_data; +}; +#endif + +#ifdef _MSM8974_ +struct extradata_buffer_info { + int buffer_size; + char* uaddr; + int count; + int size; +#ifdef USE_ION + struct vdec_ion ion; +#endif +}; +#endif + +struct video_driver_context +{ + int video_driver_fd; + enum vdec_codec decoder_format; + enum vdec_output_fromat output_format; + enum vdec_interlaced_format interlace; + enum vdec_output_order picture_order; + struct vdec_picsize video_resolution; + struct vdec_allocatorproperty ip_buf; + struct vdec_allocatorproperty op_buf; + struct vdec_bufferpayload *ptr_inputbuffer; + struct vdec_bufferpayload *ptr_outputbuffer; + struct vdec_output_frameinfo *ptr_respbuffer; +#ifdef USE_ION + struct vdec_ion *ip_buf_ion_info; + struct vdec_ion *op_buf_ion_info; + struct vdec_ion h264_mv; + struct vdec_ion meta_buffer; + struct vdec_ion meta_buffer_iommu; +#endif + struct vdec_framerate frame_rate; + unsigned extradata; + bool timestamp_adjust; + char kind[128]; + bool idr_only_decoding; + unsigned disable_dmx; +#ifdef _MSM8974_ + struct extradata_buffer_info extradata_info; + int num_planes; +#endif +}; + +#ifdef _ANDROID_ +class DivXDrmDecrypt; +#endif //_ANDROID_ + +struct video_decoder_capability { + unsigned int min_width; + unsigned int max_width; + unsigned int min_height; + unsigned int max_height; +}; +// OMX video decoder class +class omx_vdec: public qc_omx_component +{ + +public: + omx_vdec(); // constructor + virtual ~omx_vdec(); // destructor + + static int async_message_process (void *context, void* message); + static void process_event_cb(void *ctxt,unsigned char id); + + OMX_ERRORTYPE allocate_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes + ); + + + OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp); + + OMX_ERRORTYPE component_init(OMX_STRING role); + + OMX_ERRORTYPE component_role_enum( + OMX_HANDLETYPE hComp, + OMX_U8 *role, + OMX_U32 index + ); + + OMX_ERRORTYPE component_tunnel_request( + OMX_HANDLETYPE hComp, + OMX_U32 port, + OMX_HANDLETYPE peerComponent, + OMX_U32 peerPort, + OMX_TUNNELSETUPTYPE *tunnelSetup + ); + + OMX_ERRORTYPE empty_this_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + + + OMX_ERRORTYPE fill_this_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + + OMX_ERRORTYPE free_buffer( + OMX_HANDLETYPE hComp, + OMX_U32 port, + OMX_BUFFERHEADERTYPE *buffer + ); + + OMX_ERRORTYPE get_component_version( + OMX_HANDLETYPE hComp, + OMX_STRING componentName, + OMX_VERSIONTYPE *componentVersion, + OMX_VERSIONTYPE *specVersion, + OMX_UUIDTYPE *componentUUID + ); + + OMX_ERRORTYPE get_config( + OMX_HANDLETYPE hComp, + OMX_INDEXTYPE configIndex, + OMX_PTR configData + ); + + OMX_ERRORTYPE get_extension_index( + OMX_HANDLETYPE hComp, + OMX_STRING paramName, + OMX_INDEXTYPE *indexType + ); + + OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE paramIndex, + OMX_PTR paramData); + + OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp, + OMX_STATETYPE *state); + + + + OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp, + OMX_COMMANDTYPE cmd, + OMX_U32 param1, + OMX_PTR cmdData); + + + OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp, + OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData); + + OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE configIndex, + OMX_PTR configData); + + OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE paramIndex, + OMX_PTR paramData); + + OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8 *buffer); + + OMX_ERRORTYPE use_input_heap_buffers( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8* buffer); + + OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + void * eglImage); + void complete_pending_buffer_done_cbs(); + struct video_driver_context drv_ctx; +#ifdef _MSM8974_ + OMX_ERRORTYPE allocate_extradata(); + void free_extradata(); + int update_resolution(int width, int height, int stride, int scan_lines); + OMX_ERRORTYPE is_video_session_supported(); +#endif + int m_pipe_in; + int m_pipe_out; + pthread_t msg_thread_id; + pthread_t async_thread_id; + bool is_component_secure(); + +private: + // Bit Positions + enum flags_bit_positions + { + // Defer transition to IDLE + OMX_COMPONENT_IDLE_PENDING =0x1, + // Defer transition to LOADING + OMX_COMPONENT_LOADING_PENDING =0x2, + // First Buffer Pending + OMX_COMPONENT_FIRST_BUFFER_PENDING =0x3, + // Second Buffer Pending + OMX_COMPONENT_SECOND_BUFFER_PENDING =0x4, + // Defer transition to Enable + OMX_COMPONENT_INPUT_ENABLE_PENDING =0x5, + // Defer transition to Enable + OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x6, + // Defer transition to Disable + OMX_COMPONENT_INPUT_DISABLE_PENDING =0x7, + // Defer transition to Disable + OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x8, + //defer flush notification + OMX_COMPONENT_OUTPUT_FLUSH_PENDING =0x9, + OMX_COMPONENT_INPUT_FLUSH_PENDING =0xA, + OMX_COMPONENT_PAUSE_PENDING =0xB, + OMX_COMPONENT_EXECUTE_PENDING =0xC, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING =0xD, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE + }; + + // Deferred callback identifiers + enum + { + //Event Callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_EVENT = 0x1, + //Buffer Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2, + //Frame Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3, + //Buffer Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_FTB = 0x4, + //Frame Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_ETB = 0x5, + //Command + OMX_COMPONENT_GENERATE_COMMAND = 0x6, + //Push-Pending Buffers + OMX_COMPONENT_PUSH_PENDING_BUFS = 0x7, + // Empty Buffer Done callbacks + OMX_COMPONENT_GENERATE_EBD = 0x8, + //Flush Event Callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_EVENT_FLUSH = 0x9, + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH = 0x0A, + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH = 0x0B, + OMX_COMPONENT_GENERATE_FBD = 0xc, + OMX_COMPONENT_GENERATE_START_DONE = 0xD, + OMX_COMPONENT_GENERATE_PAUSE_DONE = 0xE, + OMX_COMPONENT_GENERATE_RESUME_DONE = 0xF, + OMX_COMPONENT_GENERATE_STOP_DONE = 0x10, + OMX_COMPONENT_GENERATE_HARDWARE_ERROR = 0x11, + OMX_COMPONENT_GENERATE_ETB_ARBITRARY = 0x12, + OMX_COMPONENT_GENERATE_PORT_RECONFIG = 0x13, + OMX_COMPONENT_GENERATE_EOS_DONE = 0x14, + OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG = 0x15, + OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED = 0x16, + OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING = 0x17, + }; + + enum vc1_profile_type + { + VC1_SP_MP_RCV = 1, + VC1_AP = 2 + }; + +#ifdef _MSM8974_ + enum v4l2_ports + { + CAPTURE_PORT, + OUTPUT_PORT, + MAX_PORT + }; +#endif + + struct omx_event + { + unsigned param1; + unsigned param2; + unsigned id; + }; + + struct omx_cmd_queue + { + omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE]; + unsigned m_read; + unsigned m_write; + unsigned m_size; + + omx_cmd_queue(); + ~omx_cmd_queue(); + bool insert_entry(unsigned p1, unsigned p2, unsigned id); + bool pop_entry(unsigned *p1,unsigned *p2, unsigned *id); + // get msgtype of the first ele from the queue + unsigned get_q_msg_type(); + + }; + +#ifdef _ANDROID_ + struct ts_entry + { + OMX_TICKS timestamp; + bool valid; + }; + + struct ts_arr_list + { + ts_entry m_ts_arr_list[MAX_NUM_INPUT_OUTPUT_BUFFERS]; + + ts_arr_list(); + ~ts_arr_list(); + + bool insert_ts(OMX_TICKS ts); + bool pop_min_ts(OMX_TICKS &ts); + bool reset_ts_list(); + }; +#endif + + struct desc_buffer_hdr + { + OMX_U8 *buf_addr; + OMX_U32 desc_data_size; + }; + bool allocate_done(void); + bool allocate_input_done(void); + bool allocate_output_done(void); + + OMX_ERRORTYPE free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + OMX_ERRORTYPE free_input_buffer(unsigned int bufferindex, + OMX_BUFFERHEADERTYPE *pmem_bufferHdr); + OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + void free_output_buffer_header(); + void free_input_buffer_header(); + + OMX_ERRORTYPE allocate_input_heap_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes); + + + OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes); + + OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port,OMX_PTR appData, + OMX_U32 bytes); + OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8 *buffer); +#ifdef MAX_RES_720P + OMX_ERRORTYPE get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); +#endif +#ifdef MAX_RES_1080P + OMX_ERRORTYPE get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); +#endif + + OMX_ERRORTYPE allocate_desc_buffer(OMX_U32 index); + OMX_ERRORTYPE allocate_output_headers(); + bool execute_omx_flush(OMX_U32); + bool execute_output_flush(); + bool execute_input_flush(); + OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE * buffer); + + OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE * buffer); + OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer); + + OMX_ERRORTYPE empty_this_buffer_proxy_arbitrary(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + OMX_ERRORTYPE push_input_buffer (OMX_HANDLETYPE hComp); + OMX_ERRORTYPE push_input_sc_codec (OMX_HANDLETYPE hComp); + OMX_ERRORTYPE push_input_h264 (OMX_HANDLETYPE hComp); + OMX_ERRORTYPE push_input_vc1 (OMX_HANDLETYPE hComp); + + OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer); + bool release_done(); + + bool release_output_done(); + bool release_input_done(); + OMX_ERRORTYPE get_buffer_req(vdec_allocatorproperty *buffer_prop); + OMX_ERRORTYPE set_buffer_req(vdec_allocatorproperty *buffer_prop); + OMX_ERRORTYPE start_port_reconfig(); + OMX_ERRORTYPE update_picture_resolution(); + int stream_off(OMX_U32 port); + void adjust_timestamp(OMX_S64 &act_timestamp); + void set_frame_rate(OMX_S64 act_timestamp); + void handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr); + void handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr); + void print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra); +#ifdef _MSM8974_ + void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 interlaced_format_type); + OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool is_internal, + bool enable = true); + void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 num_conceal_mb, + OMX_U32 picture_type, + OMX_U32 frame_rate, + struct msm_vidc_panscan_window_payload *panscan_payload, + struct vdec_aspectratioinfo *aspect_ratio_info); +#else + void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 interlaced_format_type, OMX_U32 buf_index); + OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool enable = true); +#endif + void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 num_conceal_mb, + OMX_U32 picture_type, + OMX_S64 timestamp, + OMX_U32 frame_rate, + struct vdec_aspectratioinfo *aspect_ratio_info); + void fill_aspect_ratio_info(struct vdec_aspectratioinfo *aspect_ratio_info, + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info); + void append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra); + OMX_ERRORTYPE update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn); + void append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra); + void append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_extn); + void append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_user); + void insert_demux_addr_offset(OMX_U32 address_offset); + void extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr); + OMX_ERRORTYPE handle_demux_data(OMX_BUFFERHEADERTYPE *buf_hdr); + OMX_U32 count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra); + + bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, + OMX_U32 alignment); +#ifdef USE_ION + int alloc_map_ion_memory(OMX_U32 buffer_size, + OMX_U32 alignment, struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data,int flag); + void free_ion_memory(struct vdec_ion *buf_ion_info); +#endif + + + OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp, + OMX_COMMANDTYPE cmd, + OMX_U32 param1, + OMX_PTR cmdData); + bool post_event( unsigned int p1, + unsigned int p2, + unsigned int id + ); + inline int clip2(int x) + { + x = x -1; + x = x | x >> 1; + x = x | x >> 2; + x = x | x >> 4; + x = x | x >> 16; + x = x + 1; + return x; + } + +#ifdef MAX_RES_1080P + OMX_ERRORTYPE vdec_alloc_h264_mv(); + void vdec_dealloc_h264_mv(); + OMX_ERRORTYPE vdec_alloc_meta_buffers(); + void vdec_dealloc_meta_buffers(); +#endif + + inline void omx_report_error () + { + if (m_cb.EventHandler && !m_error_propogated) + { + ALOGE("\nERROR: Sending OMX_EventError to Client"); + m_error_propogated = true; + m_cb.EventHandler(&m_cmp,m_app_data, + OMX_EventError,OMX_ErrorHardware,0,NULL); + } + } + + inline void omx_report_unsupported_setting () + { + if (m_cb.EventHandler && !m_error_propogated) + { + DEBUG_PRINT_ERROR( + "\nERROR: Sending OMX_ErrorUnsupportedSetting to Client"); + m_error_propogated = true; + m_cb.EventHandler(&m_cmp,m_app_data, + OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL); + } + } +#ifdef _ANDROID_ + OMX_ERRORTYPE createDivxDrmContext(); +#endif //_ANDROID_ +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + OMX_ERRORTYPE use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data); +#endif +#if defined (_ANDROID_ICS_) + struct nativebuffer{ + native_handle_t *nativehandle; + private_handle_t *privatehandle; + int inuse; + }; + nativebuffer native_buffer[MAX_NUM_INPUT_OUTPUT_BUFFERS]; +#endif + + + //************************************************************* + //*******************MEMBER VARIABLES ************************* + //************************************************************* + pthread_mutex_t m_lock; + pthread_mutex_t c_lock; + //sem to handle the minimum procesing of commands + sem_t m_cmd_lock; + bool m_error_propogated; + // compression format + OMX_VIDEO_CODINGTYPE eCompressionFormat; + // OMX State + OMX_STATETYPE m_state; + // Application data + OMX_PTR m_app_data; + // Application callbacks + OMX_CALLBACKTYPE m_cb; + OMX_PRIORITYMGMTTYPE m_priority_mgm ; + OMX_PARAM_BUFFERSUPPLIERTYPE m_buffer_supplier; + // fill this buffer queue + omx_cmd_queue m_ftb_q; + // Command Q for rest of the events + omx_cmd_queue m_cmd_q; + omx_cmd_queue m_etb_q; + // Input memory pointer + OMX_BUFFERHEADERTYPE *m_inp_mem_ptr; + // Output memory pointer + OMX_BUFFERHEADERTYPE *m_out_mem_ptr; + // number of input bitstream error frame count + unsigned int m_inp_err_count; +#ifdef _ANDROID_ + // Timestamp list + ts_arr_list m_timestamp_list; +#endif + + bool input_flush_progress; + bool output_flush_progress; + bool input_use_buffer; + bool output_use_buffer; + bool ouput_egl_buffers; + OMX_BOOL m_use_output_pmem; + OMX_BOOL m_out_mem_region_smi; + OMX_BOOL m_out_pvt_entry_pmem; + + int pending_input_buffers; + int pending_output_buffers; + // bitmask array size for output side + unsigned int m_out_bm_count; + // bitmask array size for input side + unsigned int m_inp_bm_count; + //Input port Populated + OMX_BOOL m_inp_bPopulated; + //Output port Populated + OMX_BOOL m_out_bPopulated; + // encapsulate the waiting states. + unsigned int m_flags; + +#ifdef _ANDROID_ + // Heap pointer to frame buffers + struct vidc_heap + { + sp video_heap_ptr; + }; + struct vidc_heap *m_heap_ptr; + unsigned int m_heap_count; +#endif //_ANDROID_ + // store I/P PORT state + OMX_BOOL m_inp_bEnabled; + // store O/P PORT state + OMX_BOOL m_out_bEnabled; + OMX_U32 m_in_alloc_cnt; + OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE]; + // Platform specific details + OMX_QCOM_PLATFORM_PRIVATE_LIST *m_platform_list; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *m_platform_entry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *m_pmem_info; + // SPS+PPS sent as part of set_config + OMX_VENDOR_EXTRADATATYPE m_vendor_config; + + /*Variables for arbitrary Byte parsing support*/ + frame_parse m_frame_parser; + omx_cmd_queue m_input_pending_q; + omx_cmd_queue m_input_free_q; + bool arbitrary_bytes; + OMX_BUFFERHEADERTYPE h264_scratch; + OMX_BUFFERHEADERTYPE *psource_frame; + OMX_BUFFERHEADERTYPE *pdest_frame; + OMX_BUFFERHEADERTYPE *m_inp_heap_ptr; + OMX_BUFFERHEADERTYPE **m_phdr_pmem_ptr; + unsigned int m_heap_inp_bm_count; + codec_type codec_type_parse; + bool first_frame_meta; + unsigned frame_count; + unsigned nal_count; + unsigned nal_length; + bool look_ahead_nal; + int first_frame; + unsigned char *first_buffer; + int first_frame_size; + unsigned char m_hwdevice_name[80]; + FILE *m_device_file_ptr; + enum vc1_profile_type m_vc1_profile; + OMX_S64 h264_last_au_ts; + OMX_U32 h264_last_au_flags; + OMX_U32 m_demux_offsets[8192]; + OMX_U32 m_demux_entries; + OMX_U32 m_disp_hor_size; + OMX_U32 m_disp_vert_size; + + OMX_S64 prev_ts; + bool rst_prev_ts; + OMX_U32 frm_int; + + struct vdec_allocatorproperty op_buf_rcnfg; + bool in_reconfig; + OMX_NATIVE_WINDOWTYPE m_display_id; + h264_stream_parser *h264_parser; + OMX_U32 client_extradata; +#ifdef _ANDROID_ + bool m_debug_timestamp; + bool perf_flag; + OMX_U32 proc_frms, latency; + perf_metrics fps_metrics; + perf_metrics dec_time; + bool m_enable_android_native_buffers; + bool m_use_android_native_buffers; + bool m_debug_extradata; + bool m_debug_concealedmb; +#endif +#ifdef MAX_RES_1080P + MP4_Utils mp4_headerparser; +#endif + + struct h264_mv_buffer{ + unsigned char* buffer; + int size; + int count; + int pmem_fd; + int offset; + }; + h264_mv_buffer h264_mv_buff; + + struct meta_buffer{ + unsigned char* buffer; + int size; + int count; + int pmem_fd; + int pmem_fd_iommu; + int offset; + }; + meta_buffer meta_buff; + extra_data_handler extra_data_handle; +#ifdef _ANDROID_ + DivXDrmDecrypt* iDivXDrmDecrypt; +#endif //_ANDROID_ + OMX_PARAM_PORTDEFINITIONTYPE m_port_def; + omx_time_stamp_reorder time_stamp_dts; + desc_buffer_hdr *m_desc_buffer_ptr; + bool secure_mode; + bool external_meta_buffer; + bool external_meta_buffer_iommu; + OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata; + bool codec_config_flag; +#ifdef _MSM8974_ + int capture_capability; + int output_capability; + bool streaming[MAX_PORT]; + OMX_CONFIG_RECTTYPE rectangle; + int prev_n_filled_len; +#endif + bool m_power_hinted; + OMX_ERRORTYPE power_module_register(); + OMX_ERRORTYPE power_module_deregister(); + bool msg_thread_created; + bool async_thread_created; + + OMX_VIDEO_PARAM_PROFILELEVELTYPE m_profile_lvl; + unsigned int m_fill_output_msg; + bool client_set_fps; + class allocate_color_convert_buf { + public: + allocate_color_convert_buf(); + ~allocate_color_convert_buf(); + void set_vdec_client(void *); + void update_client(); + bool set_color_format(OMX_COLOR_FORMATTYPE dest_color_format); + bool get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format); + bool update_buffer_req(); + bool get_buffer_req(unsigned int &buffer_size); + OMX_BUFFERHEADERTYPE* get_il_buf_hdr(); + OMX_BUFFERHEADERTYPE* get_il_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); + OMX_BUFFERHEADERTYPE* get_dr_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); + OMX_BUFFERHEADERTYPE* convert(OMX_BUFFERHEADERTYPE *header); + OMX_BUFFERHEADERTYPE* queue_buffer(OMX_BUFFERHEADERTYPE *header); + OMX_ERRORTYPE allocate_buffers_color_convert(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData, + OMX_U32 bytes); + OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + private: + #define MAX_COUNT 32 + omx_vdec *omx; + bool enabled; + OMX_COLOR_FORMATTYPE ColorFormat; + void init_members(); + bool color_convert_mode; + ColorConvertFormat dest_format; + class omx_c2d_conv c2d; + unsigned int allocated_count; + unsigned int buffer_size_req; + unsigned int buffer_alignment_req; + OMX_QCOM_PLATFORM_PRIVATE_LIST m_platform_list_client[MAX_COUNT]; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY m_platform_entry_client[MAX_COUNT]; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO m_pmem_info_client[MAX_COUNT]; + OMX_BUFFERHEADERTYPE m_out_mem_ptr_client[MAX_COUNT]; +#ifdef USE_ION + struct vdec_ion op_buf_ion_info[MAX_COUNT]; +#endif + unsigned char *pmem_baseaddress[MAX_COUNT]; + int pmem_fd[MAX_COUNT]; + struct vidc_heap + { + sp video_heap_ptr; + }; + struct vidc_heap m_heap_ptr[MAX_COUNT]; + }; +#if defined (_MSM8960_) || defined (_MSM8974_) + allocate_color_convert_buf client_buffers; +#endif + struct video_decoder_capability m_decoder_capability; +}; + +#ifdef _MSM8974_ +enum instance_state { + MSM_VIDC_CORE_UNINIT_DONE = 0x0001, + MSM_VIDC_CORE_INIT, + MSM_VIDC_CORE_INIT_DONE, + MSM_VIDC_OPEN, + MSM_VIDC_OPEN_DONE, + MSM_VIDC_LOAD_RESOURCES, + MSM_VIDC_LOAD_RESOURCES_DONE, + MSM_VIDC_START, + MSM_VIDC_START_DONE, + MSM_VIDC_STOP, + MSM_VIDC_STOP_DONE, + MSM_VIDC_RELEASE_RESOURCES, + MSM_VIDC_RELEASE_RESOURCES_DONE, + MSM_VIDC_CLOSE, + MSM_VIDC_CLOSE_DONE, + MSM_VIDC_CORE_UNINIT, +}; + +enum vidc_resposes_id { + MSM_VIDC_DECODER_FLUSH_DONE = 0x11, + MSM_VIDC_DECODER_EVENT_CHANGE, +}; + +#endif // _MSM8974_ + +#endif // __OMX_VDEC_H__ diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h new file mode 100644 index 00000000..43603583 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h @@ -0,0 +1,961 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2013, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef __OMX_VDEC_HEVC_H__ +#define __OMX_VDEC_HEVC_H__ +/*============================================================================ + O p e n M A X Component + Video Decoder + +*//** @file comx_vdec_hevc.h + This module contains the class definition for openMAX decoder component. + +*//*========================================================================*/ + +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include + +static ptrdiff_t x; + +#ifdef _ANDROID_ +#ifdef MAX_RES_720P +#define LOG_TAG "OMX-VDEC-720P" +#elif MAX_RES_1080P +#define LOG_TAG "OMX-VDEC-1080P" +#else +#define LOG_TAG "OMX-VDEC" +#endif + +#ifdef USE_ION +#include +#endif +#include +#include +extern "C"{ +#include +} +#include +#include +#include "hevc_utils.h" +#define TIMEOUT 5000 + +#else //_ANDROID_ +#define DEBUG_PRINT_LOW printf +#define DEBUG_PRINT_HIGH printf +#define DEBUG_PRINT_ERROR printf +#endif // _ANDROID_ + + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +#include +#endif + +#include + +#if defined (_ANDROID_ICS_) +#include +#endif + +#include +#ifndef PC_DEBUG +#include +#endif +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "qc_omx_component.h" +#include +#include +#include "frameparser.h" +#ifdef MAX_RES_1080P +#include "mp4_utils.h" +#endif +#include +#include "extra_data_handler.h" +#include "ts_parser.h" +#include "vidc_color_converter.h" +extern "C" { + OMX_API void * get_omx_component_factory_fn(void); +} + +#ifdef _ANDROID_ + using namespace android; +#ifdef USE_ION + class VideoHeap : public MemoryHeapBase + { + public: + VideoHeap(int devicefd, size_t size, void* base,struct ion_handle *handle,int mapfd); + virtual ~VideoHeap() {} + private: + int m_ion_device_fd; + struct ion_handle *m_ion_handle; + }; +#else + // local pmem heap object + class VideoHeap : public MemoryHeapBase + { + public: + VideoHeap(int fd, size_t size, void* base); + virtual ~VideoHeap() {} + }; +#endif +#endif // _ANDROID_ +////////////////////////////////////////////////////////////////////////////// +// Module specific globals +////////////////////////////////////////////////////////////////////////////// +#define OMX_SPEC_VERSION 0x00000101 + + +////////////////////////////////////////////////////////////////////////////// +// Macros +////////////////////////////////////////////////////////////////////////////// +#define PrintFrameHdr(bufHdr) DEBUG_PRINT("bufHdr %x buf %x size %d TS %d\n",\ + (unsigned) bufHdr,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp) + +// BitMask Management logic +#define BITS_PER_BYTE 32 +#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE) +#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE) +#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE)) +#define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ + &= ~(BITMASK_FLAG(mIndex)) +#define BITMASK_SET(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ + |= BITMASK_FLAG(mIndex) +#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) +#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) == 0x0) +#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) +#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) == 0x0) + +#define OMX_CORE_CONTROL_CMDQ_SIZE 100 +#define OMX_CORE_QCIF_HEIGHT 144 +#define OMX_CORE_QCIF_WIDTH 176 +#define OMX_CORE_VGA_HEIGHT 480 +#define OMX_CORE_VGA_WIDTH 640 +#define OMX_CORE_WVGA_HEIGHT 480 +#define OMX_CORE_WVGA_WIDTH 800 + +#define DESC_BUFFER_SIZE (8192 * 16) + +#ifdef _ANDROID_ +#define MAX_NUM_INPUT_OUTPUT_BUFFERS 32 +#endif + +#define OMX_FRAMEINFO_EXTRADATA 0x00010000 +#define OMX_INTERLACE_EXTRADATA 0x00020000 +#define OMX_TIMEINFO_EXTRADATA 0x00040000 +#define OMX_PORTDEF_EXTRADATA 0x00080000 +#define OMX_EXTNUSER_EXTRADATA 0x00100000 +#define DRIVER_EXTRADATA_MASK 0x0000FFFF + +#define OMX_INTERLACE_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ + sizeof(OMX_STREAMINTERLACEFORMAT) + 3)&(~3)) +#define OMX_FRAMEINFO_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ + sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO) + 3)&(~3)) +#define OMX_PORTDEF_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ + sizeof(OMX_PARAM_PORTDEFINITIONTYPE) + 3)&(~3)) + +// Define next macro with required values to enable default extradata, +// VDEC_EXTRADATA_MB_ERROR_MAP +// OMX_INTERLACE_EXTRADATA +// OMX_FRAMEINFO_EXTRADATA +// OMX_TIMEINFO_EXTRADATA + +//#define DEFAULT_EXTRADATA (OMX_FRAMEINFO_EXTRADATA|OMX_INTERLACE_EXTRADATA) + +enum port_indexes +{ + OMX_CORE_INPUT_PORT_INDEX =0, + OMX_CORE_OUTPUT_PORT_INDEX =1 +}; +#ifdef USE_ION +struct vdec_ion +{ + int ion_device_fd; + struct ion_fd_data fd_ion_data; + struct ion_allocation_data ion_alloc_data; +}; +#endif + +#ifdef _MSM8974_ +struct extradata_buffer_info { + int buffer_size; + char* uaddr; + int count; + int size; +#ifdef USE_ION + struct vdec_ion ion; +#endif +}; +#endif + +struct video_driver_context +{ + int video_driver_fd; + enum vdec_codec decoder_format; + enum vdec_output_fromat output_format; + enum vdec_interlaced_format interlace; + enum vdec_output_order picture_order; + struct vdec_picsize video_resolution; + struct vdec_allocatorproperty ip_buf; + struct vdec_allocatorproperty op_buf; + struct vdec_bufferpayload *ptr_inputbuffer; + struct vdec_bufferpayload *ptr_outputbuffer; + struct vdec_output_frameinfo *ptr_respbuffer; +#ifdef USE_ION + struct vdec_ion *ip_buf_ion_info; + struct vdec_ion *op_buf_ion_info; + struct vdec_ion h264_mv; + struct vdec_ion meta_buffer; + struct vdec_ion meta_buffer_iommu; +#endif + struct vdec_framerate frame_rate; + unsigned extradata; + bool timestamp_adjust; + char kind[128]; + bool idr_only_decoding; + unsigned disable_dmx; +#ifdef _MSM8974_ + struct extradata_buffer_info extradata_info; + int num_planes; +#endif +}; + +#ifdef _ANDROID_ +class DivXDrmDecrypt; +#endif //_ANDROID_ + +// OMX video decoder class +class omx_vdec: public qc_omx_component +{ + +public: + omx_vdec(); // constructor + virtual ~omx_vdec(); // destructor + + static int async_message_process (void *context, void* message); + static void process_event_cb(void *ctxt,unsigned char id); + + OMX_ERRORTYPE allocate_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes + ); + + + OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp); + + OMX_ERRORTYPE component_init(OMX_STRING role); + + OMX_ERRORTYPE component_role_enum( + OMX_HANDLETYPE hComp, + OMX_U8 *role, + OMX_U32 index + ); + + OMX_ERRORTYPE component_tunnel_request( + OMX_HANDLETYPE hComp, + OMX_U32 port, + OMX_HANDLETYPE peerComponent, + OMX_U32 peerPort, + OMX_TUNNELSETUPTYPE *tunnelSetup + ); + + OMX_ERRORTYPE empty_this_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + + + OMX_ERRORTYPE fill_this_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + + OMX_ERRORTYPE free_buffer( + OMX_HANDLETYPE hComp, + OMX_U32 port, + OMX_BUFFERHEADERTYPE *buffer + ); + + OMX_ERRORTYPE get_component_version( + OMX_HANDLETYPE hComp, + OMX_STRING componentName, + OMX_VERSIONTYPE *componentVersion, + OMX_VERSIONTYPE *specVersion, + OMX_UUIDTYPE *componentUUID + ); + + OMX_ERRORTYPE get_config( + OMX_HANDLETYPE hComp, + OMX_INDEXTYPE configIndex, + OMX_PTR configData + ); + + OMX_ERRORTYPE get_extension_index( + OMX_HANDLETYPE hComp, + OMX_STRING paramName, + OMX_INDEXTYPE *indexType + ); + + OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE paramIndex, + OMX_PTR paramData); + + OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp, + OMX_STATETYPE *state); + + + + OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp, + OMX_COMMANDTYPE cmd, + OMX_U32 param1, + OMX_PTR cmdData); + + + OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp, + OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData); + + OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE configIndex, + OMX_PTR configData); + + OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE paramIndex, + OMX_PTR paramData); + + OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8 *buffer); + + OMX_ERRORTYPE use_input_heap_buffers( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8* buffer); + + OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + void * eglImage); + void complete_pending_buffer_done_cbs(); + struct video_driver_context drv_ctx; +#ifdef _MSM8974_ + OMX_ERRORTYPE allocate_extradata(); + void free_extradata(); + void update_resolution(int width, int height); +#endif + int m_pipe_in; + int m_pipe_out; + pthread_t msg_thread_id; + pthread_t async_thread_id; + bool is_component_secure(); + +private: + // Bit Positions + enum flags_bit_positions + { + // Defer transition to IDLE + OMX_COMPONENT_IDLE_PENDING =0x1, + // Defer transition to LOADING + OMX_COMPONENT_LOADING_PENDING =0x2, + // First Buffer Pending + OMX_COMPONENT_FIRST_BUFFER_PENDING =0x3, + // Second Buffer Pending + OMX_COMPONENT_SECOND_BUFFER_PENDING =0x4, + // Defer transition to Enable + OMX_COMPONENT_INPUT_ENABLE_PENDING =0x5, + // Defer transition to Enable + OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x6, + // Defer transition to Disable + OMX_COMPONENT_INPUT_DISABLE_PENDING =0x7, + // Defer transition to Disable + OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x8, + //defer flush notification + OMX_COMPONENT_OUTPUT_FLUSH_PENDING =0x9, + OMX_COMPONENT_INPUT_FLUSH_PENDING =0xA, + OMX_COMPONENT_PAUSE_PENDING =0xB, + OMX_COMPONENT_EXECUTE_PENDING =0xC, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING =0xD, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE + }; + + // Deferred callback identifiers + enum + { + //Event Callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_EVENT = 0x1, + //Buffer Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2, + //Frame Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3, + //Buffer Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_FTB = 0x4, + //Frame Done callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_ETB = 0x5, + //Command + OMX_COMPONENT_GENERATE_COMMAND = 0x6, + //Push-Pending Buffers + OMX_COMPONENT_PUSH_PENDING_BUFS = 0x7, + // Empty Buffer Done callbacks + OMX_COMPONENT_GENERATE_EBD = 0x8, + //Flush Event Callbacks from the vdec component thread context + OMX_COMPONENT_GENERATE_EVENT_FLUSH = 0x9, + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH = 0x0A, + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH = 0x0B, + OMX_COMPONENT_GENERATE_FBD = 0xc, + OMX_COMPONENT_GENERATE_START_DONE = 0xD, + OMX_COMPONENT_GENERATE_PAUSE_DONE = 0xE, + OMX_COMPONENT_GENERATE_RESUME_DONE = 0xF, + OMX_COMPONENT_GENERATE_STOP_DONE = 0x10, + OMX_COMPONENT_GENERATE_HARDWARE_ERROR = 0x11, + OMX_COMPONENT_GENERATE_ETB_ARBITRARY = 0x12, + OMX_COMPONENT_GENERATE_PORT_RECONFIG = 0x13, + OMX_COMPONENT_GENERATE_EOS_DONE = 0x14, + OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG = 0x15, + OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED = 0x16, + }; + + enum vc1_profile_type + { + VC1_SP_MP_RCV = 1, + VC1_AP = 2 + }; + +#ifdef _MSM8974_ + enum v4l2_ports + { + CAPTURE_PORT, + OUTPUT_PORT, + MAX_PORT + }; +#endif + + struct omx_event + { + unsigned param1; + unsigned param2; + unsigned id; + }; + + struct omx_cmd_queue + { + omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE]; + unsigned m_read; + unsigned m_write; + unsigned m_size; + + omx_cmd_queue(); + ~omx_cmd_queue(); + bool insert_entry(unsigned p1, unsigned p2, unsigned id); + bool pop_entry(unsigned *p1,unsigned *p2, unsigned *id); + // get msgtype of the first ele from the queue + unsigned get_q_msg_type(); + + }; + +#ifdef _ANDROID_ + struct ts_entry + { + OMX_TICKS timestamp; + bool valid; + }; + + struct ts_arr_list + { + ts_entry m_ts_arr_list[MAX_NUM_INPUT_OUTPUT_BUFFERS]; + + ts_arr_list(); + ~ts_arr_list(); + + bool insert_ts(OMX_TICKS ts); + bool pop_min_ts(OMX_TICKS &ts); + bool reset_ts_list(); + }; +#endif + + struct desc_buffer_hdr + { + OMX_U8 *buf_addr; + OMX_U32 desc_data_size; + }; + bool allocate_done(void); + bool allocate_input_done(void); + bool allocate_output_done(void); + + OMX_ERRORTYPE free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + OMX_ERRORTYPE free_input_buffer(unsigned int bufferindex, + OMX_BUFFERHEADERTYPE *pmem_bufferHdr); + OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + void free_output_buffer_header(); + void free_input_buffer_header(); + + OMX_ERRORTYPE allocate_input_heap_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes); + + + OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes); + + OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port,OMX_PTR appData, + OMX_U32 bytes); + OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8 *buffer); +#ifdef MAX_RES_720P + OMX_ERRORTYPE get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); +#endif +#ifdef MAX_RES_1080P + OMX_ERRORTYPE get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); +#endif + + OMX_ERRORTYPE allocate_desc_buffer(OMX_U32 index); + OMX_ERRORTYPE allocate_output_headers(); + bool execute_omx_flush(OMX_U32); + bool execute_output_flush(); + bool execute_input_flush(); + OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE * buffer); + + OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE * buffer); + OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer); + + OMX_ERRORTYPE empty_this_buffer_proxy_arbitrary(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + OMX_ERRORTYPE push_input_buffer (OMX_HANDLETYPE hComp); + OMX_ERRORTYPE push_input_sc_codec (OMX_HANDLETYPE hComp); + OMX_ERRORTYPE push_input_h264 (OMX_HANDLETYPE hComp); + OMX_ERRORTYPE push_input_hevc (OMX_HANDLETYPE hComp); + OMX_ERRORTYPE push_input_vc1 (OMX_HANDLETYPE hComp); + + OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer); + bool release_done(); + + bool release_output_done(); + bool release_input_done(); + OMX_ERRORTYPE get_buffer_req(vdec_allocatorproperty *buffer_prop); + OMX_ERRORTYPE set_buffer_req(vdec_allocatorproperty *buffer_prop); + OMX_ERRORTYPE start_port_reconfig(); + OMX_ERRORTYPE update_picture_resolution(); + int stream_off(OMX_U32 port); + void adjust_timestamp(OMX_S64 &act_timestamp); + void set_frame_rate(OMX_S64 act_timestamp); + void handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr); + void handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr); + void print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra); +#ifdef _MSM8974_ + void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 interlaced_format_type); + OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool is_internal, + bool enable = true); + void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 num_conceal_mb, + OMX_U32 picture_type, + OMX_U32 frame_rate, + struct msm_vidc_panscan_window_payload *panscan_payload, + struct vdec_aspectratioinfo *aspect_ratio_info); +#else + void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 interlaced_format_type, OMX_U32 buf_index); + OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool enable = true); +#endif + void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 num_conceal_mb, + OMX_U32 picture_type, + OMX_S64 timestamp, + OMX_U32 frame_rate, + struct vdec_aspectratioinfo *aspect_ratio_info); + void fill_aspect_ratio_info(struct vdec_aspectratioinfo *aspect_ratio_info, + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info); + void append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra); + OMX_ERRORTYPE update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn); + void append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra); + void append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_extn); + void append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_user); + void insert_demux_addr_offset(OMX_U32 address_offset); + void extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr); + OMX_ERRORTYPE handle_demux_data(OMX_BUFFERHEADERTYPE *buf_hdr); + OMX_U32 count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra); + + bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, + OMX_U32 alignment); +#ifdef USE_ION + int alloc_map_ion_memory(OMX_U32 buffer_size, + OMX_U32 alignment, struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data,int flag); + void free_ion_memory(struct vdec_ion *buf_ion_info); +#endif + + + OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp, + OMX_COMMANDTYPE cmd, + OMX_U32 param1, + OMX_PTR cmdData); + bool post_event( unsigned int p1, + unsigned int p2, + unsigned int id + ); + inline int clip2(int x) + { + x = x -1; + x = x | x >> 1; + x = x | x >> 2; + x = x | x >> 4; + x = x | x >> 16; + x = x + 1; + return x; + } + +#ifdef MAX_RES_1080P + OMX_ERRORTYPE vdec_alloc_h264_mv(); + void vdec_dealloc_h264_mv(); + OMX_ERRORTYPE vdec_alloc_meta_buffers(); + void vdec_dealloc_meta_buffers(); +#endif + + inline void omx_report_error () + { + if (m_cb.EventHandler && !m_error_propogated) + { + ALOGE("\nERROR: Sending OMX_EventError to Client"); + m_error_propogated = true; + m_cb.EventHandler(&m_cmp,m_app_data, + OMX_EventError,OMX_ErrorHardware,0,NULL); + } + } +#ifdef _ANDROID_ + OMX_ERRORTYPE createDivxDrmContext(); +#endif //_ANDROID_ +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + OMX_ERRORTYPE use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data); +#endif +#if defined (_ANDROID_ICS_) + struct nativebuffer{ + native_handle_t *nativehandle; + private_handle_t *privatehandle; + int inuse; + }; + nativebuffer native_buffer[MAX_NUM_INPUT_OUTPUT_BUFFERS]; +#endif + + + //************************************************************* + //*******************MEMBER VARIABLES ************************* + //************************************************************* + pthread_mutex_t m_lock; + pthread_mutex_t c_lock; + //sem to handle the minimum procesing of commands + sem_t m_cmd_lock; + bool m_error_propogated; + // compression format + OMX_VIDEO_CODINGTYPE eCompressionFormat; + // OMX State + OMX_STATETYPE m_state; + // Application data + OMX_PTR m_app_data; + // Application callbacks + OMX_CALLBACKTYPE m_cb; + OMX_PRIORITYMGMTTYPE m_priority_mgm ; + OMX_PARAM_BUFFERSUPPLIERTYPE m_buffer_supplier; + // fill this buffer queue + omx_cmd_queue m_ftb_q; + // Command Q for rest of the events + omx_cmd_queue m_cmd_q; + omx_cmd_queue m_etb_q; + // Input memory pointer + OMX_BUFFERHEADERTYPE *m_inp_mem_ptr; + // Output memory pointer + OMX_BUFFERHEADERTYPE *m_out_mem_ptr; + // number of input bitstream error frame count + unsigned int m_inp_err_count; +#ifdef _ANDROID_ + // Timestamp list + ts_arr_list m_timestamp_list; +#endif + + bool input_flush_progress; + bool output_flush_progress; + bool input_use_buffer; + bool output_use_buffer; + bool ouput_egl_buffers; + OMX_BOOL m_use_output_pmem; + OMX_BOOL m_out_mem_region_smi; + OMX_BOOL m_out_pvt_entry_pmem; + + int pending_input_buffers; + int pending_output_buffers; + // bitmask array size for output side + unsigned int m_out_bm_count; + // bitmask array size for input side + unsigned int m_inp_bm_count; + //Input port Populated + OMX_BOOL m_inp_bPopulated; + //Output port Populated + OMX_BOOL m_out_bPopulated; + // encapsulate the waiting states. + unsigned int m_flags; + +#ifdef _ANDROID_ + // Heap pointer to frame buffers + struct vidc_heap + { + sp video_heap_ptr; + }; + struct vidc_heap *m_heap_ptr; + unsigned int m_heap_count; +#endif //_ANDROID_ + // store I/P PORT state + OMX_BOOL m_inp_bEnabled; + // store O/P PORT state + OMX_BOOL m_out_bEnabled; + OMX_U32 m_in_alloc_cnt; + OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE]; + // Platform specific details + OMX_QCOM_PLATFORM_PRIVATE_LIST *m_platform_list; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *m_platform_entry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *m_pmem_info; + // SPS+PPS sent as part of set_config + OMX_VENDOR_EXTRADATATYPE m_vendor_config; + + /*Variables for arbitrary Byte parsing support*/ + frame_parse m_frame_parser; + omx_cmd_queue m_input_pending_q; + omx_cmd_queue m_input_free_q; + bool arbitrary_bytes; + OMX_BUFFERHEADERTYPE h264_scratch; + OMX_BUFFERHEADERTYPE *psource_frame; + OMX_BUFFERHEADERTYPE *pdest_frame; + OMX_BUFFERHEADERTYPE *m_inp_heap_ptr; + OMX_BUFFERHEADERTYPE **m_phdr_pmem_ptr; + unsigned int m_heap_inp_bm_count; + codec_type codec_type_parse; + bool first_frame_meta; + unsigned frame_count; + unsigned nal_count; + unsigned nal_length; + bool look_ahead_nal; + int first_frame; + unsigned char *first_buffer; + int first_frame_size; + unsigned char m_hwdevice_name[80]; + FILE *m_device_file_ptr; + enum vc1_profile_type m_vc1_profile; + OMX_S64 h264_last_au_ts; + OMX_U32 h264_last_au_flags; + OMX_U32 m_demux_offsets[8192]; + OMX_U32 m_demux_entries; + OMX_U32 m_disp_hor_size; + OMX_U32 m_disp_vert_size; + + OMX_S64 prev_ts; + bool rst_prev_ts; + OMX_U32 frm_int; + + struct vdec_allocatorproperty op_buf_rcnfg; + bool in_reconfig; + OMX_NATIVE_WINDOWTYPE m_display_id; + h264_stream_parser *h264_parser; + OMX_U32 client_extradata; +#ifdef _ANDROID_ + bool m_debug_timestamp; + bool perf_flag; + OMX_U32 proc_frms, latency; + perf_metrics fps_metrics; + perf_metrics dec_time; + bool m_enable_android_native_buffers; + bool m_use_android_native_buffers; + bool m_debug_extradata; + bool m_debug_concealedmb; +#endif +#ifdef MAX_RES_1080P + MP4_Utils mp4_headerparser; +#endif + + struct h264_mv_buffer{ + unsigned char* buffer; + int size; + int count; + int pmem_fd; + int offset; + }; + h264_mv_buffer h264_mv_buff; + + struct meta_buffer{ + unsigned char* buffer; + int size; + int count; + int pmem_fd; + int pmem_fd_iommu; + int offset; + }; + meta_buffer meta_buff; + extra_data_handler extra_data_handle; +#ifdef _ANDROID_ + DivXDrmDecrypt* iDivXDrmDecrypt; +#endif //_ANDROID_ + OMX_PARAM_PORTDEFINITIONTYPE m_port_def; + omx_time_stamp_reorder time_stamp_dts; + desc_buffer_hdr *m_desc_buffer_ptr; + bool secure_mode; + bool external_meta_buffer; + bool external_meta_buffer_iommu; + OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata; + bool codec_config_flag; +#ifdef _MSM8974_ + int capture_capability; + int output_capability; + bool streaming[MAX_PORT]; + OMX_CONFIG_RECTTYPE rectangle; +#endif + bool m_power_hinted; + OMX_ERRORTYPE power_module_register(); + OMX_ERRORTYPE power_module_deregister(); + bool msg_thread_created; + bool async_thread_created; + + unsigned int m_fill_output_msg; + class allocate_color_convert_buf { + public: + allocate_color_convert_buf(); + ~allocate_color_convert_buf(); + void set_vdec_client(void *); + void update_client(); + bool set_color_format(OMX_COLOR_FORMATTYPE dest_color_format); + bool get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format); + bool update_buffer_req(); + bool get_buffer_req(unsigned int &buffer_size); + OMX_BUFFERHEADERTYPE* get_il_buf_hdr(); + OMX_BUFFERHEADERTYPE* get_il_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); + OMX_BUFFERHEADERTYPE* get_dr_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); + OMX_BUFFERHEADERTYPE* convert(OMX_BUFFERHEADERTYPE *header); + OMX_BUFFERHEADERTYPE* queue_buffer(OMX_BUFFERHEADERTYPE *header); + OMX_ERRORTYPE allocate_buffers_color_convert(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData, + OMX_U32 bytes); + OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + private: + #define MAX_COUNT 32 + omx_vdec *omx; + bool enabled; + OMX_COLOR_FORMATTYPE ColorFormat; + void init_members(); + bool color_convert_mode; + ColorConvertFormat dest_format; + class omx_c2d_conv c2d; + unsigned int allocated_count; + unsigned int buffer_size_req; + unsigned int buffer_alignment_req; + OMX_QCOM_PLATFORM_PRIVATE_LIST m_platform_list_client[MAX_COUNT]; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY m_platform_entry_client[MAX_COUNT]; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO m_pmem_info_client[MAX_COUNT]; + OMX_BUFFERHEADERTYPE m_out_mem_ptr_client[MAX_COUNT]; +#ifdef USE_ION + struct vdec_ion op_buf_ion_info[MAX_COUNT]; +#endif + unsigned char *pmem_baseaddress[MAX_COUNT]; + int pmem_fd[MAX_COUNT]; + struct vidc_heap + { + sp video_heap_ptr; + }; + struct vidc_heap m_heap_ptr[MAX_COUNT]; + }; +#if defined (_MSM8960_) || defined (_MSM8974_) + allocate_color_convert_buf client_buffers; +#endif + HEVC_Utils mHEVCutils; +}; + +#ifdef _MSM8974_ +enum instance_state { + MSM_VIDC_CORE_UNINIT_DONE = 0x0001, + MSM_VIDC_CORE_INIT, + MSM_VIDC_CORE_INIT_DONE, + MSM_VIDC_OPEN, + MSM_VIDC_OPEN_DONE, + MSM_VIDC_LOAD_RESOURCES, + MSM_VIDC_LOAD_RESOURCES_DONE, + MSM_VIDC_START, + MSM_VIDC_START_DONE, + MSM_VIDC_STOP, + MSM_VIDC_STOP_DONE, + MSM_VIDC_RELEASE_RESOURCES, + MSM_VIDC_RELEASE_RESOURCES_DONE, + MSM_VIDC_CLOSE, + MSM_VIDC_CLOSE_DONE, + MSM_VIDC_CORE_UNINIT, +}; + +enum vidc_resposes_id { + MSM_VIDC_DECODER_FLUSH_DONE = 0x11, + MSM_VIDC_DECODER_EVENT_CHANGE, +}; + +#endif // _MSM8974_ + +#endif // __OMX_VDEC_H__ diff --git a/mm-video-v4l2/vidc/vdec/inc/power_module.h b/mm-video-v4l2/vidc/vdec/inc/power_module.h new file mode 100644 index 00000000..59586a12 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/power_module.h @@ -0,0 +1,42 @@ +/*------------------------------------------------------------------------- +Copyright (c) 2012, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#include + +class PowerModule +{ + public: + static PowerModule *getInstance(); + power_module_t *getPowerModuleHandle(); + private: + static PowerModule *mPowerModuleInstance; + power_module_t *mPowerModuleHandle; + PowerModule() {} +}; diff --git a/mm-video-v4l2/vidc/vdec/inc/qtypes.h b/mm-video-v4l2/vidc/vdec/inc/qtypes.h new file mode 100755 index 00000000..63126af7 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/qtypes.h @@ -0,0 +1,90 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef QTYPES_H +#define QTYPES_H +/*=========================================================================== + + Data Declarations + +===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------------ +** Constants +** ------------------------------------------------------------------------ */ + +#ifdef TRUE +#undef TRUE +#endif + +#ifdef FALSE +#undef FALSE +#endif + +#define TRUE 1 /* Boolean true value. */ +#define FALSE 0 /* Boolean false value. */ + + + +/* ----------------------------------------------------------------------- +** Standard Types +** ----------------------------------------------------------------------- */ + +/* The following definitions are the same accross platforms. This first +** group are the sanctioned types. +*/ + +typedef unsigned char boolean; /* Boolean value type. */ + +typedef unsigned int uint32; /* Unsigned 32 bit value */ +typedef unsigned short uint16; /* Unsigned 16 bit value */ +typedef unsigned char uint8; /* Unsigned 8 bit value */ + +typedef int int32; /* Signed 32 bit value */ +typedef signed short int16; /* Signed 16 bit value */ +typedef signed char int8; /* Signed 8 bit value */ + +/* This group are the deprecated types. Their use should be +** discontinued and new code should use the types above +*/ +typedef unsigned char byte; /* Unsigned 8 bit value type. */ +typedef unsigned short word; /* Unsinged 16 bit value type. */ +typedef unsigned long dword; /* Unsigned 32 bit value type. */ + +typedef long long int64; +typedef unsigned long long uint64; + + +#ifdef __cplusplus +} +#endif + +#endif /* QTYPES_H */ diff --git a/mm-video-v4l2/vidc/vdec/inc/queue.h b/mm-video-v4l2/vidc/vdec/inc/queue.h new file mode 100755 index 00000000..f22e43c1 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/queue.h @@ -0,0 +1,39 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef QUEUE_H +#define QUEUE_H + +typedef struct Queue Queue; + +Queue *alloc_queue(); +void free_queue(Queue *q); +void free_queue_and_qelement(Queue *q); +int push(Queue *q, void * element); +void *pop(Queue *q); + +#endif diff --git a/mm-video-v4l2/vidc/vdec/inc/ts_parser.h b/mm-video-v4l2/vidc/vdec/inc/ts_parser.h new file mode 100755 index 00000000..8e884c77 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/inc/ts_parser.h @@ -0,0 +1,88 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef __DTSPARSER_H +#define __DTSPARSER_H + +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "qc_omx_component.h" + +#include + +#include +#include + +#ifdef _ANDROID_ +extern "C"{ +#include +} +#else +#define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args) +#endif /* _ANDROID_ */ + +class omx_time_stamp_reorder { +public: + omx_time_stamp_reorder(); + ~omx_time_stamp_reorder(); + void set_timestamp_reorder_mode(bool flag); + void enable_debug_print(bool flag); + bool insert_timestamp(OMX_BUFFERHEADERTYPE *header); + bool get_next_timestamp(OMX_BUFFERHEADERTYPE *header, bool is_interlaced); + bool remove_time_stamp(OMX_TICKS ts, bool is_interlaced); + void flush_timestamp(); + +private: + #define TIME_SZ 64 + typedef struct timestamp { + OMX_TICKS timestamps; + bool in_use; + }timestamp; + typedef struct time_stamp_list { + timestamp input_timestamps[TIME_SZ]; + time_stamp_list *next; + time_stamp_list *prev; + unsigned int entries_filled; + }time_stamp_list; + bool error; + time_stamp_list *phead,*pcurrent; + bool get_current_list(); + bool add_new_list(); + bool update_head(); + void delete_list(); + void handle_error() + { + ALOGE("Error handler called for TS Parser"); + if (error) + return; + error = true; + delete_list(); + } + bool reorder_ts; + bool print_debug; +}; +#endif diff --git a/mm-video-v4l2/vidc/vdec/src/frameparser.cpp b/mm-video-v4l2/vidc/vdec/src/frameparser.cpp new file mode 100755 index 00000000..c591f5fd --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/frameparser.cpp @@ -0,0 +1,688 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "frameparser.h" +//#include "omx_vdec.h" + +#ifdef _ANDROID_ + extern "C"{ + #include + } +#endif//_ANDROID_ + +#undef DEBUG_PRINT_LOW +#undef DEBUG_PRINT_HIGH +#undef DEBUG_PRINT_ERROR + +#define DEBUG_PRINT_LOW ALOGV +#define DEBUG_PRINT_HIGH ALOGV +#define DEBUG_PRINT_ERROR ALOGE + +static unsigned char H264_mask_code[4] = {0xFF,0xFF,0xFF,0xFF}; +static unsigned char H264_start_code[4] = {0x00,0x00,0x00,0x01}; + +static unsigned char MPEG4_start_code[4] = {0x00,0x00,0x01,0xB6}; +static unsigned char MPEG4_mask_code[4] = {0xFF,0xFF,0xFF,0xFF}; + +static unsigned char H263_start_code[4] = {0x00,0x00,0x80,0x00}; +static unsigned char H263_mask_code[4] = {0xFF,0xFF,0xFC,0x00}; + +static unsigned char VC1_AP_start_code[4] = {0x00,0x00,0x01,0x0C}; +static unsigned char VC1_AP_mask_code[4] = {0xFF,0xFF,0xFF,0xFC}; + +static unsigned char MPEG2_start_code[4] = {0x00, 0x00, 0x01, 0x00}; +static unsigned char MPEG2_mask_code[4] = {0xFF, 0xFF, 0xFF, 0xFF}; + +frame_parse::frame_parse():mutils(NULL), + parse_state(A0), + start_code(NULL), + mask_code(NULL), + last_byte_h263(0), + last_byte(0), + header_found(false), + skip_frame_boundary(false), + state_nal(NAL_LENGTH_ACC), + nal_length(0), + accum_length(0), + bytes_tobeparsed(0) +{ +} + +frame_parse::~frame_parse () +{ + if (mutils) + delete mutils; + + mutils = NULL; +} + +int frame_parse::init_start_codes (codec_type codec_type_parse) +{ + /*Check if Codec Type is proper and we are in proper state*/ + if (codec_type_parse > CODEC_TYPE_MAX || parse_state != A0) + { + return -1; + } + + switch (codec_type_parse) + { + case CODEC_TYPE_MPEG4: + start_code = MPEG4_start_code; + mask_code = MPEG4_mask_code; + break; + case CODEC_TYPE_H263: + start_code = H263_start_code; + mask_code = H263_mask_code; + break; + case CODEC_TYPE_H264: + case CODEC_TYPE_HEVC: + start_code = H264_start_code; + mask_code = H264_mask_code; + break; + case CODEC_TYPE_VC1: + start_code = VC1_AP_start_code; + mask_code = VC1_AP_mask_code; + break; + case CODEC_TYPE_MPEG2: + start_code = MPEG2_start_code; + mask_code = MPEG2_mask_code; + break; +#ifdef _MSM8974_ + case CODEC_TYPE_VP8: + break; +#endif + default: + return -1; + } + return 1; +} + + +int frame_parse::init_nal_length (unsigned int nal_len) +{ + if (nal_len == 0 || nal_len > 4 || state_nal != NAL_LENGTH_ACC) + { + return -1; + } + nal_length = nal_len; + + return 1; +} + +int frame_parse::parse_sc_frame ( OMX_BUFFERHEADERTYPE *source, + OMX_BUFFERHEADERTYPE *dest , + OMX_U32 *partialframe) +{ + OMX_U8 *pdest = NULL,*psource = NULL, match_found = FALSE, is_byte_match = 0; + OMX_U32 dest_len =0, source_len = 0, temp_len = 0; + OMX_U32 parsed_length = 0,i=0; + int residue_byte = 0; + + if (source == NULL || dest == NULL || partialframe == NULL) + { + return -1; + } + + /*Calculate how many bytes are left in source and destination*/ + dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); + psource = source->pBuffer + source->nOffset; + pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); + source_len = source->nFilledLen; + + /*Need Minimum Start Code size for destination to copy atleast Start code*/ + if ((start_code == H263_start_code && dest_len < 3) || + (start_code != H263_start_code && dest_len < 4) || (source_len == 0)) + { + DEBUG_PRINT_LOW("\n FrameParser: dest_len %d source_len %d",dest_len,source_len); + if (source_len == 0 && (source->nFlags & 0x01)) + { + DEBUG_PRINT_LOW("\n FrameParser: EOS rxd!! Notify it as a complete frame"); + *partialframe = 0; + return 1; + } + DEBUG_PRINT_LOW("\n FrameParser: Bitstream Parsing error"); + return -1; + } + + /*Check if State of the previous find is a Start code*/ + if (parse_state == A4 || parse_state == A5) + { + /*Check for minimun size should be 4*/ + dest->nFlags = source->nFlags; + dest->nTimeStamp = source->nTimeStamp; + + if(start_code == H263_start_code) + { + memcpy (pdest,start_code,2); + pdest[2] = last_byte_h263; + dest->nFilledLen += 3; + pdest += 3; + } + else + { + memcpy (pdest,start_code,4); + if (start_code == VC1_AP_start_code + || start_code == MPEG4_start_code + || start_code == MPEG2_start_code) + { + pdest[3] = last_byte; + update_skip_frame(); + } + dest->nFilledLen += 4; + pdest += 4; + } + parse_state = A0; + } + + /*Entry State Machine*/ + while ( source->nFilledLen > 0 && parse_state != A0 + && parse_state != A4 && parse_state != A5 && dest_len > 0 + ) + { + //printf ("\n In the Entry Loop"); + switch (parse_state) + { + case A3: + parse_additional_start_code(psource,&parsed_length); + if (parse_state == A4) { + source->nFilledLen--; + source->nOffset++; + psource++; + break; + } + /*If fourth Byte is matching then start code is found*/ + if ((*psource & mask_code [3]) == start_code [3]) + { + parse_state = A4; + last_byte = *psource; + source->nFilledLen--; + source->nOffset++; + psource++; + } + else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) + { + parse_state = A2; + memcpy (pdest,start_code,1); + pdest++; + dest->nFilledLen++; + dest_len--; + } + else if (start_code [2] == start_code [0]) + { + parse_state = A1; + memcpy (pdest,start_code,2); + pdest += 2; + dest->nFilledLen += 2; + dest_len -= 2; + } + else + { + parse_state = A0; + memcpy (pdest,start_code,3); + pdest += 3; + dest->nFilledLen +=3; + dest_len -= 3; + } + break; + + case A2: + is_byte_match = ((*psource & mask_code [2]) == start_code [2]); + match_found = FALSE; + + if (start_code == H263_start_code) + { + if (is_byte_match) + { + last_byte_h263 = *psource; + parse_state = A5; + match_found = TRUE; + } + } + else if (start_code == H264_start_code && + (*psource & mask_code [3]) == start_code [3]) + { + parse_state = A5; + match_found = TRUE; + } + else + { + if (is_byte_match) + { + parse_state = A3; + match_found = TRUE; + } + } + + if (match_found) + { + source->nFilledLen--; + source->nOffset++; + psource++; + } + else if (start_code [1] == start_code [0]) + { + parse_state = A1; + memcpy (pdest,start_code,1); + dest->nFilledLen +=1; + dest_len--; + pdest++; + } + else + { + parse_state = A0; + memcpy (pdest,start_code,2); + dest->nFilledLen +=2; + dest_len -= 2; + pdest += 2; + } + + break; + + case A1: + if ((*psource & mask_code [1]) == start_code [1]) + { + parse_state = A2; + source->nFilledLen--; + source->nOffset++; + psource++; + } + else + { + memcpy (pdest,start_code,1); + dest->nFilledLen +=1; + pdest++; + dest_len--; + parse_state = A0; + } + break; + case A4: + case A0: + case A5: + break; + } + dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); + } + + if (parse_state == A4 || parse_state == A5) + { + *partialframe = 0; + check_skip_frame_boundary(partialframe); + DEBUG_PRINT_LOW("\n FrameParser: Parsed Len = %d", dest->nFilledLen); + return 1; + } + + /*Partial Frame is true*/ + *partialframe = 1; + + /*Calculate how many bytes are left in source and destination*/ + dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); + psource = source->pBuffer + source->nOffset; + pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); + source_len = source->nFilledLen; + + temp_len = (source_len < dest_len)?source_len:dest_len; + + /*Check if entry state machine consumed source or destination*/ + if (temp_len == 0) + { + return 1; + } + + /*Parsing State Machine*/ + while (parsed_length < temp_len) + { + switch (parse_state) + { + case A0: + if ((psource [parsed_length] & mask_code [0]) == start_code[0]) + { + parse_state = A1; + } + parsed_length++; + break; + case A1: + if ((psource [parsed_length] & mask_code [1]) == start_code [1]) + { + parsed_length++; + parse_state = A2; + } + else + { + parse_state = A0; + } + break; + case A2: + is_byte_match = ((psource[parsed_length] & mask_code [2]) == start_code [2]); + match_found = FALSE; + + if (start_code == H263_start_code) + { + if (is_byte_match) + { + last_byte_h263 = psource[parsed_length]; + parse_state = A5; + match_found = TRUE; + } + } + else if (start_code == H264_start_code && + (psource[parsed_length] & mask_code [3]) == start_code [3]) + { + parse_state = A5; + match_found = TRUE; + } + else + { + if(is_byte_match) + { + parse_state = A3; + match_found = TRUE; + } + } + + if (match_found) + { + parsed_length++; + } + else if (start_code [1] == start_code [0]) + { + parse_state = A1; + } + else + { + parse_state = A0; + } + + break; + case A3: + parse_additional_start_code(psource,&parsed_length); + if (parse_state == A4) break; + + if ((psource [parsed_length] & mask_code [3]) == start_code [3]) + { + last_byte = psource [parsed_length]; + parsed_length++; + parse_state = A4; + } + else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) + { + parse_state = A2; + } + else if (start_code [2] == start_code [0]) + { + parse_state = A1; + } + else + { + parse_state = A0; + } + break; + case A4: + case A5: + break; + } + + /*Found the code break*/ + if (parse_state == A4 || parse_state == A5) + { + break; + } + } + + /*Exit State Machine*/ + psource = source->pBuffer + source->nOffset; + switch (parse_state) + { + case A5: + *partialframe = 0; + check_skip_frame_boundary(partialframe); + if (parsed_length > 3) + { + memcpy (pdest,psource,(parsed_length-3)); + dest->nFilledLen += (parsed_length-3); + } + break; + case A4: + *partialframe = 0; + check_skip_frame_boundary(partialframe); + if (parsed_length > 4) + { + memcpy (pdest,psource,(parsed_length-4)); + dest->nFilledLen += (parsed_length-4); + } + break; + case A3: + if (parsed_length > 3) + { + memcpy (pdest,psource,(parsed_length-3)); + dest->nFilledLen += (parsed_length-3); + } + break; + case A2: + if (parsed_length > 2) + { + memcpy (pdest,psource,(parsed_length-2)); + dest->nFilledLen += (parsed_length-2); + } + break; + case A1: + if (parsed_length > 1) + { + memcpy (pdest,psource,(parsed_length-1)); + dest->nFilledLen += (parsed_length-1); + } + break; + case A0: + memcpy (pdest,psource,(parsed_length)); + dest->nFilledLen += (parsed_length); + break; + } + + if (source->nFilledLen < parsed_length) + { + printf ("\n FATAL Error"); + return -1; + } + source->nFilledLen -= parsed_length; + source->nOffset += parsed_length; + + return 1; +} + + +int frame_parse::parse_h264_nallength (OMX_BUFFERHEADERTYPE *source, + OMX_BUFFERHEADERTYPE *dest , + OMX_U32 *partialframe) +{ + OMX_U8 *pdest = NULL,*psource = NULL; + OMX_U32 dest_len =0, source_len = 0, temp_len = 0,parsed_length = 0; + + if (source == NULL || dest == NULL || partialframe == NULL) + { + return -1; + } + + /*Calculate the length's*/ + dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); + source_len = source->nFilledLen; + + if (dest_len < 4 || source_len == 0 || nal_length == 0) + { + DEBUG_PRINT_LOW("\n FrameParser: NAL Parsing Error! dest_len %d " + "source_len %d nal_length %d", dest_len, source_len, nal_length); + return -1; + } + *partialframe = 1; + temp_len = (source_len < dest_len)?source_len:dest_len; + psource = source->pBuffer + source->nOffset; + pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); + + /* Find the Bytes to Accumalte*/ + if (state_nal == NAL_LENGTH_ACC) + { + while (parsed_length < temp_len ) + { + bytes_tobeparsed |= (((OMX_U32)(*psource))) << (((nal_length-accum_length-1) << 3)); + + /*COPY THE DATA FOR C-SIM TO BE REOMVED ON TARGET*/ + //*pdest = *psource; + accum_length++; + source->nFilledLen--; + source->nOffset++; + psource++; + //dest->nFilledLen++; + //pdest++; + parsed_length++; + + if (accum_length == nal_length) + { + accum_length = 0; + state_nal = NAL_PARSING; + memcpy (pdest,H264_start_code,4); + dest->nFilledLen += 4; + break; + } + } + } + + dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); + source_len = source->nFilledLen; + temp_len = (source_len < dest_len)?source_len:dest_len; + + psource = source->pBuffer + source->nOffset; + pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); + + dest->nTimeStamp = source->nTimeStamp; + dest->nFlags = source->nFlags; + + /*Already in Parsing state go ahead and copy*/ + if(state_nal == NAL_PARSING && temp_len > 0) + { + if (temp_len < bytes_tobeparsed) + { + memcpy (pdest,psource,temp_len); + dest->nFilledLen += temp_len; + source->nOffset += temp_len; + source->nFilledLen -= temp_len; + bytes_tobeparsed -= temp_len; + } + else + { + memcpy (pdest,psource,bytes_tobeparsed); + temp_len -= bytes_tobeparsed; + dest->nFilledLen += bytes_tobeparsed; + source->nOffset += bytes_tobeparsed; + source->nFilledLen -= bytes_tobeparsed; + bytes_tobeparsed = 0; + } + } + + if (bytes_tobeparsed == 0 && state_nal == NAL_PARSING) + { + *partialframe = 0; + state_nal = NAL_LENGTH_ACC; + } + + return 1; +} + +void frame_parse::flush () +{ + parse_state = A0; + state_nal = NAL_LENGTH_ACC; + accum_length = 0; + bytes_tobeparsed = 0; + header_found = false; + skip_frame_boundary = false; +} + +void frame_parse::parse_additional_start_code(OMX_U8 *psource, + OMX_U32 *parsed_length) +{ + + if (((start_code == MPEG4_start_code) || + (start_code == MPEG2_start_code)) && + psource && + parsed_length) + { + OMX_U32 index = *parsed_length; + if ((start_code == MPEG4_start_code && + (psource [index] & 0xF0) == 0x20) || + (start_code == MPEG2_start_code && + psource [index] == 0xB3)) + { + if (header_found) + { + last_byte = psource [index]; + index++; + parse_state = A4; + } else + header_found = true; + } + *parsed_length = index; + } +} + +void frame_parse::check_skip_frame_boundary(OMX_U32 *partialframe) +{ + if ((start_code == MPEG4_start_code || + start_code == MPEG2_start_code) && + partialframe) { + + *partialframe = 1; + if (!skip_frame_boundary) + *partialframe = 0; + skip_frame_boundary = false; + } +} + +void frame_parse::update_skip_frame() +{ + if (((start_code == MPEG4_start_code) && + ((last_byte & 0xF0) == 0x20)) || + ((start_code == MPEG2_start_code) && + (last_byte == 0xB3))) { + + skip_frame_boundary = true; + } +} diff --git a/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp b/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp new file mode 100644 index 00000000..651bb6b4 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp @@ -0,0 +1,1700 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +/*======================================================================== + + O p e n M M + V i d e o U t i l i t i e s + +*//** @file VideoUtils.cpp + This module contains utilities and helper routines. + +@par EXTERNALIZED FUNCTIONS + +@par INITIALIZATION AND SEQUENCING REQUIREMENTS + (none) + +*//*====================================================================== */ + +/* ======================================================================= + + INCLUDE FILES FOR MODULE + +========================================================================== */ +#include "h264_utils.h" +#include "extra_data_handler.h" +#include +#include +#include +#include +#ifdef _ANDROID_ +#include + extern "C"{ + #include + } + +#endif + +/* ======================================================================= + + DEFINITIONS AND DECLARATIONS FOR MODULE + +This section contains definitions for constants, macros, types, variables +and other items needed by this module. + +========================================================================== */ + +#define SIZE_NAL_FIELD_MAX 4 +#define BASELINE_PROFILE 66 +#define MAIN_PROFILE 77 +#define HIGH_PROFILE 100 + +#define MAX_SUPPORTED_LEVEL 32 + +RbspParser::RbspParser (const uint8 *_begin, const uint8 *_end) +: begin (_begin), end(_end), pos (- 1), bit (0), +cursor (0xFFFFFF), advanceNeeded (true) +{ +} + +// Destructor +/*lint -e{1540} Pointer member neither freed nor zeroed by destructor + * No problem + */ +RbspParser::~RbspParser () {} + +// Return next RBSP byte as a word +uint32 RbspParser::next () +{ + if (advanceNeeded) advance (); + //return static_cast (*pos); + return static_cast (begin[pos]); +} + +// Advance RBSP decoder to next byte +void RbspParser::advance () +{ + ++pos; + //if (pos >= stop) + if (begin + pos == end) + { + /*lint -e{730} Boolean argument to function + * I don't see a problem here + */ + //throw false; + ALOGV("H264Parser-->NEED TO THROW THE EXCEPTION...\n"); + } + cursor <<= 8; + //cursor |= static_cast (*pos); + cursor |= static_cast (begin[pos]); + if ((cursor & 0xFFFFFF) == 0x000003) + { + advance (); + } + advanceNeeded = false; +} + +// Decode unsigned integer +uint32 RbspParser::u (uint32 n) +{ + uint32 i, s, x = 0; + for (i = 0; i < n; i += s) + { + s = static_castSTD_MIN(static_cast(8 - bit), + static_cast(n - i)); + x <<= s; + + x |= ((next () >> ((8 - static_cast(bit)) - s)) & + ((1 << s) - 1)); + + bit = (bit + s) % 8; + if (!bit) + { + advanceNeeded = true; + } + } + return x; +} + +// Decode unsigned integer Exp-Golomb-coded syntax element +uint32 RbspParser::ue () +{ + int leadingZeroBits = -1; + for (uint32 b = 0; !b; ++leadingZeroBits) + { + b = u (1); + } + return ((1 << leadingZeroBits) - 1) + + u (static_cast(leadingZeroBits)); +} + +// Decode signed integer Exp-Golomb-coded syntax element +int32 RbspParser::se () +{ + const uint32 x = ue (); + if (!x) return 0; + else if (x & 1) return static_cast ((x >> 1) + 1); + else return - static_cast (x >> 1); +} + +void H264_Utils::allocate_rbsp_buffer(uint32 inputBufferSize) +{ + m_rbspBytes = (byte *) calloc(1,inputBufferSize); + m_prv_nalu.nal_ref_idc = 0; + m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED; +} + +H264_Utils::H264_Utils(): m_height(0), + m_width(0), + m_rbspBytes(NULL), + m_au_data (false) +{ + initialize_frame_checking_environment(); +} + +H264_Utils::~H264_Utils() +{ +/* if(m_pbits) + { + delete(m_pbits); + m_pbits = NULL; + } +*/ + if (m_rbspBytes) + { + free(m_rbspBytes); + m_rbspBytes = NULL; + } +} + +/***********************************************************************/ +/* +FUNCTION: + H264_Utils::initialize_frame_checking_environment + +DESCRIPTION: + Extract RBSP data from a NAL + +INPUT/OUTPUT PARAMETERS: + None + +RETURN VALUE: + boolean + +SIDE EFFECTS: + None. +*/ +/***********************************************************************/ +void H264_Utils::initialize_frame_checking_environment() +{ + m_forceToStichNextNAL = false; + m_au_data = false; + m_prv_nalu.nal_ref_idc = 0; + m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED; +} + +/***********************************************************************/ +/* +FUNCTION: + H264_Utils::extract_rbsp + +DESCRIPTION: + Extract RBSP data from a NAL + +INPUT/OUTPUT PARAMETERS: + + buffer : buffer containing start code or nal length + NAL units + buffer_length : the length of the NAL buffer + start_code : If true, start code is detected, + otherwise size nal length is detected + size_of_nal_length_field: size of nal length field + + + rbsp_bistream : extracted RBSP bistream + rbsp_length : the length of the RBSP bitstream + nal_unit : decoded NAL header information + +RETURN VALUE: + boolean + +SIDE EFFECTS: + None. +*/ +/***********************************************************************/ + +boolean H264_Utils::extract_rbsp(OMX_IN OMX_U8 *buffer, + OMX_IN OMX_U32 buffer_length, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_U8 *rbsp_bistream, + OMX_OUT OMX_U32 *rbsp_length, + OMX_OUT NALU *nal_unit) +{ + byte coef1, coef2, coef3; + uint32 pos = 0; + uint32 nal_len = buffer_length; + uint32 sizeofNalLengthField = 0; + uint32 zero_count; + boolean eRet = true; + boolean start_code = (size_of_nal_length_field==0)?true:false; + + if(start_code) { + // Search start_code_prefix_one_3bytes (0x000001) + coef2 = buffer[pos++]; + coef3 = buffer[pos++]; + do { + if(pos >= buffer_length) + { + ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + + coef1 = coef2; + coef2 = coef3; + coef3 = buffer[pos++]; + } while(coef1 || coef2 || coef3 != 1); + } + else if (size_of_nal_length_field) + { + /* This is the case to play multiple NAL units inside each access unit*/ + /* Extract the NAL length depending on sizeOfNALength field */ + sizeofNalLengthField = size_of_nal_length_field; + nal_len = 0; + while(size_of_nal_length_field--) + { + nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3); + } + if (nal_len >= buffer_length) + { + ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + } + + if (nal_len > buffer_length) + { + ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + if(pos + 1 > (nal_len + sizeofNalLengthField)) + { + ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + if ((nal_unit->forbidden_zero_bit = (buffer[pos] & 0x80)) != 0) + { + ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); + } + nal_unit->nal_ref_idc = (buffer[pos] & 0x60) >> 5; + nal_unit->nalu_type = buffer[pos++] & 0x1f; + ALOGV("\n@#@# Pos = %x NalType = %x buflen = %d", + pos-1, nal_unit->nalu_type, buffer_length); + *rbsp_length = 0; + + + if( nal_unit->nalu_type == NALU_TYPE_EOSEQ || + nal_unit->nalu_type == NALU_TYPE_EOSTREAM) + return (nal_len + sizeofNalLengthField); + + zero_count = 0; + while (pos < (nal_len+sizeofNalLengthField)) //similar to for in p-42 + { + if( zero_count == 2 ) { + if( buffer[pos] == 0x03 ) { + pos ++; + zero_count = 0; + continue; + } + if( buffer[pos] <= 0x01 ) { + if( start_code ) { + *rbsp_length -= 2; + pos -= 2; + return pos; + } + } + zero_count = 0; + } + zero_count ++; + if( buffer[pos] != 0 ) + zero_count = 0; + + rbsp_bistream[(*rbsp_length)++] = buffer[pos++]; + } + + return eRet; +} + +/*=========================================================================== +FUNCTION: + H264_Utils::iSNewFrame + +DESCRIPTION: + Returns true if NAL parsing successfull otherwise false. + +INPUT/OUTPUT PARAMETERS: + + buffer : buffer containing start code or nal length + NAL units + buffer_length : the length of the NAL buffer + start_code : If true, start code is detected, + otherwise size nal length is detected + size_of_nal_length_field: size of nal length field + + isNewFrame: true if the NAL belongs to a differenet frame + false if the NAL belongs to a current frame + +RETURN VALUE: + boolean true, if nal parsing is successful + false, if the nal parsing has errors + +SIDE EFFECTS: + None. +===========================================================================*/ +bool H264_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_BOOL &isNewFrame) +{ + NALU nal_unit; + uint16 first_mb_in_slice = 0; + OMX_IN OMX_U32 numBytesInRBSP = 0; + OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer; + OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen; + bool eRet = true; + + ALOGV("isNewFrame: buffer %p buffer_length %d " + "size_of_nal_length_field %d\n", buffer, buffer_length, + size_of_nal_length_field); + + if ( false == extract_rbsp(buffer, buffer_length, size_of_nal_length_field, + m_rbspBytes, &numBytesInRBSP, &nal_unit) ) + { + ALOGE("ERROR: In %s() - extract_rbsp() failed", __func__); + isNewFrame = OMX_FALSE; + eRet = false; + } + else + { + nalu_type = nal_unit.nalu_type; + switch (nal_unit.nalu_type) + { + case NALU_TYPE_IDR: + case NALU_TYPE_NON_IDR: + { + ALOGV("\n AU Boundary with NAL type %d ",nal_unit.nalu_type); + if (m_forceToStichNextNAL) + { + isNewFrame = OMX_FALSE; + } + else + { + RbspParser rbsp_parser(m_rbspBytes, (m_rbspBytes+numBytesInRBSP)); + first_mb_in_slice = rbsp_parser.ue(); + + if((!first_mb_in_slice) || /*(slice.prv_frame_num != slice.frame_num ) ||*/ + ( (m_prv_nalu.nal_ref_idc != nal_unit.nal_ref_idc) && ( nal_unit.nal_ref_idc * m_prv_nalu.nal_ref_idc == 0 ) ) || + /*( ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) && (nal_unit.nalu_type == NALU_TYPE_IDR)) && (slice.idr_pic_id != slice.prv_idr_pic_id) ) || */ + ( (m_prv_nalu.nalu_type != nal_unit.nalu_type ) && ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) || (nal_unit.nalu_type == NALU_TYPE_IDR)) ) ) + { + //ALOGV("Found a New Frame due to NALU_TYPE_IDR/NALU_TYPE_NON_IDR"); + isNewFrame = OMX_TRUE; + } + else + { + isNewFrame = OMX_FALSE; + } + } + m_au_data = true; + m_forceToStichNextNAL = false; + break; + } + case NALU_TYPE_SPS: + case NALU_TYPE_PPS: + case NALU_TYPE_SEI: + { + ALOGV("\n Non-AU boundary with NAL type %d", nal_unit.nalu_type); + if(m_au_data) + { + isNewFrame = OMX_TRUE; + m_au_data = false; + } + else + { + isNewFrame = OMX_FALSE; + } + + m_forceToStichNextNAL = true; + break; + } + case NALU_TYPE_ACCESS_DELIM: + case NALU_TYPE_UNSPECIFIED: + case NALU_TYPE_EOSEQ: + case NALU_TYPE_EOSTREAM: + default: + { + isNewFrame = OMX_FALSE; + // Do not update m_forceToStichNextNAL + break; + } + } // end of switch + } // end of if + m_prv_nalu = nal_unit; + ALOGV("get_h264_nal_type - newFrame value %d\n",isNewFrame); + return eRet; +} + +void perf_metrics::start() +{ + if (!active) + { + start_time = get_act_time(); + active = true; + } +} + +void perf_metrics::stop() +{ + OMX_U64 stop_time = get_act_time(); + if (active) + { + proc_time += (stop_time - start_time); + active = false; + } +} + +void perf_metrics::end(OMX_U32 units_cntr) +{ + stop(); + ALOGV("--> Processing time : [%.2f] Sec", (float)proc_time / 1e6); + if (units_cntr) + { + ALOGV("--> Avrg proc time : [%.2f] mSec", proc_time / (float)(units_cntr * 1e3)); + } +} + +void perf_metrics::reset() +{ + start_time = 0; + proc_time = 0; + active = false; +} + +OMX_U64 perf_metrics::get_act_time() +{ + struct timeval act_time = {0, 0}; + gettimeofday(&act_time, NULL); + return (act_time.tv_usec + act_time.tv_sec * 1e6); +} + +OMX_U64 perf_metrics::processing_time_us() +{ + return proc_time; +} + +h264_stream_parser::h264_stream_parser() +{ + reset(); +#ifdef PANSCAN_HDLR + panscan_hdl = new panscan_handler(); + if (!panscan_hdl) + { + ALOGE("ERROR: Panscan hdl was not allocated!"); + } + else if (!panscan_hdl->initialize(10)) + { + ALOGE("ERROR: Allocating memory for panscan!"); + delete panscan_hdl; + panscan_hdl = NULL; + } +#else + memset(&panscan_param, 0, sizeof(panscan_param)); + panscan_param.rect_id = NO_PAN_SCAN_BIT; +#endif +} + +h264_stream_parser::~h264_stream_parser() +{ +#ifdef PANSCAN_HDLR + if (panscan_hdl) + { + delete panscan_hdl; + panscan_hdl = NULL; + } +#endif +} + +void h264_stream_parser::reset() +{ + curr_32_bit = 0; + bits_read = 0; + zero_cntr = 0; + emulation_code_skip_cntr = 0; + emulation_sc_enabled = true; + bitstream = NULL; + bitstream_bytes = 0; + memset(&vui_param, 0, sizeof(vui_param)); + vui_param.fixed_fps_prev_ts = LLONG_MAX; + memset(&sei_buf_period, 0, sizeof(sei_buf_period)); + memset(&sei_pic_timing, 0, sizeof(sei_pic_timing)); + memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement)); + frame_packing_arrangement.cancel_flag = 1; + mbaff_flag = 0; +} + +void h264_stream_parser::init_bitstream(OMX_U8* data, OMX_U32 size) +{ + bitstream = data; + bitstream_bytes = size; + curr_32_bit = 0; + bits_read = 0; + zero_cntr = 0; + emulation_code_skip_cntr = 0; +} + +void h264_stream_parser::parse_vui(bool vui_in_extradata) +{ + OMX_U32 value = 0; + ALOGV("parse_vui: IN"); + if (vui_in_extradata) + while (!extract_bits(1) && more_bits()); // Discard VUI enable flag + if (!more_bits()) + return; + + vui_param.aspect_ratio_info_present_flag = extract_bits(1); //aspect_ratio_info_present_flag + if (vui_param.aspect_ratio_info_present_flag) + { + ALOGV("Aspect Ratio Info present!"); + aspect_ratio_info(); + } + + if (extract_bits(1)) //overscan_info_present_flag + extract_bits(1); //overscan_appropriate_flag + if (extract_bits(1)) //video_signal_type_present_flag + { + extract_bits(3); //video_format + extract_bits(1); //video_full_range_flag + if (extract_bits(1)) //colour_description_present_flag + { + extract_bits(8); //colour_primaries + extract_bits(8); //transfer_characteristics + extract_bits(8); //matrix_coefficients + } + } + if (extract_bits(1)) //chroma_location_info_present_flag + { + uev(); //chroma_sample_loc_type_top_field + uev(); //chroma_sample_loc_type_bottom_field + } + vui_param.timing_info_present_flag = extract_bits(1); + if (vui_param.timing_info_present_flag) + { + vui_param.num_units_in_tick = extract_bits(32); + vui_param.time_scale = extract_bits(32); + vui_param.fixed_frame_rate_flag = extract_bits(1); + ALOGV("Timing info present in VUI!"); + ALOGV(" num units in tick : %u", vui_param.num_units_in_tick); + ALOGV(" time scale : %u", vui_param.time_scale); + ALOGV(" fixed frame rate : %u", vui_param.fixed_frame_rate_flag); + } + vui_param.nal_hrd_parameters_present_flag = extract_bits(1); + if (vui_param.nal_hrd_parameters_present_flag) + { + ALOGV("nal hrd params present!"); + hrd_parameters(&vui_param.nal_hrd_parameters); + } + vui_param.vcl_hrd_parameters_present_flag = extract_bits(1); + if (vui_param.vcl_hrd_parameters_present_flag) + { + ALOGV("vcl hrd params present!"); + hrd_parameters(&vui_param.vcl_hrd_parameters); + } + if (vui_param.nal_hrd_parameters_present_flag || + vui_param.vcl_hrd_parameters_present_flag) + vui_param.low_delay_hrd_flag = extract_bits(1); + vui_param.pic_struct_present_flag = extract_bits(1); + ALOGV("pic_struct_present_flag : %u", vui_param.pic_struct_present_flag); + if (extract_bits(1)) //bitstream_restriction_flag + { + extract_bits(1); //motion_vectors_over_pic_boundaries_flag + uev(); //max_bytes_per_pic_denom + uev(); //max_bits_per_mb_denom + uev(); //log2_max_mv_length_vertical + uev(); //log2_max_mv_length_horizontal + uev(); //num_reorder_frames + uev(); //max_dec_frame_buffering + } + ALOGV("parse_vui: OUT"); +} + +void h264_stream_parser::aspect_ratio_info() +{ + ALOGV("aspect_ratio_info: IN"); + OMX_U32 aspect_ratio_idc = 0; + OMX_U32 aspect_ratio_x = 0; + OMX_U32 aspect_ratio_y = 0; + aspect_ratio_idc = extract_bits(8); //aspect_ratio_idc + switch (aspect_ratio_idc) + { + case 1: + aspect_ratio_x = 1; + aspect_ratio_y = 1; + break; + case 2: + aspect_ratio_x = 12; + aspect_ratio_y = 11; + break; + case 3: + aspect_ratio_x = 10; + aspect_ratio_y = 11; + break; + case 4: + aspect_ratio_x = 16; + aspect_ratio_y = 11; + break; + case 5: + aspect_ratio_x = 40; + aspect_ratio_y = 33; + break; + case 6: + aspect_ratio_x = 24; + aspect_ratio_y = 11; + break; + case 7: + aspect_ratio_x = 20; + aspect_ratio_y = 11; + break; + case 8: + aspect_ratio_x = 32; + aspect_ratio_y = 11; + break; + case 9: + aspect_ratio_x = 80; + aspect_ratio_y = 33; + break; + case 10: + aspect_ratio_x = 18; + aspect_ratio_y = 11; + break; + case 11: + aspect_ratio_x = 15; + aspect_ratio_y = 11; + break; + case 12: + aspect_ratio_x = 64; + aspect_ratio_y = 33; + break; + case 13: + aspect_ratio_x = 160; + aspect_ratio_y = 99; + break; + case 14: + aspect_ratio_x = 4; + aspect_ratio_y = 3; + break; + case 15: + aspect_ratio_x = 3; + aspect_ratio_y = 2; + break; + case 16: + aspect_ratio_x = 2; + aspect_ratio_y = 1; + break; + case 255: + aspect_ratio_x = extract_bits(16); //sar_width + aspect_ratio_y = extract_bits(16); //sar_height + break; + default: + ALOGV("-->aspect_ratio_idc: Reserved Value "); + break; + } + ALOGV("-->aspect_ratio_idc : %u", aspect_ratio_idc); + ALOGV("-->aspect_ratio_x : %u", aspect_ratio_x); + ALOGV("-->aspect_ratio_y : %u", aspect_ratio_y); + vui_param.aspect_ratio_info.aspect_ratio_idc = aspect_ratio_idc; + vui_param.aspect_ratio_info.aspect_ratio_x = aspect_ratio_x; + vui_param.aspect_ratio_info.aspect_ratio_y = aspect_ratio_y; + ALOGV("aspect_ratio_info: OUT"); +} + +void h264_stream_parser::hrd_parameters(h264_hrd_param *hrd_param) +{ + OMX_U32 idx; + ALOGV("hrd_parameters: IN"); + hrd_param->cpb_cnt = uev() + 1; + hrd_param->bit_rate_scale = extract_bits(4); + hrd_param->cpb_size_scale = extract_bits(4); + ALOGV("-->cpb_cnt : %u", hrd_param->cpb_cnt); + ALOGV("-->bit_rate_scale : %u", hrd_param->bit_rate_scale); + ALOGV("-->cpb_size_scale : %u", hrd_param->cpb_size_scale); + if (hrd_param->cpb_cnt > MAX_CPB_COUNT) + { + ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt); + return; + } + for (idx = 0; idx < hrd_param->cpb_cnt && more_bits(); idx++) + { + hrd_param->bit_rate_value[idx] = uev() + 1; + hrd_param->cpb_size_value[idx] = uev() + 1; + hrd_param->cbr_flag[idx] = extract_bits(1); + ALOGV("-->bit_rate_value [%d] : %u", idx, hrd_param->bit_rate_value[idx]); + ALOGV("-->cpb_size_value [%d] : %u", idx, hrd_param->cpb_size_value[idx]); + ALOGV("-->cbr_flag [%d] : %u", idx, hrd_param->cbr_flag[idx]); + } + hrd_param->initial_cpb_removal_delay_length = extract_bits(5) + 1; + hrd_param->cpb_removal_delay_length = extract_bits(5) + 1; + hrd_param->dpb_output_delay_length = extract_bits(5) + 1; + hrd_param->time_offset_length = extract_bits(5); + ALOGV("-->initial_cpb_removal_delay_length : %u", hrd_param->initial_cpb_removal_delay_length); + ALOGV("-->cpb_removal_delay_length : %u", hrd_param->cpb_removal_delay_length); + ALOGV("-->dpb_output_delay_length : %u", hrd_param->dpb_output_delay_length); + ALOGV("-->time_offset_length : %u", hrd_param->time_offset_length); + ALOGV("hrd_parameters: OUT"); +} + +void h264_stream_parser::parse_sei() +{ + OMX_U32 value = 0, processed_bytes = 0; + OMX_U8 *sei_msg_start = bitstream; + OMX_U32 sei_unit_size = bitstream_bytes; + ALOGV("@@parse_sei: IN sei_unit_size(%u)", sei_unit_size); + while ((processed_bytes + 2) < sei_unit_size && more_bits()) + { + init_bitstream(sei_msg_start + processed_bytes, sei_unit_size - processed_bytes); + ALOGV("-->NALU_TYPE_SEI"); + OMX_U32 payload_type = 0, payload_size = 0, aux = 0; + do { + value = extract_bits(8); + payload_type += value; + processed_bytes++; + } while (value == 0xFF); + ALOGV("-->payload_type : %u", payload_type); + do { + value = extract_bits(8); + payload_size += value; + processed_bytes++; + } while (value == 0xFF); + ALOGV("-->payload_size : %u", payload_size); + if (payload_size > 0) + { + switch (payload_type) + { + case BUFFERING_PERIOD: + sei_buffering_period(); + break; + case PIC_TIMING: + sei_picture_timing(); + break; + case PAN_SCAN_RECT: + sei_pan_scan(); + break; + case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT: + parse_frame_pack(); + break; + default: + ALOGV("-->SEI payload type [%u] not implemented! size[%u]", payload_type, payload_size); + } + } + processed_bytes += (payload_size + emulation_code_skip_cntr); + ALOGV("-->SEI processed_bytes[%u]", processed_bytes); + } + ALOGV("@@parse_sei: OUT"); +} + +void h264_stream_parser::sei_buffering_period() +{ + OMX_U32 idx; + OMX_U32 value = 0; + h264_hrd_param *hrd_param = NULL; + ALOGV("@@sei_buffering_period: IN"); + value = uev(); // seq_parameter_set_id + ALOGV("-->seq_parameter_set_id : %u", value); + if (value > 31) + { + ALOGV("ERROR: Invalid seq_parameter_set_id [%u]!", value); + return; + } + sei_buf_period.is_valid = false; + if (vui_param.nal_hrd_parameters_present_flag) + { + hrd_param = &vui_param.nal_hrd_parameters; + if (hrd_param->cpb_cnt > MAX_CPB_COUNT) + { + ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt); + return; + } + for (idx = 0; idx < hrd_param->cpb_cnt ; idx++) + { + sei_buf_period.is_valid = true; + sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); + sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); + ALOGV("-->initial_cpb_removal_delay : %u", sei_buf_period.initial_cpb_removal_delay[idx]); + ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]); + } + } + if (vui_param.vcl_hrd_parameters_present_flag) + { + hrd_param = &vui_param.vcl_hrd_parameters; + if (hrd_param->cpb_cnt > MAX_CPB_COUNT) + { + ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt); + return; + } + for (idx = 0; idx < hrd_param->cpb_cnt ; idx++) + { + sei_buf_period.is_valid = true; + sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); + sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); + ALOGV("-->initial_cpb_removal_delay : %u", sei_buf_period.initial_cpb_removal_delay[idx]); + ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]); + } + } + sei_buf_period.au_cntr = 0; + ALOGV("@@sei_buffering_period: OUT"); +} + +void h264_stream_parser::sei_picture_timing() +{ + ALOGV("@@sei_picture_timing: IN"); + OMX_U32 time_offset_len = 0, cpb_removal_len = 24, dpb_output_len = 24; + OMX_U8 cbr_flag = 0; + sei_pic_timing.is_valid = true; + if (vui_param.nal_hrd_parameters_present_flag) + { + cpb_removal_len = vui_param.nal_hrd_parameters.cpb_removal_delay_length; + dpb_output_len = vui_param.nal_hrd_parameters.dpb_output_delay_length; + time_offset_len = vui_param.nal_hrd_parameters.time_offset_length; + cbr_flag = vui_param.nal_hrd_parameters.cbr_flag[0]; + } + else if (vui_param.vcl_hrd_parameters_present_flag) + { + cpb_removal_len = vui_param.vcl_hrd_parameters.cpb_removal_delay_length; + dpb_output_len = vui_param.vcl_hrd_parameters.dpb_output_delay_length; + time_offset_len = vui_param.vcl_hrd_parameters.time_offset_length; + cbr_flag = vui_param.vcl_hrd_parameters.cbr_flag[0]; + } + sei_pic_timing.cpb_removal_delay = extract_bits(cpb_removal_len); + sei_pic_timing.dpb_output_delay = extract_bits(dpb_output_len); + ALOGV("-->cpb_removal_len : %u", cpb_removal_len); + ALOGV("-->dpb_output_len : %u", dpb_output_len); + ALOGV("-->cpb_removal_delay : %u", sei_pic_timing.cpb_removal_delay); + ALOGV("-->dpb_output_delay : %u", sei_pic_timing.dpb_output_delay); + if (vui_param.pic_struct_present_flag) + { + sei_pic_timing.pic_struct = extract_bits(4); + sei_pic_timing.num_clock_ts = 0; + switch (sei_pic_timing.pic_struct) + { + case 0: case 1: case 2: sei_pic_timing.num_clock_ts = 1; break; + case 3: case 4: case 7: sei_pic_timing.num_clock_ts = 2; break; + case 5: case 6: case 8: sei_pic_timing.num_clock_ts = 3; break; + default: + ALOGE("sei_picture_timing: pic_struct invalid!"); + } + ALOGV("-->num_clock_ts : %u", sei_pic_timing.num_clock_ts); + for (OMX_U32 i = 0; i < sei_pic_timing.num_clock_ts && more_bits(); i++) + { + sei_pic_timing.clock_ts_flag = extract_bits(1); + if(sei_pic_timing.clock_ts_flag) + { + ALOGV("-->clock_timestamp present!"); + sei_pic_timing.ct_type = extract_bits(2); + sei_pic_timing.nuit_field_based_flag = extract_bits(1); + sei_pic_timing.counting_type = extract_bits(5); + sei_pic_timing.full_timestamp_flag = extract_bits(1); + sei_pic_timing.discontinuity_flag = extract_bits(1); + sei_pic_timing.cnt_dropped_flag = extract_bits(1); + sei_pic_timing.n_frames = extract_bits(8); + ALOGV("-->f_timestamp_flg : %u", sei_pic_timing.full_timestamp_flag); + ALOGV("-->n_frames : %u", sei_pic_timing.n_frames); + sei_pic_timing.seconds_value = 0; + sei_pic_timing.minutes_value = 0; + sei_pic_timing.hours_value = 0; + if (sei_pic_timing.full_timestamp_flag) + { + sei_pic_timing.seconds_value = extract_bits(6); + sei_pic_timing.minutes_value = extract_bits(6); + sei_pic_timing.hours_value = extract_bits(5); + } + else if (extract_bits(1)) + { + ALOGV("-->seconds_flag enabled!"); + sei_pic_timing.seconds_value = extract_bits(6); + if (extract_bits(1)) + { + ALOGV("-->minutes_flag enabled!"); + sei_pic_timing.minutes_value = extract_bits(6); + if (extract_bits(1)) + { + ALOGV("-->hours_flag enabled!"); + sei_pic_timing.hours_value = extract_bits(5); + } + } + } + sei_pic_timing.time_offset = 0; + if (time_offset_len > 0) + sei_pic_timing.time_offset = iv(time_offset_len); + ALOGV("-->seconds_value : %u", sei_pic_timing.seconds_value); + ALOGV("-->minutes_value : %u", sei_pic_timing.minutes_value); + ALOGV("-->hours_value : %u", sei_pic_timing.hours_value); + ALOGV("-->time_offset : %d", sei_pic_timing.time_offset); + } + } + } + ALOGV("@@sei_picture_timing: OUT"); +} + +void h264_stream_parser::sei_pan_scan() +{ +#ifdef _ANDROID_ + char property_value[PROPERTY_VALUE_MAX] = {0}; + OMX_S32 enable_panscan_log = 0; + property_get("vidc.dec.debug.panframedata", property_value, "0"); + enable_panscan_log = atoi(property_value); +#endif +#ifdef PANSCAN_HDLR + h264_pan_scan *pan_scan_param = panscan_hdl->get_free(); +#else + h264_pan_scan *pan_scan_param = &panscan_param; +#endif + + if (!pan_scan_param) + { + ALOGE("sei_pan_scan: ERROR: Invalid pointer!"); + return; + } + + pan_scan_param->rect_id = uev(); + if (pan_scan_param->rect_id > 0xFF) + { + ALOGE("sei_pan_scan: ERROR: Invalid rect_id[%lu]!", pan_scan_param->rect_id); + pan_scan_param->rect_id = NO_PAN_SCAN_BIT; + return; + } + + pan_scan_param->rect_cancel_flag = extract_bits(1); + + if (pan_scan_param->rect_cancel_flag) + pan_scan_param->rect_id = NO_PAN_SCAN_BIT; + else + { + pan_scan_param->cnt = uev() + 1; + if (pan_scan_param->cnt > MAX_PAN_SCAN_RECT) + { + ALOGE("sei_pan_scan: ERROR: Invalid num of rect [%lu]!", pan_scan_param->cnt); + pan_scan_param->rect_id = NO_PAN_SCAN_BIT; + return; + } + + for (OMX_U32 i = 0; i < pan_scan_param->cnt; i++) + { + pan_scan_param->rect_left_offset[i] = sev(); + pan_scan_param->rect_right_offset[i] = sev(); + pan_scan_param->rect_top_offset[i] = sev(); + pan_scan_param->rect_bottom_offset[i] = sev(); + + } + pan_scan_param->rect_repetition_period = uev(); +#ifdef PANSCAN_HDLR + if (pan_scan_param->rect_repetition_period > 1) + // Repetition period is decreased by 2 each time panscan data is used + pan_scan_param->rect_repetition_period *= 2; +#endif +#ifdef _ANDROID_ + if (enable_panscan_log) + { + print_pan_data(pan_scan_param); + } +#endif + } +} + +void h264_stream_parser::print_pan_data(h264_pan_scan *pan_scan_param) +{ + ALOGE("@@print_pan_data: IN"); + + ALOGE("-->rect_id : %lu", pan_scan_param->rect_id); + ALOGE("-->rect_cancel_flag : %u", pan_scan_param->rect_cancel_flag); + + ALOGE("-->cnt : %lu", pan_scan_param->cnt); + + for (OMX_U32 i = 0; i < pan_scan_param->cnt; i++) + { + ALOGE("-->rect_left_offset : %ld", pan_scan_param->rect_left_offset[i]); + ALOGE("-->rect_right_offset : %ld", pan_scan_param->rect_right_offset[i]); + ALOGE("-->rect_top_offset : %ld", pan_scan_param->rect_top_offset[i]); + ALOGE("-->rect_bottom_offset : %ld", pan_scan_param->rect_bottom_offset[i]); + } + ALOGE("-->repetition_period : %lu", pan_scan_param->rect_repetition_period); + + ALOGE("@@print_pan_data: OUT"); +} + +void h264_stream_parser::parse_sps() +{ + OMX_U32 value = 0, scaling_matrix_limit; + ALOGV("@@parse_sps: IN"); + value = extract_bits(8); //profile_idc + extract_bits(8); //constraint flags and reserved bits + extract_bits(8); //level_idc + uev(); //sps id + if (value == 100 || value == 110 || value == 122 || value == 244 || + value == 44 || value == 83 || value == 86 || value == 118) + { + if (uev() == 3) //chroma_format_idc + { + extract_bits(1); //separate_colour_plane_flag + scaling_matrix_limit = 12; + } + else + scaling_matrix_limit = 12; + uev(); //bit_depth_luma_minus8 + uev(); //bit_depth_chroma_minus8 + extract_bits(1); //qpprime_y_zero_transform_bypass_flag + if (extract_bits(1)) { //seq_scaling_matrix_present_flag + for (unsigned int i = 0; i < scaling_matrix_limit && more_bits(); i++) + { + if (extract_bits(1)) { ////seq_scaling_list_present_flag[ i ] + if (i < 6) + scaling_list(16); + else + scaling_list(64); + } + } + } + } + uev(); //log2_max_frame_num_minus4 + value = uev(); //pic_order_cnt_type + if (value == 0) + uev(); //log2_max_pic_order_cnt_lsb_minus4 + else if (value == 1) + { + extract_bits(1); //delta_pic_order_always_zero_flag + sev(); //offset_for_non_ref_pic + sev(); //offset_for_top_to_bottom_field + value = uev(); // num_ref_frames_in_pic_order_cnt_cycle + for (unsigned int i = 0; i < value; i++) + sev(); //offset_for_ref_frame[ i ] + } + uev(); //max_num_ref_frames + extract_bits(1); //gaps_in_frame_num_value_allowed_flag + value = uev(); //pic_width_in_mbs_minus1 + value = uev(); //pic_height_in_map_units_minus1 + if (!extract_bits(1)) //frame_mbs_only_flag + mbaff_flag = extract_bits(1); //mb_adaptive_frame_field_flag + extract_bits(1); //direct_8x8_inference_flag + if (extract_bits(1)) //frame_cropping_flag + { + uev(); //frame_crop_left_offset + uev(); //frame_crop_right_offset + uev(); //frame_crop_top_offset + uev(); //frame_crop_bottom_offset + } + if (extract_bits(1)) //vui_parameters_present_flag + parse_vui(false); + ALOGV("@@parse_sps: OUT"); +} + +void h264_stream_parser::scaling_list(OMX_U32 size_of_scaling_list) +{ + OMX_S32 last_scale = 8, next_scale = 8, delta_scale; + for (unsigned int j = 0; j < size_of_scaling_list; j++) + { + if (next_scale != 0) + { + delta_scale = sev(); + next_scale = (last_scale + delta_scale + 256) % 256; + } + last_scale = (next_scale == 0)? last_scale : next_scale; + } +} + +OMX_U32 h264_stream_parser::extract_bits(OMX_U32 n) +{ + OMX_U32 value = 0; + if (n > 32) + { + ALOGE("ERROR: extract_bits limit to 32 bits!"); + return value; + } + value = curr_32_bit >> (32 - n); + if (bits_read < n) + { + n -= bits_read; + read_word(); + value |= (curr_32_bit >> (32 - n)); + if (bits_read < n) + { + ALOGV("ERROR: extract_bits underflow!"); + value >>= (n - bits_read); + n = bits_read; + } + } + bits_read -= n; + curr_32_bit <<= n; + return value; +} + +void h264_stream_parser::read_word() +{ + curr_32_bit = 0; + bits_read = 0; + while (bitstream_bytes && bits_read < 32) + { + if (*bitstream == EMULATION_PREVENTION_THREE_BYTE && + zero_cntr >= 2 && emulation_sc_enabled) + { + ALOGV("EMULATION_PREVENTION_THREE_BYTE: Skip 0x03 byte aligned!"); + emulation_code_skip_cntr++; + } + else + { + curr_32_bit <<= 8; + curr_32_bit |= *bitstream; + bits_read += 8; + } + if (*bitstream == 0) + zero_cntr++; + else + zero_cntr = 0; + bitstream++; + bitstream_bytes--; + } + curr_32_bit <<= (32 - bits_read); +} + +OMX_U32 h264_stream_parser::uev() +{ + OMX_U32 lead_zero_bits = 0, code_num = 0; + while(!extract_bits(1) && more_bits()) + lead_zero_bits++; + code_num = lead_zero_bits == 0 ? 0 : + (1 << lead_zero_bits) - 1 + extract_bits(lead_zero_bits); + return code_num; +} + +bool h264_stream_parser::more_bits() +{ + return (bitstream_bytes > 0 || bits_read > 0); +} + +OMX_S32 h264_stream_parser::sev() +{ + OMX_U32 code_num = uev(); + OMX_S32 ret; + ret = (code_num + 1) >> 1; + return ((code_num & 1) ? ret : -ret); +} + +OMX_S32 h264_stream_parser::iv(OMX_U32 n_bits) +{ + OMX_U32 code_num = extract_bits(n_bits); + OMX_S32 ret = (code_num >> (n_bits - 1))? (-1)*(~(code_num & ~(0x1 << (n_bits - 1))) + 1) : code_num; + return ret; +} + +OMX_U32 h264_stream_parser::get_nal_unit_type(OMX_U32 *nal_unit_type) +{ + OMX_U32 value = 0, consumed_bytes = 3; + *nal_unit_type = NALU_TYPE_UNSPECIFIED; + ALOGV("-->get_nal_unit_type: IN"); + value = extract_bits(24); + while (value != 0x00000001 && more_bits()) + { + value <<= 8; + value |= extract_bits(8); + consumed_bytes++; + } + if (value != 0x00000001) + { + ALOGE("ERROR in get_nal_unit_type: Start code not found!"); + } + else + { + if (extract_bits(1)) // forbidden_zero_bit + { + ALOGE("WARNING: forbidden_zero_bit should be zero!"); + } + value = extract_bits(2); + ALOGV("-->nal_ref_idc : %x", value); + *nal_unit_type = extract_bits(5); + ALOGV("-->nal_unit_type : %x", *nal_unit_type); + consumed_bytes++; + if (consumed_bytes > 5) + { + ALOGE("-->WARNING: Startcode was found after the first 4 bytes!"); + } + } + ALOGV("-->get_nal_unit_type: OUT"); + return consumed_bytes; +} + +OMX_S64 h264_stream_parser::calculate_buf_period_ts(OMX_S64 timestamp) +{ + OMX_S64 clock_ts = timestamp; + ALOGV("calculate_ts(): IN"); + if (sei_buf_period.au_cntr == 0) + clock_ts = sei_buf_period.reference_ts = timestamp; + else if (sei_pic_timing.is_valid && VALID_TS(sei_buf_period.reference_ts)) + { + clock_ts = sei_buf_period.reference_ts + sei_pic_timing.cpb_removal_delay * + 1e6 * vui_param.num_units_in_tick / vui_param.time_scale; + } + sei_buf_period.au_cntr++; + ALOGV("calculate_ts(): OUT"); + return clock_ts; +} + +OMX_S64 h264_stream_parser::calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor) +{ + if (VALID_TS(timestamp)) + vui_param.fixed_fps_prev_ts = timestamp; + else if (VALID_TS(vui_param.fixed_fps_prev_ts)) + vui_param.fixed_fps_prev_ts += DeltaTfiDivisor * 1e6 * + vui_param.num_units_in_tick / vui_param.time_scale; + return vui_param.fixed_fps_prev_ts; +} + +void h264_stream_parser::parse_frame_pack() +{ +#ifdef _ANDROID_ + char property_value[PROPERTY_VALUE_MAX] = {0}; + OMX_S32 enable_framepack_log = 0; + + property_get("vidc.dec.debug.panframedata", property_value, "0"); + enable_framepack_log = atoi(property_value); +#endif + ALOGV("\n%s:%d parse_frame_pack", __func__, __LINE__); + + frame_packing_arrangement.id = uev(); + + frame_packing_arrangement.cancel_flag = extract_bits(1); + if(!frame_packing_arrangement.cancel_flag) { + frame_packing_arrangement.type = extract_bits(7); + frame_packing_arrangement.quincunx_sampling_flag = extract_bits(1); + frame_packing_arrangement.content_interpretation_type = extract_bits(6); + frame_packing_arrangement.spatial_flipping_flag = extract_bits(1); + frame_packing_arrangement.frame0_flipped_flag = extract_bits(1); + frame_packing_arrangement.field_views_flag = extract_bits(1); + frame_packing_arrangement.current_frame_is_frame0_flag = extract_bits(1); + frame_packing_arrangement.frame0_self_contained_flag = extract_bits(1); + frame_packing_arrangement.frame1_self_contained_flag = extract_bits(1); + + if(!frame_packing_arrangement.quincunx_sampling_flag && + frame_packing_arrangement.type != 5) { + frame_packing_arrangement.frame0_grid_position_x = extract_bits(4); + frame_packing_arrangement.frame0_grid_position_y = extract_bits(4); + frame_packing_arrangement.frame1_grid_position_x = extract_bits(4); + frame_packing_arrangement.frame1_grid_position_y = extract_bits(4); + } + frame_packing_arrangement.reserved_byte = extract_bits(8); + frame_packing_arrangement.repetition_period = uev(); + } + frame_packing_arrangement.extension_flag = extract_bits(1); + +#ifdef _ANDROID_ + if (enable_framepack_log) + { + print_frame_pack(); + } +#endif +} + +void h264_stream_parser::print_frame_pack() +{ + ALOGV("\n ## frame_packing_arrangement.id = %u", frame_packing_arrangement.id); + ALOGV("\n ## frame_packing_arrangement.cancel_flag = %u", + frame_packing_arrangement.cancel_flag); + if(!frame_packing_arrangement.cancel_flag) + { + ALOGV("\n ## frame_packing_arrangement.type = %u", + frame_packing_arrangement.type); + ALOGV("\n ## frame_packing_arrangement.quincunx_sampling_flag = %u", + frame_packing_arrangement.quincunx_sampling_flag); + ALOGV("\n ## frame_packing_arrangement.content_interpretation_type = %u", + frame_packing_arrangement.content_interpretation_type); + ALOGV("\n ## frame_packing_arrangement.spatial_flipping_flag = %u", + frame_packing_arrangement.spatial_flipping_flag); + ALOGV("\n ## frame_packing_arrangement.frame0_flipped_flag = %u", + frame_packing_arrangement.frame0_flipped_flag); + ALOGV("\n ## frame_packing_arrangement.field_views_flag = %u", + frame_packing_arrangement.field_views_flag); + ALOGV("\n ## frame_packing_arrangement.current_frame_is_frame0_flag = %u", + frame_packing_arrangement.current_frame_is_frame0_flag); + ALOGV("\n ## frame_packing_arrangement.frame0_self_contained_flag = %u", + frame_packing_arrangement.frame0_self_contained_flag); + ALOGV("\n ## frame_packing_arrangement.frame1_self_contained_flag = %u", + frame_packing_arrangement.frame1_self_contained_flag); + ALOGV("\n ## frame_packing_arrangement.reserved_byte = %u", + frame_packing_arrangement.reserved_byte); + ALOGV("\n ## frame_packing_arrangement.repetition_period = %u", + frame_packing_arrangement.repetition_period); + ALOGV("\n ## frame_packing_arrangement.extension_flag = %u", + frame_packing_arrangement.extension_flag); + } +} +/* API'S EXPOSED TO OMX COMPONENT */ + +void h264_stream_parser::get_frame_pack_data( + OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack) +{ + ALOGV("\n%s:%d get frame data", __func__, __LINE__); + memcpy(&frame_pack->id,&frame_packing_arrangement.id, + FRAME_PACK_SIZE*sizeof(OMX_U32)); + return; +} + + +bool h264_stream_parser::is_mbaff() +{ + ALOGV("\n%s:%d MBAFF flag=%d", __func__, __LINE__,mbaff_flag); + return mbaff_flag; +} + +void h264_stream_parser::get_frame_rate(OMX_U32 *frame_rate) +{ + if (vui_param.num_units_in_tick != 0) + *frame_rate = vui_param.time_scale / (2 * vui_param.num_units_in_tick); +} + +void h264_stream_parser::parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, OMX_U32 nal_type, bool enable_emu_sc) +{ + OMX_U32 nal_unit_type = NALU_TYPE_UNSPECIFIED, cons_bytes = 0; + ALOGV("parse_nal(): IN nal_type(%lu)", nal_type); + if (!data_len) + return; + init_bitstream(data_ptr, data_len); + emulation_sc_enabled = enable_emu_sc; + if (nal_type != NALU_TYPE_VUI) + { + cons_bytes = get_nal_unit_type(&nal_unit_type); + if (nal_type != nal_unit_type && nal_type != NALU_TYPE_UNSPECIFIED) + { + ALOGV("Unexpected nal_type(%x) expected(%x)", nal_unit_type, nal_type); + return; + } + } + switch (nal_type) + { + case NALU_TYPE_SPS: + if (more_bits()) + parse_sps(); +#ifdef PANSCAN_HDLR + panscan_hdl->get_free(); +#endif + break; + case NALU_TYPE_SEI: + init_bitstream(data_ptr + cons_bytes, data_len - cons_bytes); + parse_sei(); + break; + case NALU_TYPE_VUI: + parse_vui(true); + break; + default: + ALOGV("nal_unit_type received : %lu", nal_type); + } + ALOGV("parse_nal(): OUT"); +} + +#ifdef PANSCAN_HDLR +void h264_stream_parser::update_panscan_data(OMX_S64 timestamp) +{ + panscan_hdl->update_last(timestamp); +} +#endif + +void h264_stream_parser::fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio) +{ + if(dest_aspect_ratio && vui_param.aspect_ratio_info_present_flag) + { + dest_aspect_ratio->aspectRatioX = vui_param.aspect_ratio_info.aspect_ratio_x; + dest_aspect_ratio->aspectRatioY = vui_param.aspect_ratio_info.aspect_ratio_y; + } +} + +void h264_stream_parser::fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp) +{ +#ifdef PANSCAN_HDLR + h264_pan_scan *pan_scan_param = panscan_hdl->get_populated(timestamp); +#else + h264_pan_scan *pan_scan_param = &panscan_param; +#endif + if (pan_scan_param) { + if (!(pan_scan_param->rect_id & NO_PAN_SCAN_BIT)) + { + PRINT_PANSCAN_PARAM(*pan_scan_param); + dest_pan_scan->numWindows = pan_scan_param->cnt; + for (unsigned int i = 0; i < dest_pan_scan->numWindows; i++) + { + dest_pan_scan->window[i].x = pan_scan_param->rect_left_offset[i]; + dest_pan_scan->window[i].y = pan_scan_param->rect_top_offset[i]; + dest_pan_scan->window[i].dx = pan_scan_param->rect_right_offset[i]; + dest_pan_scan->window[i].dy = pan_scan_param->rect_bottom_offset[i]; + } +#ifndef PANSCAN_HDLR + if (pan_scan_param->rect_repetition_period == 0) + pan_scan_param->rect_id = NO_PAN_SCAN_BIT; + else if (pan_scan_param->rect_repetition_period > 1) + pan_scan_param->rect_repetition_period = + (pan_scan_param->rect_repetition_period == 2)? 0 : + (pan_scan_param->rect_repetition_period - 1); +#endif + } + else + pan_scan_param->rect_repetition_period = 0; + } +} + +OMX_S64 h264_stream_parser::process_ts_with_sei_vui(OMX_S64 timestamp) +{ + bool clock_ts_flag = false; + OMX_S64 clock_ts = timestamp; + OMX_U32 deltaTfiDivisor = 2; + if (vui_param.timing_info_present_flag) + { + if (vui_param.pic_struct_present_flag) + { + if(sei_pic_timing.clock_ts_flag) + { + clock_ts = ((sei_pic_timing.hours_value * 60 + sei_pic_timing.minutes_value) * 60 + sei_pic_timing.seconds_value) * 1e6 + + (sei_pic_timing.n_frames * (vui_param.num_units_in_tick * (1 + sei_pic_timing.nuit_field_based_flag)) + sei_pic_timing.time_offset) * + 1e6 / vui_param.time_scale; + ALOGV("-->CLOCK TIMESTAMP : %lld", clock_ts); + clock_ts_flag = true; + } + if (vui_param.fixed_frame_rate_flag) + { + switch (sei_pic_timing.pic_struct) + { + case 1: case 2: deltaTfiDivisor = 1; break; + case 0: case 3: case 4: deltaTfiDivisor = 2; break; + case 5: case 6: deltaTfiDivisor = 3; break; + case 7: deltaTfiDivisor = 4; break; + case 8: deltaTfiDivisor = 6; break; + default: + ALOGE("process_ts_with_sei_vui: pic_struct invalid!"); + } + } + } + if (!clock_ts_flag) + { + if (vui_param.fixed_frame_rate_flag) + clock_ts = calculate_fixed_fps_ts(timestamp, deltaTfiDivisor); + else if (sei_buf_period.is_valid) + clock_ts = calculate_buf_period_ts(timestamp); + } + } + else + { + ALOGV("NO TIMING information present in VUI!"); + } + sei_pic_timing.is_valid = false; // SEI data is valid only for current frame + return clock_ts; +} + +#ifdef PANSCAN_HDLR + +panscan_handler::panscan_handler() : panscan_data(NULL) {} + +panscan_handler::~panscan_handler() +{ + if (panscan_data) + { + free(panscan_data); + panscan_data = NULL; + } +} + +bool panscan_handler::initialize(int num_data) +{ + bool ret = false; + if (!panscan_data) + { + panscan_data = (PANSCAN_NODE *) malloc (sizeof(PANSCAN_NODE) * num_data); + if (panscan_data) + { + panscan_free.add_multiple(panscan_data, num_data); + ret = true; + } + } + else + { + ALOGE("ERROR: Old panscan memory must be freed to allocate new"); + } + return ret; +} + +h264_pan_scan *panscan_handler::get_free() +{ + h264_pan_scan *data = NULL; + PANSCAN_NODE *panscan_node = panscan_used.watch_last(); + panscan_node = (!panscan_node || VALID_TS(panscan_node->start_ts))? + panscan_free.remove_first() : + panscan_used.remove_last(); + if (panscan_node) + { + panscan_node->start_ts = LLONG_MAX; + panscan_node->end_ts = LLONG_MAX; + panscan_node->pan_scan_param.rect_id = NO_PAN_SCAN_BIT; + panscan_node->active = false; + panscan_used.add_last(panscan_node); + data = &panscan_node->pan_scan_param; + } + return data; +} + +h264_pan_scan *panscan_handler::get_populated(OMX_S64 frame_ts) +{ + h264_pan_scan *data = NULL; + PANSCAN_NODE *panscan_node = panscan_used.watch_first(); + while (panscan_node && !data) + { + if (VALID_TS(panscan_node->start_ts)) + { + if (panscan_node->active && frame_ts < panscan_node->start_ts) + panscan_node->start_ts = frame_ts; + if (frame_ts >= panscan_node->start_ts) + if (frame_ts < panscan_node->end_ts) + { + data = &panscan_node->pan_scan_param; + panscan_node->active = true; + } + else + { + panscan_free.add_last(panscan_used.remove_first()); + panscan_node = panscan_used.watch_first(); + } + else + // Finish search if current timestamp has not reached + // start timestamp of first panscan data. + panscan_node = NULL; + } + else + { + // Only one panscan data is stored for clips + // with invalid timestamps in every frame + data = &panscan_node->pan_scan_param; + panscan_node->active = true; + } + } + if (data) { + if (data->rect_repetition_period == 0) + panscan_free.add_last(panscan_used.remove_first()); + else if (data->rect_repetition_period > 1) + data->rect_repetition_period -= 2; + } + PRINT_PANSCAN_DATA(panscan_node); + return data; +} + +void panscan_handler::update_last(OMX_S64 frame_ts) +{ + PANSCAN_NODE *panscan_node = panscan_used.watch_last(); + if (panscan_node && !VALID_TS(panscan_node->start_ts)) + { + panscan_node->start_ts = frame_ts; + PRINT_PANSCAN_DATA(panscan_node); + if (panscan_node->prev) + { + if (frame_ts < panscan_node->prev->end_ts) + panscan_node->prev->end_ts = frame_ts; + else if (!VALID_TS(frame_ts)) + panscan_node->prev->pan_scan_param.rect_repetition_period = 0; + PRINT_PANSCAN_DATA(panscan_node->prev); + } + } +} + +template +void omx_dl_list::add_multiple(NODE_STRUCT *data_arr, int data_num) +{ + for (int idx = 0; idx < data_num; idx++) + add_last(&data_arr[idx]); +} + +template +NODE_STRUCT *omx_dl_list::remove_first() +{ + NODE_STRUCT *data = head; + if (head) + { + if (head->next) + { + head = head->next; + head->prev = NULL; + } + else + head = tail = NULL; + data->next = data->prev = NULL; + } + return data; +} + +template +NODE_STRUCT *omx_dl_list::remove_last() +{ + NODE_STRUCT *data = tail; + if (tail) + { + if (tail->prev) + { + tail = tail->prev; + tail->next = NULL; + } + else + head = tail = NULL; + data->next = data->prev = NULL; + } + return data; +} + +template +void omx_dl_list::add_last(NODE_STRUCT* data_ptr) +{ + if (data_ptr) + { + data_ptr->next = NULL; + data_ptr->prev = tail; + if (tail) + { + tail->next = data_ptr; + tail = data_ptr; + } + else + head = tail = data_ptr; + } +} + +template +NODE_STRUCT* omx_dl_list::watch_first() +{ + return head; +} + +template +NODE_STRUCT* omx_dl_list::watch_last() +{ + return tail; +} + +#endif diff --git a/mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp b/mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp new file mode 100644 index 00000000..a283f0ed --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp @@ -0,0 +1,228 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +/*======================================================================== + + O p e n M M + V i d e o U t i l i t i e s + +*//** @file VideoUtils.cpp + This module contains utilities and helper routines. + +@par EXTERNALIZED FUNCTIONS + +@par INITIALIZATION AND SEQUENCING REQUIREMENTS + (none) + +*//*====================================================================== */ + +/* ======================================================================= + + INCLUDE FILES FOR MODULE + +========================================================================== */ +#include "hevc_utils.h" +#include +#include +#include +#include +#ifdef _ANDROID_ +#include +#endif + +#define DEBUG_PRINT_LOW ALOGV +#define DEBUG_PRINT_ERROR ALOGE + + +/* ======================================================================= + + DEFINITIONS AND DECLARATIONS FOR MODULE + +This section contains definitions for constants, macros, types, variables +and other items needed by this module. + +========================================================================== */ + +HEVC_Utils::HEVC_Utils() +{ + initialize_frame_checking_environment(); +} + +HEVC_Utils::~HEVC_Utils() +{ +} + +/***********************************************************************/ +/* +FUNCTION: + HEVC_Utils::initialize_frame_checking_environment + +DESCRIPTION: + Extract RBSP data from a NAL + +INPUT/OUTPUT PARAMETERS: + None + +RETURN VALUE: + boolean + +SIDE EFFECTS: + None. +*/ +/***********************************************************************/ +void HEVC_Utils::initialize_frame_checking_environment() +{ + m_forceToStichNextNAL = false; + m_au_data = false; + nalu_type = NAL_UNIT_INVALID; +} + +/*=========================================================================== +FUNCTION: + HEVC_Utils::iSNewFrame + +DESCRIPTION: + Returns true if NAL parsing successfull otherwise false. + +INPUT/OUTPUT PARAMETERS: + + buffer : buffer containing start code or nal length + NAL units + buffer_length : the length of the NAL buffer + start_code : If true, start code is detected, + otherwise size nal length is detected + size_of_nal_length_field: size of nal length field + + isNewFrame: true if the NAL belongs to a differenet frame + false if the NAL belongs to a current frame + +RETURN VALUE: + boolean true, if nal parsing is successful + false, if the nal parsing has errors + +SIDE EFFECTS: + None. +===========================================================================*/ +bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, + OMX_IN OMX_U32 size_of_nal_length_field, + OMX_OUT OMX_BOOL &isNewFrame) +{ + OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer; + OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen; + byte bFirstSliceInPic = 0; + + byte coef1=1, coef2=0, coef3=0; + uint32 pos = 0; + uint32 nal_len = buffer_length; + uint32 sizeofNalLengthField = 0; + uint32 zero_count; + boolean start_code = (size_of_nal_length_field==0)?true:false; + + if(start_code) { + // Search start_code_prefix_one_3bytes (0x000001) + coef2 = buffer[pos++]; + coef3 = buffer[pos++]; + do { + if(pos >= buffer_length) + { + DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + + coef1 = coef2; + coef2 = coef3; + coef3 = buffer[pos++]; + } while(coef1 || coef2 || coef3 != 1); + } + else if (size_of_nal_length_field) + { + /* This is the case to play multiple NAL units inside each access unit*/ + /* Extract the NAL length depending on sizeOfNALength field */ + sizeofNalLengthField = size_of_nal_length_field; + nal_len = 0; + while(size_of_nal_length_field--) + { + nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3); + } + if (nal_len >= buffer_length) + { + DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + } + + if (nal_len > buffer_length) + { + DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + + if(pos + 2 > (nal_len + sizeofNalLengthField)) + { + DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); + return false; + } + + nalu_type = (buffer[pos] & 0x7E)>>1 ; //=== nal_unit_type + + DEBUG_PRINT_LOW("\n@#@# Pos = %x NalType = %x buflen = %d", pos-1, nalu_type, buffer_length); + + isNewFrame = OMX_FALSE; + + if (nalu_type == NAL_UNIT_VPS || + nalu_type == NAL_UNIT_SPS || + nalu_type == NAL_UNIT_PPS || + nalu_type == NAL_UNIT_SEI) + { + DEBUG_PRINT_LOW("\n Non-AU boundary with NAL type %d", nalu_type); + if(m_au_data) + { + isNewFrame = OMX_TRUE; + m_au_data = false; + } + + m_forceToStichNextNAL = true; + } + else if (nalu_type <= NAL_UNIT_RESERVED_23) + { + DEBUG_PRINT_LOW("\n AU Boundary with NAL type %d ",nal_unit.nalu_type); + if (!m_forceToStichNextNAL) + { + bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7); + if (bFirstSliceInPic) //=== first_ctb_in_slice is only 1'b1 coded tree block + { + DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block"); + isNewFrame = OMX_TRUE; + } + } + m_au_data = true; + m_forceToStichNextNAL = false; + } + DEBUG_PRINT_LOW("get_HEVC_nal_type - newFrame value %d\n",isNewFrame); + return true; +} + diff --git a/mm-video-v4l2/vidc/vdec/src/message_queue.c b/mm-video-v4l2/vidc/vdec/src/message_queue.c new file mode 100755 index 00000000..a6b491ed --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/message_queue.c @@ -0,0 +1,178 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "message_queue.h" + +int check_if_queue_empty ( unsigned int queuetocheck, void* queuecontext ) +{ + struct video_queue_context *ptr_q = NULL; + /* + * queuetocheck - 0 command queue + * queuetocheck - 1 data queue + */ + if ( queuecontext == NULL || (queuetocheck > 1 ) ) + { + return 1; + } + ptr_q = (struct video_queue_context *)queuecontext; + + if (queuetocheck == 0) + { + if (ptr_q->read_comq == ptr_q->write_comq) + { + return 1; + } + } + else if (queuetocheck == 1) + { + if (ptr_q->write_dataq == ptr_q->read_dataq) + { + return 1; + } + } + + return 0; +} + + + +struct video_msgq * queue_get_cmd (void* queuecontext ) +{ + struct video_queue_context *ptr_q = NULL; + struct video_msgq *pitem = NULL; + + if( NULL == queuecontext ) + { + printf("\n queue_get_cmd: Invalid Input parameter\n"); + return NULL; + } + + ptr_q = (struct video_queue_context *)queuecontext; + + /* Wait on the semaphore till it is released */ + sem_wait(&ptr_q->sem_message); + + /* Lock the mutex to protect the critical section */ + pthread_mutex_lock(&ptr_q->mutex); + + if (ptr_q->read_comq != ptr_q->write_comq) + { + pitem = &ptr_q->ptr_cmdq [ptr_q->read_comq]; + ptr_q->read_comq = (ptr_q->read_comq + 1) % \ + ptr_q->commandq_size; + } + else if (ptr_q->write_dataq != ptr_q->read_dataq) + { + pitem = &ptr_q->ptr_dataq [ptr_q->read_dataq]; + ptr_q->read_dataq = (ptr_q->read_dataq + 1) % \ + ptr_q->dataq_size; + } + + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + + return pitem; +} + + +int queue_post_cmdq ( void* queuecontext, + struct video_msgq *pitem + ) +{ + struct video_queue_context *ptr_q = NULL; + + if (pitem == NULL || queuecontext == NULL) + { + return -1; + } + ptr_q = (struct video_queue_context *)queuecontext; + + /* Lock the mutex to protect the critical section */ + pthread_mutex_lock(&ptr_q->mutex); + + if ((ptr_q->write_comq + 1) % ptr_q->commandq_size == ptr_q->read_comq) + { + printf("\n QUEUE is FULL"); + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + return 0; + } + else + { + /* Store the command in the Message Queue & increment write offset */ + memcpy ( &ptr_q->ptr_cmdq [ptr_q->write_comq],pitem, \ + sizeof (struct video_msgq)); + ptr_q->write_comq = (ptr_q->write_comq + 1) % ptr_q->commandq_size; + } + + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + + /* Post the semaphore */ + sem_post(&ptr_q->sem_message); + return 1; +} + + +int queue_post_dataq ( void *queuecontext, + struct video_msgq *pitem + ) +{ + struct video_queue_context *ptr_q = NULL; + + if (pitem == NULL || queuecontext == NULL) + { + return -1; + } + ptr_q = (struct video_queue_context *)queuecontext; + + /* Lock the mutex to protect the critical section */ + pthread_mutex_lock(&ptr_q->mutex); + + if ((ptr_q->write_dataq + 1) % ptr_q->dataq_size == ptr_q->read_dataq) + { + printf("\n QUEUE is FULL"); + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + return 0; + } + else + { + /* Store the command in the Message Queue & increment write offset */ + memcpy ( &ptr_q->ptr_dataq [ptr_q->write_dataq],pitem, \ + sizeof (struct video_msgq)); + ptr_q->write_dataq = (ptr_q->write_dataq + 1) % ptr_q->dataq_size; + } + + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + + /* Post the semaphore */ + sem_post(&ptr_q->sem_message); + return 1; + +} diff --git a/mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp b/mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp new file mode 100644 index 00000000..95335d08 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp @@ -0,0 +1,302 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "mp4_utils.h" +//#include "omx_vdec.h" +# include +#ifdef _ANDROID_ + extern "C"{ + #include + } +#endif//_ANDROID_ + +#undef DEBUG_PRINT_LOW +#undef DEBUG_PRINT_HIGH +#undef DEBUG_PRINT_ERROR + +#define DEBUG_PRINT_LOW ALOGV +#define DEBUG_PRINT_HIGH ALOGV +#define DEBUG_PRINT_ERROR ALOGE + +MP4_Utils::MP4_Utils() +{ + m_SrcWidth = 0; + m_SrcHeight = 0; + vop_time_resolution = 0; + vop_time_found = false; + +} +MP4_Utils::~MP4_Utils() +{ +} + +uint32 MP4_Utils::read_bit_field(posInfoType * posPtr, uint32 size) { + uint8 *bits = &posPtr->bytePtr[0]; + uint32 bitBuf = + (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3]; + + uint32 value = (bitBuf >> (32 - posPtr->bitPos - size)) & MASK(size); + + /* Update the offset in preparation for next field */ + posPtr->bitPos += size; + + while (posPtr->bitPos >= 8) { + posPtr->bitPos -= 8; + posPtr->bytePtr++; + } + return value; +} +static uint8 *find_code + (uint8 * bytePtr, uint32 size, uint32 codeMask, uint32 referenceCode) { + uint32 code = 0xFFFFFFFF; + for (uint32 i = 0; i < size; i++) { + code <<= 8; + code |= *bytePtr++; + + if ((code & codeMask) == referenceCode) { + return bytePtr; + } + } + + DEBUG_PRINT_LOW("Unable to find code 0x%x\n", referenceCode); + return NULL; +} +bool MP4_Utils::parseHeader(mp4StreamType * psBits) { + uint32 profile_and_level_indication = 0; + uint8 VerID = 1; /* default value */ + long hxw = 0; + + m_posInfo.bitPos = 0; + m_posInfo.bytePtr = psBits->data; + m_dataBeginPtr = psBits->data; + + m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,4, + MASK(32),VOP_START_CODE); + if(m_posInfo.bytePtr) { + return false; + } + + m_posInfo.bitPos = 0; + m_posInfo.bytePtr = psBits->data; + m_dataBeginPtr = psBits->data; + m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,4, + MASK(32),GOV_START_CODE); + if(m_posInfo.bytePtr) { + return false; + } + + m_posInfo.bitPos = 0; + m_posInfo.bytePtr = psBits->data; + m_dataBeginPtr = psBits->data; + /* parsing Visual Object Seqence(VOS) header */ + m_posInfo.bytePtr = find_code(m_posInfo.bytePtr, + psBits->numBytes, + MASK(32), + VISUAL_OBJECT_SEQUENCE_START_CODE); + if ( m_posInfo.bytePtr == NULL ){ + m_posInfo.bitPos = 0; + m_posInfo.bytePtr = psBits->data; + } + else { + uint32 profile_and_level_indication = read_bit_field (&m_posInfo, 8); + } + /* parsing Visual Object(VO) header*/ + /* note: for now, we skip over the user_data */ + m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,psBits->numBytes, + MASK(32),VISUAL_OBJECT_START_CODE); + if(m_posInfo.bytePtr == NULL) { + m_posInfo.bitPos = 0; + m_posInfo.bytePtr = psBits->data; + } + else { + uint32 is_visual_object_identifier = read_bit_field (&m_posInfo, 1); + if ( is_visual_object_identifier ) { + /* visual_object_verid*/ + read_bit_field (&m_posInfo, 4); + /* visual_object_priority*/ + read_bit_field (&m_posInfo, 3); + } + + /* visual_object_type*/ + uint32 visual_object_type = read_bit_field (&m_posInfo, 4); + if ( visual_object_type != VISUAL_OBJECT_TYPE_VIDEO_ID ) { + return false; + } + /* skipping video_signal_type params*/ + /*parsing Video Object header*/ + m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,psBits->numBytes, + VIDEO_OBJECT_START_CODE_MASK,VIDEO_OBJECT_START_CODE); + if ( m_posInfo.bytePtr == NULL ) { + return false; + } + } + + /* parsing Video Object Layer(VOL) header */ + m_posInfo.bitPos = 0; + m_posInfo.bytePtr = find_code(m_posInfo.bytePtr, + psBits->numBytes, + VIDEO_OBJECT_LAYER_START_CODE_MASK, + VIDEO_OBJECT_LAYER_START_CODE); + if ( m_posInfo.bytePtr == NULL ) { + m_posInfo.bitPos = 0; + m_posInfo.bytePtr = psBits->data; + } + + // 1 -> random accessible VOL + read_bit_field(&m_posInfo, 1); + + uint32 video_object_type_indication = read_bit_field (&m_posInfo, 8); + if ( (video_object_type_indication != SIMPLE_OBJECT_TYPE) && + (video_object_type_indication != SIMPLE_SCALABLE_OBJECT_TYPE) && + (video_object_type_indication != CORE_OBJECT_TYPE) && + (video_object_type_indication != ADVANCED_SIMPLE) && + (video_object_type_indication != RESERVED_OBJECT_TYPE) && + (video_object_type_indication != MAIN_OBJECT_TYPE)) { + return false; + } + /* is_object_layer_identifier*/ + uint32 is_object_layer_identifier = read_bit_field (&m_posInfo, 1); + if (is_object_layer_identifier) { + uint32 video_object_layer_verid = read_bit_field (&m_posInfo, 4); + uint32 video_object_layer_priority = read_bit_field (&m_posInfo, 3); + VerID = (unsigned char)video_object_layer_verid; + } + + /* aspect_ratio_info*/ + uint32 aspect_ratio_info = read_bit_field (&m_posInfo, 4); + if ( aspect_ratio_info == EXTENDED_PAR ) { + /* par_width*/ + read_bit_field (&m_posInfo, 8); + /* par_height*/ + read_bit_field (&m_posInfo, 8); + } + /* vol_control_parameters */ + uint32 vol_control_parameters = read_bit_field (&m_posInfo, 1); + if ( vol_control_parameters ) { + /* chroma_format*/ + uint32 chroma_format = read_bit_field (&m_posInfo, 2); + if ( chroma_format != 1 ) { + return false; + } + /* low_delay*/ + uint32 low_delay = read_bit_field (&m_posInfo, 1); + /* vbv_parameters (annex D)*/ + uint32 vbv_parameters = read_bit_field (&m_posInfo, 1); + if ( vbv_parameters ) { + /* first_half_bitrate*/ + uint32 first_half_bitrate = read_bit_field (&m_posInfo, 15); + uint32 marker_bit = read_bit_field (&m_posInfo, 1); + if ( marker_bit != 1) { + return false; + } + /* latter_half_bitrate*/ + uint32 latter_half_bitrate = read_bit_field (&m_posInfo, 15); + marker_bit = read_bit_field (&m_posInfo, 1); + if ( marker_bit != 1) { + return false; + } + uint32 VBVPeakBitRate = (first_half_bitrate << 15) + latter_half_bitrate; + /* first_half_vbv_buffer_size*/ + uint32 first_half_vbv_buffer_size = read_bit_field (&m_posInfo, 15); + marker_bit = read_bit_field (&m_posInfo, 1); + if ( marker_bit != 1) { + return false; + } + /* latter_half_vbv_buffer_size*/ + uint32 latter_half_vbv_buffer_size = read_bit_field (&m_posInfo, 3); + uint32 VBVBufferSize = (first_half_vbv_buffer_size << 3) + latter_half_vbv_buffer_size; + /* first_half_vbv_occupancy*/ + uint32 first_half_vbv_occupancy = read_bit_field (&m_posInfo, 11); + marker_bit = read_bit_field (&m_posInfo, 1); + if ( marker_bit != 1) { + return false; + } + /* latter_half_vbv_occupancy*/ + uint32 latter_half_vbv_occupancy = read_bit_field (&m_posInfo, 15); + marker_bit = read_bit_field (&m_posInfo, 1); + if ( marker_bit != 1) { + return false; + } + }/* vbv_parameters*/ + }/*vol_control_parameters*/ + + /* video_object_layer_shape*/ + uint32 video_object_layer_shape = read_bit_field (&m_posInfo, 2); + uint8 VOLShape = (unsigned char)video_object_layer_shape; + if ( VOLShape != MPEG4_SHAPE_RECTANGULAR ) { + return false; + } + /* marker_bit*/ + uint32 marker_bit = read_bit_field (&m_posInfo, 1); + if ( marker_bit != 1 ) { + return false; + } + /* vop_time_increment_resolution*/ + uint32 vop_time_increment_resolution = read_bit_field (&m_posInfo, 16); + vop_time_resolution = vop_time_increment_resolution; + vop_time_found = true; + return true; +} + +bool MP4_Utils::is_notcodec_vop(unsigned char *pbuffer, unsigned int len) +{ + unsigned int index = 4,vop_bits=0; + unsigned int temp = vop_time_resolution - 1; + unsigned char vop_type=0,modulo_bit=0,not_coded=0; + if (!vop_time_found || !pbuffer || len < 5) { + return false; + } + if((pbuffer[0] == 0) && (pbuffer[1] == 0) && (pbuffer[2] == 1) && (pbuffer[3] == 0xB6)){ + while(temp) { + vop_bits++; + temp >>= 1; + } + vop_type = (pbuffer[index] & 0xc0) >> 6; + unsigned bits_parsed = 2; + do { + modulo_bit = pbuffer[index] & (1 << (7-bits_parsed)); + bits_parsed++; + index += bits_parsed/8; + bits_parsed = bits_parsed %8; + if(index >= len) { + return false; + } + }while(modulo_bit); + bits_parsed++; //skip marker bit + bits_parsed += vop_bits + 1;//Vop bit & Marker bits + index += bits_parsed/8; + if(index >= len) { + return false; + } + bits_parsed = bits_parsed % 8; + not_coded = pbuffer[index] & (1 << (7 - bits_parsed)); + if(!not_coded){ + return true; + } + } + return false; +} diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec.cpp new file mode 100644 index 00000000..f9ca19ca --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec.cpp @@ -0,0 +1,9978 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +/*============================================================================ + O p e n M A X w r a p p e r s + O p e n M A X C o r e + +*//** @file omx_vdec.cpp + This module contains the implementation of the OpenMAX core & component. + +*//*========================================================================*/ + +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// +#define JB_MR1 +#include +#include +#include +#include +#include +#include +#ifndef JB_MR1 +#include +#include +#endif +#include "power_module.h" +#include "omx_vdec.h" +#include +#include + +#ifndef _ANDROID_ +#include +#include +#endif //_ANDROID_ + +#ifdef _ANDROID_ +#include +#undef USE_EGL_IMAGE_GPU +#endif + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +#include +#endif + +#if defined (_ANDROID_ICS_) +#include +#include +#endif + +#ifdef _ANDROID_ +#include "DivXDrmDecrypt.h" +#endif //_ANDROID_ + +#ifdef USE_EGL_IMAGE_GPU +#include +#include +#define EGL_BUFFER_HANDLE_QCOM 0x4F00 +#define EGL_BUFFER_OFFSET_QCOM 0x4F01 +#endif + +#ifdef INPUT_BUFFER_LOG +#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" +#define INPUT_BUFFER_FILE_NAME_LEN 30 +FILE *inputBufferFile1; +char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; +#endif +#ifdef OUTPUT_BUFFER_LOG +FILE *outputBufferFile1; +char outputfilename [] = "/data/output.yuv"; +#endif +#ifdef OUTPUT_EXTRADATA_LOG +FILE *outputExtradataFile; +char ouputextradatafilename [] = "/data/extradata"; +#endif + +#define DEFAULT_FPS 30 +#define MAX_NUM_SPS 32 +#define MAX_NUM_PPS 256 +#define MAX_INPUT_ERROR (MAX_NUM_SPS + MAX_NUM_PPS) +#define MAX_SUPPORTED_FPS 120 + +#define VC1_SP_MP_START_CODE 0xC5000000 +#define VC1_SP_MP_START_CODE_MASK 0xFF000000 +#define VC1_AP_SEQ_START_CODE 0x0F010000 +#define VC1_STRUCT_C_PROFILE_MASK 0xF0 +#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 +#define VC1_SIMPLE_PROFILE 0 +#define VC1_MAIN_PROFILE 1 +#define VC1_ADVANCE_PROFILE 3 +#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 +#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 +#define VC1_STRUCT_C_LEN 4 +#define VC1_STRUCT_C_POS 8 +#define VC1_STRUCT_A_POS 12 +#define VC1_STRUCT_B_POS 24 +#define VC1_SEQ_LAYER_SIZE 36 + +#ifdef USE_ION + #define MEM_DEVICE "/dev/ion" + #ifdef MAX_RES_720P + #define MEM_HEAP_ID ION_CAMERA_HEAP_ID + #else + #define MEM_HEAP_ID ION_CP_MM_HEAP_ID + #endif +#elif MAX_RES_720P +#define MEM_DEVICE "/dev/pmem_adsp" +#elif MAX_RES_1080P_EBI +#define MEM_DEVICE "/dev/pmem_adsp" +#elif MAX_RES_1080P +#define MEM_DEVICE "/dev/pmem_smipool" +#endif + + +#ifdef MAX_RES_720P +#define DEVICE_SCRATCH 0 +#else +#define DEVICE_SCRATCH 64 +#endif + +/* +#ifdef _ANDROID_ + extern "C"{ + #include + } +#endif//_ANDROID_ +*/ + +#ifndef _ANDROID_ +#include +#define strlcpy g_strlcpy +#endif + +#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } +#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } + +void* async_message_thread (void *input) +{ + struct vdec_ioctl_msg ioctl_msg; + struct vdec_msginfo vdec_msg; + omx_vdec *omx = reinterpret_cast(input); + int error_code = 0; + DEBUG_PRINT_HIGH("omx_vdec: Async thread start"); + prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); + while (1) + { + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&vdec_msg; + /*Wait for a message from the video decoder driver*/ + error_code = ioctl ( omx->drv_ctx.video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG, + (void*)&ioctl_msg); + if (error_code == -512) // ERESTARTSYS + { + DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!"); + } + else if (error_code < 0) + { + DEBUG_PRINT_ERROR("\n Error in ioctl read next msg"); + break; + } /*Call Instance specific process function*/ + else if (omx->async_message_process(input,&vdec_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message"); + } + } + DEBUG_PRINT_HIGH("omx_vdec: Async thread stop"); + return NULL; +} + +void* message_thread(void *input) +{ + omx_vdec* omx = reinterpret_cast(input); + unsigned char id; + int n; + + DEBUG_PRINT_HIGH("omx_vdec: message thread start"); + prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); + while (1) + { + + n = read(omx->m_pipe_in, &id, 1); + + if(0 == n) + { + break; + } + + if (1 == n) + { + omx->process_event_cb(omx, id); + } + if ((n < 0) && (errno != EINTR)) + { + DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); + break; + } + } + DEBUG_PRINT_HIGH("omx_vdec: message thread stop"); + return 0; +} + +void post_message(omx_vdec *omx, unsigned char id) +{ + int ret_value; + DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out); + ret_value = write(omx->m_pipe_out, &id, 1); + DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value); +} + +// omx_cmd_queue destructor +omx_vdec::omx_cmd_queue::~omx_cmd_queue() +{ + // Nothing to do +} + +// omx cmd queue constructor +omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) +{ + memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); +} + +// omx cmd queue insert +bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) +{ + bool ret = true; + if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_q[m_write].id = id; + m_q[m_write].param1 = p1; + m_q[m_write].param2 = p2; + m_write++; + m_size ++; + if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_write = 0; + } + } + else + { + ret = false; + DEBUG_PRINT_ERROR("\n ERROR: %s()::Command Queue Full", __func__); + } + return ret; +} + +// omx cmd queue pop +bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) +{ + bool ret = true; + if (m_size > 0) + { + *id = m_q[m_read].id; + *p1 = m_q[m_read].param1; + *p2 = m_q[m_read].param2; + // Move the read pointer ahead + ++m_read; + --m_size; + if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_read = 0; + } + } + else + { + ret = false; + } + return ret; +} + +// Retrieve the first mesg type in the queue +unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() +{ + return m_q[m_read].id; +} + +#ifdef _ANDROID_ +omx_vdec::ts_arr_list::ts_arr_list() +{ + //initialize timestamps array + memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); +} +omx_vdec::ts_arr_list::~ts_arr_list() +{ + //free m_ts_arr_list? +} + +bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) +{ + bool ret = true; + bool duplicate_ts = false; + int idx = 0; + + //insert at the first available empty location + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + if (!m_ts_arr_list[idx].valid) + { + //found invalid or empty entry, save timestamp + m_ts_arr_list[idx].valid = true; + m_ts_arr_list[idx].timestamp = ts; + DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", + ts, idx); + break; + } + } + + if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) + { + DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); + ret = false; + } + return ret; +} + +bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) +{ + bool ret = true; + int min_idx = -1; + OMX_TICKS min_ts = 0; + int idx = 0; + + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + + if (m_ts_arr_list[idx].valid) + { + //found valid entry, save index + if (min_idx < 0) + { + //first valid entry + min_ts = m_ts_arr_list[idx].timestamp; + min_idx = idx; + } + else if (m_ts_arr_list[idx].timestamp < min_ts) + { + min_ts = m_ts_arr_list[idx].timestamp; + min_idx = idx; + } + } + + } + + if (min_idx < 0) + { + //no valid entries found + DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); + ts = 0; + ret = false; + } + else + { + ts = m_ts_arr_list[min_idx].timestamp; + m_ts_arr_list[min_idx].valid = false; + DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", + ts, min_idx); + } + + return ret; + +} + + +bool omx_vdec::ts_arr_list::reset_ts_list() +{ + bool ret = true; + int idx = 0; + + DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + m_ts_arr_list[idx].valid = false; + } + return ret; +} +#endif + +// factory function executed by the core to create instances +void *get_omx_component_factory_fn(void) +{ + return (new omx_vdec); +} + +#ifdef _ANDROID_ +#ifdef USE_ION +VideoHeap::VideoHeap(int devicefd, size_t size, void* base, + struct ion_handle *handle, int ionMapfd) +{ + m_ion_device_fd = devicefd; + m_ion_handle = handle; + MemoryHeapBase::init(ionMapfd, base, size, 0, MEM_DEVICE); + //ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); +} +#else +VideoHeap::VideoHeap(int fd, size_t size, void* base) +{ + // dup file descriptor, map once, use pmem + init(dup(fd), base, size, 0 , MEM_DEVICE); +} +#endif +#endif // _ANDROID_ +/* ====================================================================== +FUNCTION + omx_vdec::omx_vdec + +DESCRIPTION + Constructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_vdec::omx_vdec(): m_state(OMX_StateInvalid), + m_app_data(NULL), + m_inp_mem_ptr(NULL), + m_out_mem_ptr(NULL), + m_phdr_pmem_ptr(NULL), + pending_input_buffers(0), + pending_output_buffers(0), + m_out_bm_count(0), + m_inp_bm_count(0), + m_inp_bPopulated(OMX_FALSE), + m_out_bPopulated(OMX_FALSE), + m_flags(0), + m_inp_bEnabled(OMX_TRUE), + m_out_bEnabled(OMX_TRUE), + m_platform_list(NULL), + m_platform_entry(NULL), + m_pmem_info(NULL), + output_flush_progress (false), + input_flush_progress (false), + input_use_buffer (false), + output_use_buffer (false), + arbitrary_bytes (true), + psource_frame (NULL), + pdest_frame (NULL), + m_inp_heap_ptr (NULL), + m_heap_inp_bm_count (0), + codec_type_parse ((codec_type)0), + first_frame_meta (true), + frame_count (0), + nal_length(0), + nal_count (0), + look_ahead_nal (false), + first_frame(0), + first_buffer(NULL), + first_frame_size (0), + m_error_propogated(false), + m_device_file_ptr(NULL), + m_vc1_profile((vc1_profile_type)0), + prev_ts(LLONG_MAX), + rst_prev_ts(true), + frm_int(0), + m_in_alloc_cnt(0), + m_display_id(NULL), + ouput_egl_buffers(false), + h264_parser(NULL), + client_extradata(0), + h264_last_au_ts(LLONG_MAX), + h264_last_au_flags(0), + m_inp_err_count(0), + m_disp_hor_size(0), + m_disp_vert_size(0), +#ifdef _ANDROID_ + m_heap_ptr(NULL), + m_heap_count(0), + m_enable_android_native_buffers(OMX_FALSE), + m_use_android_native_buffers(OMX_FALSE), +#endif + in_reconfig(false), + m_use_output_pmem(OMX_FALSE), + m_out_mem_region_smi(OMX_FALSE), + m_out_pvt_entry_pmem(OMX_FALSE), + secure_mode(false), + external_meta_buffer(false), + external_meta_buffer_iommu(false) +#ifdef _ANDROID_ + ,iDivXDrmDecrypt(NULL) +#endif + ,m_desc_buffer_ptr(NULL) + ,m_extradata(NULL) + ,m_power_hinted(false) +{ + /* Assumption is that , to begin with , we have all the frames with decoder */ + DEBUG_PRINT_HIGH("In OMX vdec Constructor"); +#ifdef _ANDROID_ + char property_value[PROPERTY_VALUE_MAX] = {0}; + property_get("vidc.dec.debug.perf", property_value, "0"); + perf_flag = atoi(property_value); + if (perf_flag) + { + DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); + dec_time.start(); + proc_frms = latency = 0; + } + property_value[0] = NULL; + property_get("vidc.dec.debug.ts", property_value, "0"); + m_debug_timestamp = atoi(property_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); + if (m_debug_timestamp) + { + time_stamp_dts.set_timestamp_reorder_mode(true); + time_stamp_dts.enable_debug_print(true); + } + + property_value[0] = NULL; + property_get("vidc.dec.debug.concealedmb", property_value, "0"); + m_debug_concealedmb = atoi(property_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); + +#endif + memset(&m_cmp,0,sizeof(m_cmp)); + memset(&m_cb,0,sizeof(m_cb)); + memset (&drv_ctx,0,sizeof(drv_ctx)); + memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); + memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); + memset(&op_buf_rcnfg, 0 ,sizeof(vdec_allocatorproperty)); + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + msg_thread_created = false; + async_thread_created = false; +#ifdef _ANDROID_ICS_ + memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); +#endif + drv_ctx.timestamp_adjust = false; + drv_ctx.video_driver_fd = -1; + m_vendor_config.pData = NULL; + pthread_mutex_init(&m_lock, NULL); + sem_init(&m_cmd_lock,0,0); +#ifdef _ANDROID_ + char extradata_value[PROPERTY_VALUE_MAX] = {0}; + property_get("vidc.dec.debug.extradata", extradata_value, "0"); + m_debug_extradata = atoi(extradata_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); +#endif + m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; + client_buffers.set_vdec_client(this); +} + + +/* ====================================================================== +FUNCTION + omx_vdec::~omx_vdec + +DESCRIPTION + Destructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_vdec::~omx_vdec() +{ + m_pmem_info = NULL; + DEBUG_PRINT_HIGH("In OMX vdec Destructor"); + if(m_pipe_in) close(m_pipe_in); + if(m_pipe_out) close(m_pipe_out); + m_pipe_in = -1; + m_pipe_out = -1; + if (msg_thread_created) + { + DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); + pthread_join(msg_thread_id,NULL); + } + if (async_thread_created) + { + DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); + pthread_join(async_thread_id,NULL); + } + DEBUG_PRINT_HIGH("Calling close() on Video Driver"); + close (drv_ctx.video_driver_fd); + drv_ctx.video_driver_fd = -1; + + pthread_mutex_destroy(&m_lock); + sem_destroy(&m_cmd_lock); +#ifdef _ANDROID_ + if (perf_flag) + { + DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); + dec_time.end(); + } +#endif /* _ANDROID_ */ + DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); +} + +/* ====================================================================== +FUNCTION + omx_vdec::OMXCntrlProcessMsgCb + +DESCRIPTION + IL Client callbacks are generated through this routine. The decoder + provides the thread context for this routine. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +void omx_vdec::process_event_cb(void *ctxt, unsigned char id) +{ + unsigned p1; // Parameter - 1 + unsigned p2; // Parameter - 2 + unsigned ident; + unsigned qsize=0; // qsize + omx_vdec *pThis = (omx_vdec *) ctxt; + + if(!pThis) + { + DEBUG_PRINT_ERROR("\n ERROR: %s()::Context is incorrect, bailing out", + __func__); + return; + } + + // Protect the shared queue data structure + do + { + /*Read the message id's from the queue*/ + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if(qsize) + { + pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); + } + + if (qsize == 0 && pThis->m_state != OMX_StatePause) + { + qsize = pThis->m_ftb_q.m_size; + if (qsize) + { + pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); + } + } + + if (qsize == 0 && pThis->m_state != OMX_StatePause) + { + qsize = pThis->m_etb_q.m_size; + if (qsize) + { + pThis->m_etb_q.pop_entry(&p1,&p2,&ident); + } + } + pthread_mutex_unlock(&pThis->m_lock); + + /*process message if we have one*/ + if(qsize > 0) + { + id = ident; + switch (id) + { + case OMX_COMPONENT_GENERATE_EVENT: + if (pThis->m_cb.EventHandler) + { + switch (p1) + { + case OMX_CommandStateSet: + pThis->m_state = (OMX_STATETYPE) p2; + DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d", + pThis->m_state); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL); + break; + + case OMX_EventError: + if(p2 == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); + pThis->m_state = (OMX_STATETYPE) p2; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError, OMX_ErrorInvalidState, p2, NULL); + } + else if (p2 == OMX_ErrorHardware) + { + pThis->omx_report_error(); + } + else + { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError, p2, NULL, NULL ); + } + break; + + case OMX_CommandPortDisable: + DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2); + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) + { + BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); + break; + } + if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig) + { + pThis->in_reconfig = false; + pThis->drv_ctx.op_buf = pThis->op_buf_rcnfg; + OMX_ERRORTYPE eRet = pThis->set_buffer_req(&pThis->drv_ctx.op_buf); + if(eRet != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); + pThis->omx_report_error(); + break; + } + } + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + case OMX_CommandPortEnable: + DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + default: + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + } + } + else + { + DEBUG_PRINT_ERROR("\n ERROR: %s()::EventHandler is NULL", __func__); + } + break; + case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: + if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); + pThis->omx_report_error (); + } + break; + case OMX_COMPONENT_GENERATE_ETB: + if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FTB: + if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_COMMAND: + pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ + (OMX_U32)p2,(OMX_PTR)NULL); + break; + + case OMX_COMPONENT_GENERATE_EBD: + + if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); + pThis->omx_report_error (); + } + else + { + if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) + { + pThis->m_inp_err_count++; + pThis->time_stamp_dts.remove_time_stamp( + ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, + (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + } + else + { + pThis->m_inp_err_count = 0; + } + if ( pThis->empty_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); + pThis->omx_report_error (); + } + if(!pThis->arbitrary_bytes && pThis->m_inp_err_count > MAX_INPUT_ERROR) + { + DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); + pThis->omx_report_error (); + } + } + break; + case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: + { + int64_t *timestamp = (int64_t *)p1; + if (p1) + { + pThis->time_stamp_dts.remove_time_stamp(*timestamp, + (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + free(timestamp); + } + } + break; + case OMX_COMPONENT_GENERATE_FBD: + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); + pThis->omx_report_error (); + } + else if ( pThis->fill_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: + DEBUG_PRINT_HIGH("Driver flush i/p Port complete"); + if (!pThis->input_flush_progress) + { + DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); + } + else + { + pThis->execute_input_flush(); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); + pThis->omx_report_error (); + } + else + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_INPUT_FLUSH_PENDING)) + { + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); + DEBUG_PRINT_LOW("Input Flush completed - Notify Client"); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + OMX_CORE_INPUT_PORT_INDEX,NULL ); + } + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_IDLE_PENDING)) + { + if (!pThis->output_flush_progress) + { + DEBUG_PRINT_LOW("Output flush done hence issue stop"); + if (ioctl (pThis->drv_ctx.video_driver_fd, + VDEC_IOCTL_CMD_STOP,NULL ) < 0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); + pThis->omx_report_error (); + } + } + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: + DEBUG_PRINT_HIGH("Driver flush o/p Port complete"); + if (!pThis->output_flush_progress) + { + DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); + } + else + { + pThis->execute_output_flush(); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); + pThis->omx_report_error (); + } + else + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) + { + DEBUG_PRINT_LOW("Notify Output Flush done"); + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + OMX_CORE_OUTPUT_PORT_INDEX,NULL ); + } + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) + { + DEBUG_PRINT_LOW("Internal flush complete"); + BITMASK_CLEAR (&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) + { + pThis->post_event(OMX_CommandPortDisable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + BITMASK_CLEAR (&pThis->m_flags, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); + + } + } + + if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) + { + if (!pThis->input_flush_progress) + { + DEBUG_PRINT_LOW("Input flush done hence issue stop"); + if (ioctl (pThis->drv_ctx.video_driver_fd, + VDEC_IOCTL_CMD_STOP,NULL ) < 0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); + pThis->omx_report_error (); + } + } + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_START_DONE: + DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE"); + + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); + pThis->omx_report_error (); + } + else + { + DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success"); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("Move to executing"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting, NULL); + } + else if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_PAUSE_PENDING)) + { + if (ioctl (pThis->drv_ctx.video_driver_fd, + VDEC_IOCTL_CMD_PAUSE,NULL ) < 0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); + pThis->omx_report_error (); + } + } + } + } + else + { + DEBUG_PRINT_ERROR("\n Event Handler callback is NULL"); + } + break; + + case OMX_COMPONENT_GENERATE_PAUSE_DONE: + DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); + pThis->omx_report_error (); + } + else + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) + { + DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); + //Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); + pThis->m_state = OMX_StatePause; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StatePause, NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_RESUME_DONE: + DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); + pThis->omx_report_error (); + } + else + { + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("Moving the decoder to execute state"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting,NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_STOP_DONE: + DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); + pThis->omx_report_error (); + } + else + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); + pThis->m_state = OMX_StateIdle; + DEBUG_PRINT_LOW("Move to Idle State"); + pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateIdle,NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_PORT_RECONFIG: + DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); + if (pThis->start_port_reconfig() != OMX_ErrorNone) + pThis->omx_report_error(); + else + { + if (pThis->in_reconfig) + { + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventPortSettingsChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + { + OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; + OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; + if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) + format = OMX_InterlaceInterleaveFrameTopFieldFirst; + else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) + format = OMX_InterlaceInterleaveFrameBottomFieldFirst; + else //unsupported interlace format; raise a error + event = OMX_EventError; + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + event, format, 0, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + } + break; + + case OMX_COMPONENT_GENERATE_EOS_DONE: + DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, + OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + pThis->prev_ts = LLONG_MAX; + pThis->rst_prev_ts = true; + break; + + case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); + pThis->omx_report_error (); + break; + case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: + { + DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + //update power HAL with new width, height and bitrate + pThis->power_module_deregister(); + pThis->power_module_register(); + } + default: + break; + } + } + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if (pThis->m_state != OMX_StatePause) + qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); + pthread_mutex_unlock(&pThis->m_lock); + } + while(qsize>0); + +} + + + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentInit + +DESCRIPTION + Initialize the component. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + unsigned int alignment = 0,buffer_size = 0; + int is_secure = 0; + int i = 0; + int fds[2]; + int r; + OMX_STRING device_name = "/dev/msm_vidc_dec"; + +#ifndef JB_MR1 + sp sm; + sp hwcBinder = NULL; +#endif + if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){ + secure_mode = true; + arbitrary_bytes = false; + role = "OMX.qcom.video.decoder.avc"; + device_name = "/dev/msm_vidc_dec_sec"; + is_secure = 1; + } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",OMX_MAX_STRINGNAME_SIZE)){ + secure_mode = true; + arbitrary_bytes = false; + role = "OMX.qcom.video.decoder.mpeg2"; + device_name = "/dev/msm_vidc_dec_sec"; + is_secure = 1; + } +#ifndef JB_MR1 + if (secure_mode) { + sm = defaultServiceManager(); + hwcBinder = + interface_cast(sm->getService(String16("display.hwcservice"))); + if (hwcBinder != NULL) { + hwcBinder->setOpenSecureStart(); + } else { + DEBUG_PRINT_HIGH("Failed to get ref to hwcBinder, " + "cannot call secure display start"); + } + } +#endif + DEBUG_PRINT_HIGH("omx_vdec::component_init(): Start of New Playback : role = %s : DEVICE = %s", + role, device_name); + + drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); + + DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d, errno %d", + drv_ctx.video_driver_fd, errno); + + if(drv_ctx.video_driver_fd == 0){ + drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); + } + + if(is_secure && drv_ctx.video_driver_fd < 0) { + do { + usleep(100 * 1000); + drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); + if (drv_ctx.video_driver_fd > 0) { + break; + } + } while(i++ < 50); + } + if(drv_ctx.video_driver_fd < 0) + { + DEBUG_PRINT_ERROR("\n Omx_vdec::Comp Init Returning failure, errno %d", errno); + return OMX_ErrorInsufficientResources; + } + drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; + drv_ctx.frame_rate.fps_denominator = 1; + + +#ifdef INPUT_BUFFER_LOG + strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); +#endif +#ifdef OUTPUT_BUFFER_LOG + outputBufferFile1 = fopen (outputfilename, "ab"); +#endif +#ifdef OUTPUT_EXTRADATA_LOG + outputExtradataFile = fopen (ouputextradatafilename, "ab"); +#endif + + // Copy the role information which provides the decoder kind + strlcpy(drv_ctx.kind,role,128); + if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE); + drv_ctx.timestamp_adjust = true; + drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; + eCompressionFormat = OMX_VIDEO_CodingMPEG4; + /*Initialize Start Code for MPEG4*/ + codec_type_parse = CODEC_TYPE_MPEG4; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "m4v"); +#endif + } + else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ + OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; + eCompressionFormat = OMX_VIDEO_CodingMPEG2; + /*Initialize Start Code for MPEG2*/ + codec_type_parse = CODEC_TYPE_MPEG2; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "mpg"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("H263 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_H263; + eCompressionFormat = OMX_VIDEO_CodingH263; + codec_type_parse = CODEC_TYPE_H263; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "263"); +#endif + } +#ifdef MAX_RES_1080P + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW ("DIVX 311 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef _ANDROID_ + OMX_ERRORTYPE err = createDivxDrmContext(); + if( err != OMX_ErrorNone ) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + eRet = err; + goto cleanup; + } +#endif //_ANDROID_ + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef _ANDROID_ + OMX_ERRORTYPE err = createDivxDrmContext(); + if( err != OMX_ErrorNone ) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + eRet = err; + goto cleanup; + } +#endif //_ANDROID_ + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef _ANDROID_ + OMX_ERRORTYPE err = createDivxDrmContext(); + if( err != OMX_ErrorNone ) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + eRet = err; + goto cleanup; + } +#endif //_ANDROID_ + } +#else + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ + OMX_MAX_STRINGNAME_SIZE)) || (!strncmp(drv_ctx.kind, \ + "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE))) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_ERROR ("DIVX Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_5; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + m_frame_parser.init_start_codes (codec_type_parse); + +#ifdef _ANDROID_ + OMX_ERRORTYPE err = createDivxDrmContext(); + if( err != OMX_ErrorNone ) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + eRet = err; + goto cleanup; + } +#endif //_ANDROID_ + } +#endif + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_H264; + eCompressionFormat = OMX_VIDEO_CodingAVC; + codec_type_parse = CODEC_TYPE_H264; + m_frame_parser.init_start_codes (codec_type_parse); + m_frame_parser.init_nal_length(nal_length); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "264"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; + eCompressionFormat = OMX_VIDEO_CodingWMV; + codec_type_parse = CODEC_TYPE_VC1; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "vc1"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; + eCompressionFormat = OMX_VIDEO_CodingWMV; + codec_type_parse = CODEC_TYPE_VC1; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "vc1"); +#endif + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } +#ifdef INPUT_BUFFER_LOG + inputBufferFile1 = fopen (inputfilename, "ab"); +#endif + if (eRet == OMX_ErrorNone) + { +#ifdef MAX_RES_720P + drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; + +#endif +#ifdef MAX_RES_1080P + drv_ctx.output_format = VDEC_YUV_FORMAT_TILE_4x2; + OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; + if (!client_buffers.set_color_format(dest_color_format)) { + DEBUG_PRINT_ERROR("\n Setting color format failed"); + eRet = OMX_ErrorInsufficientResources; + } +#endif + /*Initialize Decoder with codec type and resolution*/ + ioctl_msg.in = &drv_ctx.decoder_format; + ioctl_msg.out = NULL; + + if ( (eRet == OMX_ErrorNone) && + ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_CODEC, + (void*)&ioctl_msg) < 0) + + { + DEBUG_PRINT_ERROR("\n Set codec type failed"); + eRet = OMX_ErrorInsufficientResources; + } + + /*Set the output format*/ + ioctl_msg.in = &drv_ctx.output_format; + ioctl_msg.out = NULL; + + if ( (eRet == OMX_ErrorNone) && + ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set output format failed"); + eRet = OMX_ErrorInsufficientResources; + } + +#ifdef MAX_RES_720P + drv_ctx.video_resolution.frame_height = + drv_ctx.video_resolution.scan_lines = 720; + drv_ctx.video_resolution.frame_width = + drv_ctx.video_resolution.stride = 1280; +#endif +#ifdef MAX_RES_1080P + drv_ctx.video_resolution.frame_height = + drv_ctx.video_resolution.scan_lines = 1088; + drv_ctx.video_resolution.frame_width = + drv_ctx.video_resolution.stride = 1920; +#endif + + ioctl_msg.in = &drv_ctx.video_resolution; + ioctl_msg.out = NULL; + + if ( (eRet == OMX_ErrorNone) && + ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_PICRES, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set Resolution failed"); + eRet = OMX_ErrorInsufficientResources; + } + + /*Get the Buffer requirements for input and output ports*/ + drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; + drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; + drv_ctx.extradata = 0; + drv_ctx.picture_order = VDEC_ORDER_DISPLAY; + drv_ctx.idr_only_decoding = 0; + + if (eRet == OMX_ErrorNone) + eRet = get_buffer_req(&drv_ctx.ip_buf); + if (eRet == OMX_ErrorNone) + eRet = get_buffer_req(&drv_ctx.op_buf); + m_state = OMX_StateLoaded; +#ifdef DEFAULT_EXTRADATA + if (eRet == OMX_ErrorNone) + eRet = enable_extradata(DEFAULT_EXTRADATA); +#endif + if ( (codec_type_parse == CODEC_TYPE_VC1) || + (codec_type_parse == CODEC_TYPE_H264)) //add CP check here + { + //Check if dmx can be disabled + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + ioctl_msg.out = &drv_ctx.disable_dmx; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT, &ioctl_msg)) + { + DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT"); + eRet = OMX_ErrorHardware; + } + else + { + if (drv_ctx.disable_dmx && !secure_mode) + { + DEBUG_PRINT_HIGH("DMX disable is supported"); + + int rc = ioctl(drv_ctx.video_driver_fd, + VDEC_IOCTL_SET_DISABLE_DMX); + if(rc < 0) { + DEBUG_PRINT_ERROR("Failed to disable dmx on driver."); + drv_ctx.disable_dmx = false; + eRet = OMX_ErrorHardware; + } + } + else { + drv_ctx.disable_dmx = false; + } + } + } + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + if (m_frame_parser.mutils == NULL) + { + m_frame_parser.mutils = new H264_Utils(); + + if (m_frame_parser.mutils == NULL) + { + DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); + eRet = OMX_ErrorInsufficientResources; + } + else + { + h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; + h264_scratch.pBuffer = (OMX_U8 *)malloc (h264_scratch.nAllocLen); + h264_scratch.nFilledLen = 0; + h264_scratch.nOffset = 0; + + if (h264_scratch.pBuffer == NULL) + { + DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); + return OMX_ErrorInsufficientResources; + } + m_frame_parser.mutils->initialize_frame_checking_environment(); + m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); + } + } + + h264_parser = new h264_stream_parser(); + if (!h264_parser) + { + DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); + eRet = OMX_ErrorInsufficientResources; + } + } + + if(pipe(fds)) + { + DEBUG_PRINT_ERROR("\n pipe creation failed."); + eRet = OMX_ErrorInsufficientResources; + } + else + { + int temp1[2]; + if(fds[0] == 0 || fds[1] == 0) + { + if (pipe (temp1)) + { + DEBUG_PRINT_ERROR("\n pipe creation failed.."); + return OMX_ErrorInsufficientResources; + } + //close (fds[0]); + //close (fds[1]); + fds[0] = temp1 [0]; + fds[1] = temp1 [1]; + } + m_pipe_in = fds[0]; + m_pipe_out = fds[1]; + r = pthread_create(&msg_thread_id,0,message_thread,this); + if(r < 0) + { + DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + msg_thread_created = true; + r = pthread_create(&async_thread_id,0,async_message_thread,this); + if(r < 0) + { + DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + async_thread_created = true; + } + } + } + } + + if (eRet != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Component Init Failed"); + DEBUG_PRINT_HIGH("Calling VDEC_IOCTL_STOP_NEXT_MSG"); + (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, + NULL); + } + else + { + DEBUG_PRINT_HIGH("omx_vdec::component_init() success"); + } + + memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); + memset(&meta_buff,0,sizeof(struct meta_buffer)); +cleanup: + if (!secure_mode) { + return eRet; + } +#ifndef JB_MR1 + if (hwcBinder != NULL) { + (eRet == OMX_ErrorNone) ? + hwcBinder->setOpenSecureEnd() : + hwcBinder->setCloseSecureEnd(); + } else { + DEBUG_PRINT_HIGH("hwcBinder not found, " + "not calling secure end"); + } +#endif + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetComponentVersion + +DESCRIPTION + Returns the component version. + +PARAMETERS + TBD. + +RETURN VALUE + OMX_ErrorNone. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_component_version + ( + OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STRING componentName, + OMX_OUT OMX_VERSIONTYPE* componentVersion, + OMX_OUT OMX_VERSIONTYPE* specVersion, + OMX_OUT OMX_UUIDTYPE* componentUUID + ) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n Get Comp Version in Invalid State"); + return OMX_ErrorInvalidState; + } + /* TBD -- Return the proper version */ + if (specVersion) + { + specVersion->nVersion = OMX_SPEC_VERSION; + } + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_vdec::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + DEBUG_PRINT_HIGH("send_command: Recieved a Command from Client"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n ERROR: Send Command in Invalid State"); + return OMX_ErrorInvalidState; + } + if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX + && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) + { + DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush " + "to invalid port: %d", param1); + return OMX_ErrorBadPortIndex; + } + post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); + sem_wait(&m_cmd_lock); + DEBUG_PRINT_HIGH("send_command: Command Processed"); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_STATETYPE eState = (OMX_STATETYPE) param1; + int bFlag = 1,sem_posted = 0; + + DEBUG_PRINT_HIGH("send_command_proxy(): cmd = %d, Current State %d, Expected State %d", + cmd, m_state, eState); + + if(cmd == OMX_CommandStateSet) + { + DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued"); + DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState); + /***************************/ + /* Current State is Loaded */ + /***************************/ + if(m_state == OMX_StateLoaded) + { + if(eState == OMX_StateIdle) + { + //if all buffers are allocated or all ports disabled + if(allocate_done() || + (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) + { + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle"); + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending"); + BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Loaded to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\n ERROR::send_command_proxy(): Loaded-->Loaded"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Loaded to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources"); + } + /* Requesting transition from Loaded to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ + eState); + eRet = OMX_ErrorBadParameter; + } + } + + /***************************/ + /* Current State is IDLE */ + /***************************/ + else if(m_state == OMX_StateIdle) + { + if(eState == OMX_StateLoaded) + { + if(release_done()) + { + /* + Since error is None , we will post an event at the end + of this function definition + */ + DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Loaded"); + } + else + { + DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Loaded-Pending"); + BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Idle to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Executing"); + BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); + bFlag = 0; + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, + NULL) < 0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } else { + power_module_register(); + } + } + /* Requesting transition from Idle to Idle */ + else if(eState == OMX_StateIdle) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Idle to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Idle to Pause */ + else if(eState == OMX_StatePause) + { + /*To pause the Video core we need to start the driver*/ + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, + NULL) < 0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Pause"); + bFlag = 0; + } + } + /* Requesting transition from Idle to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + + /******************************/ + /* Current State is Executing */ + /******************************/ + else if(m_state == OMX_StateExecuting) + { + DEBUG_PRINT_HIGH("Command Recieved in OMX_StateExecuting"); + /* Requesting transition from Executing to Idle */ + if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition + */ + DEBUG_PRINT_HIGH("send_command_proxy(): Executing --> Idle"); + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + execute_omx_flush(OMX_ALL); + } + bFlag = 0; + } + /* Requesting transition from Executing to Paused */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_HIGH("PAUSE Command Issued"); + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_PAUSE, + NULL) < 0) + { + DEBUG_PRINT_ERROR("\n Error In Pause State"); + post_event(OMX_EventError,OMX_ErrorHardware,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_HIGH("send_command_proxy(): Executing-->Pause"); + bFlag = 0; + } + } + /* Requesting transition from Executing to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Executing to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is Pause */ + /***************************/ + else if(m_state == OMX_StatePause) + { + /* Requesting transition from Pause to Executing */ + if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_HIGH("Pause --> Executing"); + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_RESUME, + NULL) < 0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed"); + post_event(OMX_EventError,OMX_ErrorHardware,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); + DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Executing"); + post_event (NULL,VDEC_S_SUCCESS,\ + OMX_COMPONENT_GENERATE_RESUME_DONE); + bFlag = 0; + } + } + /* Requesting transition from Pause to Idle */ + else if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_HIGH("Pause --> Idle.."); + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + execute_omx_flush(OMX_ALL); + } + bFlag = 0; + } + /* Requesting transition from Pause to loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Pause to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is WaitForResources */ + /***************************/ + else if(m_state == OMX_StateWaitForResources) + { + /* Requesting transition from WaitForResources to Loaded */ + if(eState == OMX_StateLoaded) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_HIGH("send_command_proxy(): WaitForResources-->Loaded"); + } + /* Requesting transition from WaitForResources to WaitForResources */ + else if (eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorSameState, + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from WaitForResources to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + /* Requesting transition from WaitForResources to Loaded - + is NOT tested by Khronos TS */ + + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); + eRet = OMX_ErrorBadParameter; + } + } + /********************************/ + /* Current State is Invalid */ + /*******************************/ + else if(m_state == OMX_StateInvalid) + { + /* State Transition from Inavlid to any state */ + if(eState == (OMX_StateLoaded || OMX_StateWaitForResources + || OMX_StateIdle || OMX_StateExecuting + || OMX_StatePause || OMX_StateInvalid)) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); + post_event(OMX_EventError,OMX_ErrorInvalidState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + } + else if (cmd == OMX_CommandFlush) + { + DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued " + "with param1: %d", param1); + if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); + } + if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) + { + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + } + if (!sem_posted){ + sem_posted = 1; + DEBUG_PRINT_LOW("Set the Semaphore"); + sem_post (&m_cmd_lock); + execute_omx_flush(param1); + } + bFlag = 0; + } + else if ( cmd == OMX_CommandPortEnable) + { + DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued " + "with param1: %d", param1); + if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_inp_bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || allocate_input_done()) + { + post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + DEBUG_PRINT_HIGH("send_command_proxy(): Disabled-->Enabled Pending"); + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) + { + DEBUG_PRINT_HIGH("Enable output Port command recieved"); + m_out_bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || (allocate_output_done())) + { + post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + + } + else + { + DEBUG_PRINT_HIGH("send_command_proxy(): Disabled-->Enabled Pending"); + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + } + else if (cmd == OMX_CommandPortDisable) + { + DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued " + "with param1: %d", param1); + if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_inp_bEnabled = OMX_FALSE; + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_input_done()) + { + post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + } + execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); + } + + // Skip the event notification + bFlag = 0; + } + } + if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_out_bEnabled = OMX_FALSE; + DEBUG_PRINT_HIGH("Disable output Port command recieved"); + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_output_done()) + { + post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + if (!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + } + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); + execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); + } + // Skip the event notification + bFlag = 0; + + } + } + } + else + { + DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); + eRet = OMX_ErrorNotImplemented; + } + if(eRet == OMX_ErrorNone && bFlag) + { + post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); + } + if(!sem_posted) + { + sem_post(&m_cmd_lock); + } + + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ExecuteOmxFlush + +DESCRIPTION + Executes the OMX flush. + +PARAMETERS + flushtype - input flush(1)/output flush(0)/ both. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_vdec::execute_omx_flush(OMX_U32 flushType) +{ + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + enum vdec_bufferflush flush_dir; + bool bRet = false; + switch (flushType) + { + case OMX_CORE_INPUT_PORT_INDEX: + input_flush_progress = true; + flush_dir = VDEC_FLUSH_TYPE_INPUT; + break; + case OMX_CORE_OUTPUT_PORT_INDEX: + output_flush_progress = true; + flush_dir = VDEC_FLUSH_TYPE_OUTPUT; + break; + default: + input_flush_progress = true; + output_flush_progress = true; + flush_dir = VDEC_FLUSH_TYPE_ALL; + } + ioctl_msg.in = &flush_dir; + ioctl_msg.out = NULL; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_CMD_FLUSH, &ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", (int)flush_dir); + bRet = false; + } + return bRet; +} +/*========================================================================= +FUNCTION : execute_output_flush + +DESCRIPTION + Executes the OMX flush at OUTPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_vdec::execute_output_flush() +{ + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate FBD for all Buffers in the FTBq*/ + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_HIGH("Initiate Output Flush"); + while (m_ftb_q.m_size) + { + DEBUG_PRINT_HIGH("Buffer queue size %d pending buf cnt %d", + m_ftb_q.m_size,pending_output_buffers); + m_ftb_q.pop_entry(&p1,&p2,&ident); + DEBUG_PRINT_HIGH("ID(%x) P1(%x) P2(%x)", ident, p1, p2); + if(ident == m_fill_output_msg ) + { + m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + else if (ident == OMX_COMPONENT_GENERATE_FBD) + { + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + pthread_mutex_unlock(&m_lock); + output_flush_progress = false; + + if (arbitrary_bytes) + { + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } + DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); + return bRet; +} +/*========================================================================= +FUNCTION : execute_input_flush + +DESCRIPTION + Executes the OMX flush at INPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_vdec::execute_input_flush() +{ + unsigned i =0; + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate EBD for all Buffers in the ETBq*/ + DEBUG_PRINT_HIGH("Initiate Input Flush"); + + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_LOW("Check if the Queue is empty"); + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + + if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) + { + DEBUG_PRINT_HIGH("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_ETB) + { + pending_input_buffers++; + DEBUG_PRINT_HIGH("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", + (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if (ident == OMX_COMPONENT_GENERATE_EBD) + { + DEBUG_PRINT_HIGH("Flush Input OMX_COMPONENT_GENERATE_EBD %p", + (OMX_BUFFERHEADERTYPE *)p1); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + time_stamp_dts.flush_timestamp(); + /*Check if Heap Buffers are to be flushed*/ + if (arbitrary_bytes && !(codec_config_flag)) + { + DEBUG_PRINT_HIGH("Reset all the variables before flusing"); + h264_scratch.nFilledLen = 0; + nal_count = 0; + look_ahead_nal = false; + frame_count = 0; + h264_last_au_ts = LLONG_MAX; + h264_last_au_flags = 0; + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + DEBUG_PRINT_HIGH("Initialize parser"); + if (m_frame_parser.mutils) + { + m_frame_parser.mutils->initialize_frame_checking_environment(); + } + + while (m_input_pending_q.m_size) + { + m_input_pending_q.pop_entry(&p1,&p2,&ident); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); + } + + if (psource_frame) + { + m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); + psource_frame = NULL; + } + + if (pdest_frame) + { + pdest_frame->nFilledLen = 0; + m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); + pdest_frame = NULL; + } + m_frame_parser.flush(); + } + else if (codec_config_flag) + { + DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " + "is not sent to the driver yet"); + } + pthread_mutex_unlock(&m_lock); + input_flush_progress = false; + if (!arbitrary_bytes) + { + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } +#ifdef _ANDROID_ + if (m_debug_timestamp) + { + m_timestamp_list.reset_ts_list(); + } +#endif + DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); + return bRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::SendCommandEvent + +DESCRIPTION + Send the event to decoder pipe. This is needed to generate the callbacks + in decoder thread context. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_vdec::post_event(unsigned int p1, + unsigned int p2, + unsigned int id) +{ + bool bRet = false; + + + pthread_mutex_lock(&m_lock); + + if (id == m_fill_output_msg || + id == OMX_COMPONENT_GENERATE_FBD) + { + m_ftb_q.insert_entry(p1,p2,id); + } + else if (id == OMX_COMPONENT_GENERATE_ETB || + id == OMX_COMPONENT_GENERATE_EBD || + id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) + { + m_etb_q.insert_entry(p1,p2,id); + } + else + { + m_cmd_q.insert_entry(p1,p2,id); + } + + bRet = true; + DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this); + post_message(this, id); + + pthread_mutex_unlock(&m_lock); + + return bRet; +} +#ifdef MAX_RES_720P +OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 0) { + if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else + { + DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + return eRet; +} +#endif +#ifdef MAX_RES_1080P +OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNoMore; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 0) { + if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else + { + DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; + profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore\n"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + return eRet; +} +#endif + +/* ====================================================================== +FUNCTION + omx_vdec::GetParameter + +DESCRIPTION + OMX Get Parameter method implementation + +PARAMETERS + . + +RETURN VALUE + Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_INOUT OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + DEBUG_PRINT_LOW("get_parameter:"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("\n Get Param in Invalid paramData"); + return OMX_ErrorBadParameter; + } + switch(paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn = + (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + eRet = update_portdef(portDefn); + if (eRet == OMX_ErrorNone) + m_port_def = *portDefn; + DEBUG_PRINT_HIGH("Get_parameter: OMX_IndexParamPortDefinition: " + "nPortIndex (%d), nFrameWidth (%d), nFrameHeight (%d), " + "nStride (%d), nSliceHeight (%d), nBitrate (%d), xFramerate (0x%x), " + "nBufferSize (%d), nBufferCountMin (%d), nBufferCountActual (%d), " + "bBuffersContiguous (%d), nBufferAlignment (%d), " + "bEnabled (%d), bPopulated (%d), eCompressionFormat (0x%x), " + "eColorFormat (0x%x)" , (int)portDefn->nPortIndex, + (int)portDefn->format.video.nFrameWidth, (int)portDefn->format.video.nFrameHeight, + (int)portDefn->format.video.nStride, (int)portDefn->format.video.nSliceHeight, + (int)portDefn->format.video.nBitrate, (int)portDefn->format.video.xFramerate, + (int)portDefn->nBufferSize, (int)portDefn->nBufferCountMin, + (int)portDefn->nBufferCountActual, (int)portDefn->bBuffersContiguous, + (int)portDefn->nBufferAlignment, (int)portDefn->bEnabled, (int)portDefn->bPopulated, + (int)portDefn->format.video.eCompressionFormat, (int)portDefn->format.video.eColorFormat); + break; + } + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); + + portParamType->nVersion.nVersion = OMX_SPEC_VERSION; + portParamType->nSize = sizeof(portParamType); + portParamType->nPorts = 2; + portParamType->nStartPortNumber = 0; + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + portFmt->nVersion.nVersion = OMX_SPEC_VERSION; + portFmt->nSize = sizeof(portFmt); + + if (0 == portFmt->nPortIndex) + { + if (0 == portFmt->nIndex) + { + portFmt->eColorFormat = OMX_COLOR_FormatUnused; + portFmt->eCompressionFormat = eCompressionFormat; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ + " NoMore compression formats\n"); + eRet = OMX_ErrorNoMore; + } + } + else if (1 == portFmt->nPortIndex) + { + portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; + if(0 == portFmt->nIndex) + portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; + else if (1 == portFmt->nIndex) + { + portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ + " NoMore Color formats\n"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", + (int)portFmt->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_HIGH("Get_parameter: OMX_IndexParamVideoPortFormat: " + "nPortIndex (%d), nIndex (%d), eCompressionFormat (0x%x), " + "eColorFormat (0x%x), xFramerate (0x%x)", (int)portFmt->nPortIndex, + (int)portFmt->nIndex, (int)portFmt->eCompressionFormat, + (int)portFmt->eColorFormat, (int)portFmt->xFramerate); + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamAudioInit: + { + OMX_PORT_PARAM_TYPE *audioPortParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); + audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; + audioPortParamType->nSize = sizeof(audioPortParamType); + audioPortParamType->nPorts = 0; + audioPortParamType->nStartPortNumber = 0; + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamImageInit: + { + OMX_PORT_PARAM_TYPE *imagePortParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); + imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; + imagePortParamType->nSize = sizeof(imagePortParamType); + imagePortParamType->nPorts = 0; + imagePortParamType->nStartPortNumber = 0; + break; + + } + /*Component should support this port definition*/ + case OMX_IndexParamOtherInit: + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", + paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + break; + } + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + comp_role->nVersion.nVersion = OMX_SPEC_VERSION; + comp_role->nSize = sizeof(*comp_role); + + DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", + paramIndex); + strlcpy((char*)comp_role->cRole,(const char*)m_cRole, + OMX_MAX_STRINGNAME_SIZE); + break; + } + /* Added for parameter test */ + case OMX_IndexParamPriorityMgmt: + { + + OMX_PRIORITYMGMTTYPE *priorityMgmType = + (OMX_PRIORITYMGMTTYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); + priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; + priorityMgmType->nSize = sizeof(priorityMgmType); + + break; + } + /* Added for parameter test */ + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = + (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); + + bufferSupplierType->nSize = sizeof(bufferSupplierType); + bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; + if(0 == bufferSupplierType->nPortIndex) + bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; + else if (1 == bufferSupplierType->nPortIndex) + bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; + else + eRet = OMX_ErrorBadPortIndex; + + + break; + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoH263: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg4: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg2: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex); + OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = + (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; +#ifdef MAX_RES_720P + eRet = get_supported_profile_level_for_720p(profileLevelType); +#endif +#ifdef MAX_RES_1080P + eRet = get_supported_profile_level_for_1080p(profileLevelType); +#endif + break; + } +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: + { + DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage"); + GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; + if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { +#ifdef USE_ION +#if defined (MAX_RES_720P) + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_CAMERA_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); + DEBUG_PRINT_HIGH("ION:720P: nUsage 0x%x",nativeBuffersUsage->nUsage); +#else + if(secure_mode) { + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | + GRALLOC_USAGE_PRIVATE_UNCACHED); + DEBUG_PRINT_HIGH("ION:secure_mode: nUsage 0x%x",nativeBuffersUsage->nUsage); + } else { + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | + GRALLOC_USAGE_PRIVATE_IOMMU_HEAP); + DEBUG_PRINT_HIGH("ION:non_secure_mode: nUsage 0x%x",nativeBuffersUsage->nUsage); + } +#endif //(MAX_RES_720P) +#else // USE_ION +#if defined (MAX_RES_720P) || defined (MAX_RES_1080P_EBI) + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); + DEBUG_PRINT_HIGH("720P/1080P_EBI: nUsage 0x%x",nativeBuffersUsage->nUsage); +#elif MAX_RES_1080P + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_SMI_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); + DEBUG_PRINT_HIGH("1080P: nUsage 0x%x",nativeBuffersUsage->nUsage); +#endif +#endif // USE_ION + } else { + DEBUG_PRINT_ERROR("\n get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!"); + eRet = OMX_ErrorBadParameter; + } + } + break; +#endif + + default: + { + DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + } + + } + + DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)", + drv_ctx.video_resolution.frame_width, + drv_ctx.video_resolution.frame_height, + drv_ctx.video_resolution.stride, + drv_ctx.video_resolution.scan_lines); + + return eRet; +} + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) +{ + DEBUG_PRINT_LOW("Inside use_android_native_buffer"); + OMX_ERRORTYPE eRet = OMX_ErrorNone; + UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; + + if((params == NULL) || + (params->nativeBuffer == NULL) || + (params->nativeBuffer->handle == NULL) || + !m_enable_android_native_buffers) + return OMX_ErrorBadParameter; + m_use_android_native_buffers = OMX_TRUE; + sp nBuf = params->nativeBuffer; + private_handle_t *handle = (private_handle_t *)nBuf->handle; + + if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { + DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," + " expected %u, got %lu", + drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); + return OMX_ErrorBadParameter; + } + + if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port + OMX_U8 *buffer = NULL; + if(!secure_mode) { + buffer = (OMX_U8*)mmap(0, handle->size, + PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); + if(buffer == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); + return OMX_ErrorInsufficientResources; + } + } + eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); + } else { + eRet = OMX_ErrorBadParameter; + } + return eRet; +} +#endif +/* ====================================================================== +FUNCTION + omx_vdec::Setparameter + +DESCRIPTION + OMX Set Parameter method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_IN OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + if((m_state != OMX_StateLoaded) && + BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && + (m_out_bEnabled == OMX_TRUE) && + BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && + (m_inp_bEnabled == OMX_TRUE)) { + DEBUG_PRINT_ERROR("Set Param in Invalid State \n"); + return OMX_ErrorIncorrectStateOperation; + } + + switch(paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has + //been called. + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d", + (int)portDefn->format.video.nFrameHeight, + (int)portDefn->format.video.nFrameWidth); + if(OMX_DirOutput == portDefn->eDir) + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port"); + m_display_id = portDefn->format.video.pNativeWindow; + unsigned int buffer_size; + if (!client_buffers.get_buffer_req(buffer_size)) { + DEBUG_PRINT_ERROR("\n Error in getting buffer requirements"); + eRet = OMX_ErrorBadParameter; + } else { + if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && + portDefn->nBufferSize >= buffer_size) + { + drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; + drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; + eRet = set_buffer_req(&drv_ctx.op_buf); + if (eRet == OMX_ErrorNone) + m_port_def = *portDefn; + } + else + { + DEBUG_PRINT_HIGH("ERROR: OP Requirements(#%d: %u) Requested(#%d: %u)\n", + drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, + portDefn->nBufferCountActual, portDefn->nBufferSize); + eRet = OMX_ErrorBadParameter; + } + } + } + else if(OMX_DirInput == portDefn->eDir) + { + if((portDefn->format.video.xFramerate >> 16) > 0 && + (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) + { + // Frame rate only should be set if this is a "known value" or to + // activate ts prediction logic (arbitrary mode only) sending input + // timestamps with max value (LLONG_MAX). + DEBUG_PRINT_LOW("set_parameter: frame rate set by omx client : %d", + portDefn->format.video.xFramerate >> 16); + Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, + drv_ctx.frame_rate.fps_denominator); + if(!drv_ctx.frame_rate.fps_numerator) + { + DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); + drv_ctx.frame_rate.fps_numerator = 30; + } + if(drv_ctx.frame_rate.fps_denominator) + drv_ctx.frame_rate.fps_numerator = (int) + drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; + drv_ctx.frame_rate.fps_denominator = 1; + frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / + drv_ctx.frame_rate.fps_numerator; + ioctl_msg.in = &drv_ctx.frame_rate; + if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Setting frame rate to driver failed"); + } + DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", + frm_int, drv_ctx.frame_rate.fps_numerator / + (float)drv_ctx.frame_rate.fps_denominator); + } + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port"); + if(drv_ctx.video_resolution.frame_height != + portDefn->format.video.nFrameHeight || + drv_ctx.video_resolution.frame_width != + portDefn->format.video.nFrameWidth) + { + DEBUG_PRINT_LOW("SetParam IP: WxH(%d x %d)", + portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight); + if (portDefn->format.video.nFrameHeight != 0x0 && + portDefn->format.video.nFrameWidth != 0x0) + { + drv_ctx.video_resolution.frame_height = + drv_ctx.video_resolution.scan_lines = + portDefn->format.video.nFrameHeight; + drv_ctx.video_resolution.frame_width = + drv_ctx.video_resolution.stride = + portDefn->format.video.nFrameWidth; + ioctl_msg.in = &drv_ctx.video_resolution; + ioctl_msg.out = NULL; + if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICRES, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set Resolution failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + else + eRet = get_buffer_req(&drv_ctx.op_buf); + } + } + else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount + && portDefn->nBufferSize == (drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH)) + { + drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; + drv_ctx.ip_buf.buffer_size = portDefn->nBufferSize + DEVICE_SCRATCH; + eRet = set_buffer_req(&drv_ctx.ip_buf); + } + else + { + DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%d: %u)\n", + drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, + portDefn->nBufferCountActual, portDefn->nBufferSize); + eRet = OMX_ErrorBadParameter; + } + } + else if (portDefn->eDir == OMX_DirMax) + { + DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_HIGH("Set_parameter: OMX_IndexParamPortDefinition: " + "nPortIndex (%d), nFrameWidth (%d), nFrameHeight (%d), " + "nStride (%d), nSliceHeight (%d), nBitrate (%d), xFramerate (0x%x), " + "nBufferSize (%d), nBufferCountMin (%d), nBufferCountActual (%d), " + "bBuffersContiguous (%d), nBufferAlignment (%d), " + "bEnabled (%d), bPopulated (%d), eCompressionFormat (0x%x), " + "eColorFormat (0x%x)" , (int)portDefn->nPortIndex, + (int)portDefn->format.video.nFrameWidth, (int)portDefn->format.video.nFrameHeight, + (int)portDefn->format.video.nStride, (int)portDefn->format.video.nSliceHeight, + (int)portDefn->format.video.nBitrate, (int)portDefn->format.video.xFramerate, + (int)portDefn->nBufferSize, (int)portDefn->nBufferCountMin, + (int)portDefn->nBufferCountActual, (int)portDefn->bBuffersContiguous, + (int)portDefn->nBufferAlignment, (int)portDefn->bEnabled, (int)portDefn->bPopulated, + (int)portDefn->format.video.eCompressionFormat, (int)portDefn->format.video.eColorFormat); + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + if(1 == portFmt->nPortIndex) + { + enum vdec_output_fromat op_format; + if(portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) + op_format = VDEC_YUV_FORMAT_NV12; + else if(portFmt->eColorFormat == + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka || + portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) + op_format = VDEC_YUV_FORMAT_TILE_4x2; + else + eRet = OMX_ErrorBadParameter; + + if(eRet == OMX_ErrorNone && drv_ctx.output_format != op_format) + { + /*Set the output format*/ + drv_ctx.output_format = op_format; + ioctl_msg.in = &drv_ctx.output_format; + ioctl_msg.out = NULL; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_OUTPUT_FORMAT, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set output format failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + else { + eRet = get_buffer_req(&drv_ctx.op_buf); + } + } + if (eRet == OMX_ErrorNone){ + if (!client_buffers.set_color_format(portFmt->eColorFormat)) { + DEBUG_PRINT_ERROR("\n Set color format failed"); + eRet = OMX_ErrorBadParameter; + } + } + } + DEBUG_PRINT_HIGH("Set_parameter: OMX_IndexParamVideoPortFormat: " + "nPortIndex (%d), nIndex (%d), eCompressionFormat (0x%x), " + "eColorFormat (0x%x), xFramerate (0x%x)", (int)portFmt->nPortIndex, + (int)portFmt->nIndex, (int)portFmt->eCompressionFormat, + (int)portFmt->eColorFormat, (int)portFmt->xFramerate); + } + break; + + case OMX_QcomIndexPortDefn: + { + OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = + (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d", + portFmt->nFramePackingFormat); + + /* Input port */ + if (portFmt->nPortIndex == 0) + { + if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) + { + if(secure_mode) { + arbitrary_bytes = false; + DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); + eRet = OMX_ErrorUnsupportedSetting; + } else { + arbitrary_bytes = true; + DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes enabled"); + } + } + else if (portFmt->nFramePackingFormat == + OMX_QCOM_FramePacking_OnlyOneCompleteFrame) + { + arbitrary_bytes = false; + DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes disabled"); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n", + portFmt->nFramePackingFormat); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port"); + if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && + portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && + portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) + { + m_out_mem_region_smi = OMX_TRUE; + if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: set use_output_pmem"); + m_use_output_pmem = OMX_TRUE; + } + } + } + } + break; + + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s", + comp_role->cRole); + + if((m_state == OMX_StateLoaded)&& + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("Set Parameter called in valid state"); + } + else + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } +#ifdef MAX_RES_1080P + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) + ) +#else + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) +#endif + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind); + eRet = OMX_ErrorInvalidComponentName; + } + break; + } + + case OMX_IndexParamPriorityMgmt: + { + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", + priorityMgmtype->nGroupID); + + DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", + priorityMgmtype->nGroupPriority); + + m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; + m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; + + break; + } + + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", + bufferSupplierType->eBufferSupplier); + if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) + m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; + + else + + eRet = OMX_ErrorBadPortIndex; + + break; + + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoH263: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg4: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg2: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n", + paramIndex); + break; + } + case OMX_QcomIndexParamVideoDecoderPictureOrder: + { + QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = + (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; + enum vdec_output_order pic_order = VDEC_ORDER_DISPLAY; + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n", + pictureOrder->eOutputPictureOrder); + if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) + pic_order = VDEC_ORDER_DISPLAY; + else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){ + pic_order = VDEC_ORDER_DECODE; + time_stamp_dts.set_timestamp_reorder_mode(false); + } + else + eRet = OMX_ErrorBadParameter; +#ifdef MAX_RES_720P + if (drv_ctx.idr_only_decoding) + { + if (pictureOrder->eOutputPictureOrder != QOMX_VIDEO_DECODE_ORDER) + { + DEBUG_PRINT_HIGH("only decode order is supported for thumbnail mode"); + eRet = OMX_ErrorBadParameter; + } + } +#endif + if (eRet == OMX_ErrorNone && pic_order != drv_ctx.picture_order) + { + drv_ctx.picture_order = pic_order; + ioctl_msg.in = &drv_ctx.picture_order; + ioctl_msg.out = NULL; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set picture order failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + } + break; + } + case OMX_QcomIndexParamConcealMBMapExtraData: + { + eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + } + break; + case OMX_QcomIndexParamFrameInfoExtraData: + { + eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + } + break; + case OMX_QcomIndexParamInterlaceExtraData: + { + eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + } + break; + case OMX_QcomIndexParamH264TimeInfo: + { + eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + } + break; + case OMX_QcomIndexParamVideoDivx: + { +#ifdef MAX_RES_720P + QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; + if((divXType) && (divXType->eFormat == QOMX_VIDEO_DIVXFormat311)) { + DEBUG_PRINT_HIGH("set_parameter: DivX 3.11 not supported in 7x30 core."); + eRet = OMX_ErrorUnsupportedSetting; + } +#endif + } + break; + case OMX_QcomIndexPlatformPvt: + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port"); + OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; + if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) + { + DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); + eRet = OMX_ErrorUnsupportedSetting; + } + else + { + m_out_pvt_entry_pmem = OMX_TRUE; + if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: use output pmem set"); + m_use_output_pmem = OMX_TRUE; + } + } + + } + break; + case OMX_QcomIndexParamVideoSyncFrameDecodingMode: + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); + DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); + drv_ctx.idr_only_decoding = 1; + int rc = ioctl(drv_ctx.video_driver_fd, + VDEC_IOCTL_SET_IDR_ONLY_DECODING); + if(rc < 0) { + DEBUG_PRINT_ERROR("Failed to set IDR only decoding on driver."); + eRet = OMX_ErrorHardware; + } +#ifdef MAX_RES_720P + if (eRet == OMX_ErrorNone) + { + DEBUG_PRINT_HIGH("set decode order for thumbnail mode"); + drv_ctx.picture_order = VDEC_ORDER_DECODE; + ioctl_msg.in = &drv_ctx.picture_order; + ioctl_msg.out = NULL; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set picture order failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + } +#endif + } + break; +#ifdef MAX_RES_1080P + case OMX_QcomIndexParamIndexExtraDataType: + { + if(!secure_mode) { + QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; + if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && + (extradataIndexType->bEnabled == OMX_TRUE) && + (extradataIndexType->nPortIndex == 1)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming"); + eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, extradataIndexType->bEnabled); + // Set smooth streaming parameter + int rc = ioctl(drv_ctx.video_driver_fd, + VDEC_IOCTL_SET_CONT_ON_RECONFIG); + if(rc < 0) { + DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); + eRet = OMX_ErrorHardware; + } + } + } + } + break; + + case OMX_QcomIndexParamEnableSmoothStreaming: + { + + int rc = ioctl(drv_ctx.video_driver_fd, + VDEC_IOCTL_SET_CONT_ON_RECONFIG); + if(rc < 0) { + DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); + eRet = OMX_ErrorHardware; + } + } + break; +#endif +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + /* Need to allow following two set_parameters even in Idle + * state. This is ANDROID architecture which is not in sync + * with openmax standard. */ + case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: + { + EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; + if(enableNativeBuffers) { + m_enable_android_native_buffers = enableNativeBuffers->enable; + } + } + break; + case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: + { + eRet = use_android_native_buffer(hComp, paramData); + } + break; +#endif + case OMX_QcomIndexParamEnableTimeStampReorder: + { + QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; + if (drv_ctx.picture_order == QOMX_VIDEO_DISPLAY_ORDER) { + if (reorder->bEnable == OMX_TRUE) { + frm_int =0; + time_stamp_dts.set_timestamp_reorder_mode(true); + } + else + time_stamp_dts.set_timestamp_reorder_mode(false); + } else { + time_stamp_dts.set_timestamp_reorder_mode(false); + if (reorder->bEnable == OMX_TRUE) + { + eRet = OMX_ErrorUnsupportedSetting; + } + } + } + break; + case OMX_QcomIndexEnableExtnUserData: + { + eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + } + break; + default: + { + DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); + eRet = OMX_ErrorUnsupportedIndex; + } + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetConfig + +DESCRIPTION + OMX Get Config Method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_INOUT OMX_PTR configData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + if (m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + switch (configIndex) + { + case OMX_QcomIndexConfigInterlaced: + { + OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = + (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; + if (configFmt->nPortIndex == 1) + { + if (configFmt->nIndex == 0) + { + configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; + } + else if (configFmt->nIndex == 1) + { + configFmt->eInterlaceType = + OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; + } + else if (configFmt->nIndex == 2) + { + configFmt->eInterlaceType = + OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; + } + else + { + DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" + " NoMore Interlaced formats\n"); + eRet = OMX_ErrorNoMore; + } + + } + else + { + DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", + (int)configFmt->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + case OMX_QcomIndexQueryNumberOfVideoDecInstance: + { + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = + (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; + ioctl_msg.out = (void*)&decoderinstances->nNumOfInstances; + (void)(ioctl(drv_ctx.video_driver_fd, + VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg)); + break; + } + case OMX_QcomIndexConfigVideoFramePackingArrangement: + { + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = + (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; + h264_parser->get_frame_pack_data(configFmt); + } + else + { + DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); + } + break; + } + case OMX_QcomIndexParamFrameInfoExtraData: + { + OMX_QCOM_EXTRADATA_FRAMEINFO *extradata = + (OMX_QCOM_EXTRADATA_FRAMEINFO *) configData; + + if(m_extradata == NULL){ + DEBUG_PRINT_LOW("get_config: m_extradata not set. " + "Aspect Ratio information missing!!"); + } + else { + extradata->aspectRatio.aspectRatioX = + m_extradata->aspectRatio.aspectRatioX; + extradata->aspectRatio.aspectRatioY = + m_extradata->aspectRatio.aspectRatioY; + } + break; + } + + default: + { + DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); + eRet = OMX_ErrorBadParameter; + } + + } + + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SetConfig + +DESCRIPTION + OMX Set Config method implementation + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_IN OMX_PTR configData) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_VIDEO_CONFIG_NALSIZE *pNal; + + DEBUG_PRINT_LOW("Set Config Called"); + + if (m_state == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n"); + return ret; + } + + if (configIndex == OMX_IndexVendorVideoExtraData) + { + OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; + DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called"); + if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) + { + DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC"); + OMX_U32 extra_size; + // Parsing done here for the AVC atom is definitely not generic + // Currently this piece of code is working, but certainly + // not tested with all .mp4 files. + // Incase of failure, we might need to revisit this + // for a generic piece of code. + + // Retrieve size of NAL length field + // byte #4 contains the size of NAL lenght field + nal_length = (config->pData[4] & 0x03) + 1; + + extra_size = 0; + if (nal_length > 2) + { + /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ + extra_size = (nal_length - 2) * 2; + } + + // SPS starts from byte #6 + OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); + OMX_U8 *pDestBuf; + m_vendor_config.nPortIndex = config->nPortIndex; + + // minus 6 --> SPS starts from byte #6 + // minus 1 --> picture param set byte to be ignored from avcatom + m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; + m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); + OMX_U32 len; + OMX_U8 index = 0; + // case where SPS+PPS is sent as part of set_config + pDestBuf = m_vendor_config.pData; + + DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]", + m_vendor_config.nPortIndex, + m_vendor_config.nDataSize, + m_vendor_config.pData); + while (index < 2) + { + uint8 *psize; + len = *pSrcBuf; + len = len << 8; + len |= *(pSrcBuf + 1); + psize = (uint8 *) & len; + memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); + for (int i = 0; i < nal_length; i++) + { + pDestBuf[i] = psize[nal_length - 1 - i]; + } + //memcpy(pDestBuf,pSrcBuf,(len+2)); + pDestBuf += len + nal_length; + pSrcBuf += len + 2; + index++; + pSrcBuf++; // skip picture param set + len = 0; + } + } + else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || + !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) + { + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); + memcpy(m_vendor_config.pData, config->pData,config->nDataSize); + } + else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) + { + if(m_vendor_config.pData) + { + free(m_vendor_config.pData); + m_vendor_config.pData = NULL; + m_vendor_config.nDataSize = 0; + } + + if (((*((OMX_U32 *) config->pData)) & + VC1_SP_MP_START_CODE_MASK) == + VC1_SP_MP_START_CODE) + { + DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = + (OMX_U8 *) malloc(config->nDataSize); + memcpy(m_vendor_config.pData, config->pData, + config->nDataSize); + m_vc1_profile = VC1_SP_MP_RCV; + } + else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) + { + DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = + (OMX_U8 *) malloc((config->nDataSize)); + memcpy(m_vendor_config.pData, config->pData, + config->nDataSize); + m_vc1_profile = VC1_AP; + } + else if ((config->nDataSize == VC1_STRUCT_C_LEN)) + { + DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); + memcpy(m_vendor_config.pData,config->pData,config->nDataSize); + m_vc1_profile = VC1_SP_MP_RCV; + } + else + { + DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); + } + } + return ret; + } + else if (configIndex == OMX_IndexConfigVideoNalSize) + { + + pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); + nal_length = pNal->nNaluBytes; + m_frame_parser.init_nal_length(nal_length); + DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d",nal_length); + return ret; + } + + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetExtensionIndex + +DESCRIPTION + OMX GetExtensionIndex method implementaion. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_STRING paramName, + OMX_OUT OMX_INDEXTYPE* indexType) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); + return OMX_ErrorInvalidState; + } + else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; + } +#ifdef MAX_RES_1080P + else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) + { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; + } +#endif +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; + } + else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; + } + else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { + DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName); + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; + } + else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; + } +#endif + else { + DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName); + return OMX_ErrorNotImplemented; + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetState + +DESCRIPTION + Returns the state information back to the caller. + +PARAMETERS + . + +RETURN VALUE + Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STATETYPE* state) +{ + *state = m_state; + DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentTunnelRequest + +DESCRIPTION + OMX Component Tunnel Request method implementation. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_HANDLETYPE peerComponent, + OMX_IN OMX_U32 peerPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) +{ + DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::UseOutputBuffer + +DESCRIPTION + Helper function for Use buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + struct vdec_setbuffer_cmd setbuffers; + OMX_PTR privateAppData = NULL; +#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) + private_handle_t *handle = NULL; +#endif + OMX_U8 *buff = buffer; + + if (!m_out_mem_ptr) { + DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); + eRet = allocate_output_headers(); + +#ifdef MAX_RES_1080P + if(secure_mode) + { + eRet = vdec_alloc_meta_buffers(); + if (eRet) { + DEBUG_PRINT_ERROR("ERROR in allocating meta buffers\n"); + return OMX_ErrorInsufficientResources; + } + } + + if(drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + //allocate H264_mv_buffer + eRet = vdec_alloc_h264_mv(); + if (eRet) { + DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n"); + return OMX_ErrorInsufficientResources; + } + } +#endif + + } + + if (eRet == OMX_ErrorNone) { + for(i=0; i< drv_ctx.op_buf.actualcount; i++) { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + break; + } + } + } + + if(i >= drv_ctx.op_buf.actualcount) { + eRet = OMX_ErrorInsufficientResources; + } + + if (eRet == OMX_ErrorNone) { +#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) + if(m_enable_android_native_buffers) { + if (m_use_android_native_buffers) { + UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; + sp nBuf = params->nativeBuffer; + handle = (private_handle_t *)nBuf->handle; + privateAppData = params->pAppPrivate; + } else { + handle = (private_handle_t *)buff; + privateAppData = appData; + } + + if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { + DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," + " expected %u, got %lu", + drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); + return OMX_ErrorBadParameter; + } + + if (!m_use_android_native_buffers) { + if (!secure_mode) { + buff = (OMX_U8*)mmap(0, handle->size, + PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); + if (buff == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); + return OMX_ErrorInsufficientResources; + } + } + } + +#if defined(_ANDROID_ICS_) + native_buffer[i].nativehandle = handle; +#endif + if(!handle) { + DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); + return OMX_ErrorBadParameter; + } + drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; + drv_ctx.ptr_outputbuffer[i].offset = 0; + drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; + drv_ctx.ptr_outputbuffer[i].mmaped_size = + drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; +#if defined(_ANDROID_ICS_) + if (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) { + int enable = 1; + setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable); + } +#endif + } else +#endif + + if (!ouput_egl_buffers && !m_use_output_pmem) { +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( + drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, + &drv_ctx.op_buf_ion_info[i].ion_alloc_data, + &drv_ctx.op_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED); + if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; +#else + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + open (MEM_DEVICE,O_RDWR); + + if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { + return OMX_ErrorInsufficientResources; + } + + if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) + { + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + open (MEM_DEVICE,O_RDWR); + if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, + drv_ctx.op_buf.buffer_size, + drv_ctx.op_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(drv_ctx.ptr_outputbuffer[i].pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if(!secure_mode) { + drv_ctx.ptr_outputbuffer[i].bufferaddr = + (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, + PROT_READ|PROT_WRITE, MAP_SHARED, + drv_ctx.ptr_outputbuffer[i].pmem_fd,0); + if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { + close(drv_ctx.ptr_outputbuffer[i].pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[i]); +#endif + return OMX_ErrorInsufficientResources; + } + } + drv_ctx.ptr_outputbuffer[i].offset = 0; + privateAppData = appData; + } + else { + + DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); + + if (!appData || !bytes ) + { + DEBUG_PRINT_ERROR("\n Invalid appData or bytes"); + return OMX_ErrorBadParameter; + } + + if(!secure_mode && !buffer) + { + DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case"); + return OMX_ErrorBadParameter; + } + + + OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; + pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; + if (!pmem_list->entryList || !pmem_list->entryList->entry || + !pmem_list->nEntries || + pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { + DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer"); + return OMX_ErrorBadParameter; + } + pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + pmem_list->entryList->entry; + DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x", + pmem_info->pmem_fd); + drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; + drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; + drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; + drv_ctx.ptr_outputbuffer[i].mmaped_size = + drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; + privateAppData = appData; + } + m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; + m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; + + *bufferHdr = (m_out_mem_ptr + i ); + if(secure_mode) + drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; + setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], + sizeof (vdec_bufferpayload)); + + ioctl_msg.in = &setbuffers; + ioctl_msg.out = NULL; + + DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %x, pmem_fd=%0x%x", i, + drv_ctx.ptr_outputbuffer[i],drv_ctx.ptr_outputbuffer[i].pmem_fd ); + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, + &ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set output buffer failed"); + return OMX_ErrorInsufficientResources; + } + // found an empty buffer at i + (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; + if (m_enable_android_native_buffers) { + DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); + (*bufferHdr)->pBuffer = (OMX_U8 *)handle; + } else { + (*bufferHdr)->pBuffer = buff; + } + (*bufferHdr)->pAppPrivate = privateAppData; + BITMASK_SET(&m_out_bm_count,i); + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::use_input_heap_buffers + +DESCRIPTION + OMX Use Buffer Heap allocation method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer); + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!m_inp_heap_ptr) + m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), + drv_ctx.ip_buf.actualcount); + if(!m_phdr_pmem_ptr) + m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) + calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), + drv_ctx.ip_buf.actualcount); + if(!m_inp_heap_ptr || !m_phdr_pmem_ptr) + { + DEBUG_PRINT_ERROR("Insufficent memory"); + eRet = OMX_ErrorInsufficientResources; + } + else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) + { + input_use_buffer = true; + memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); + m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; + m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; + m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; + m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; + m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; + *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; + eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); + DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); + if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], NULL, NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); + return OMX_ErrorInsufficientResources; + } + m_in_alloc_cnt++; + } + else + { + DEBUG_PRINT_ERROR("All i/p buffers have been set!"); + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::UseBuffer + +DESCRIPTION + OMX Use Buffer method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE error = OMX_ErrorNone; + struct vdec_setbuffer_cmd setbuffers; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + + if (bufferHdr == NULL || bytes == 0) + { + DEBUG_PRINT_ERROR("bad param 0x%p %ld",bufferHdr, bytes); + return OMX_ErrorBadParameter; + } + + if(!secure_mode && buffer == NULL) { + DEBUG_PRINT_ERROR("bad param 0x%p",buffer); + return OMX_ErrorBadParameter; + } + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(port == OMX_CORE_INPUT_PORT_INDEX) + error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested + else + { + DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); + error = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error); + if(error == OMX_ErrorNone) + { + if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && + BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && + BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + return error; +} + +OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, + OMX_BUFFERHEADERTYPE *pmem_bufferHdr) +{ + if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) + { + if(m_inp_heap_ptr[bufferindex].pBuffer) + free(m_inp_heap_ptr[bufferindex].pBuffer); + m_inp_heap_ptr[bufferindex].pBuffer = NULL; + } + if (pmem_bufferHdr) + free_input_buffer(pmem_bufferHdr); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + if (bufferHdr == NULL || m_inp_mem_ptr == NULL) + { + return OMX_ErrorBadParameter; + } + + index = bufferHdr - m_inp_mem_ptr; + DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); + + if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) + { + DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); + if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) + { + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + struct vdec_setbuffer_cmd setbuffers; + setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], + sizeof (vdec_bufferpayload)); + ioctl_msg.in = &setbuffers; + ioctl_msg.out = NULL; + int ioctl_r = ioctl (drv_ctx.video_driver_fd, + VDEC_IOCTL_FREE_BUFFER, &ioctl_msg); + if (ioctl_r < 0) + { + DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r); + } + if (!secure_mode) { + DEBUG_PRINT_LOW("unmap the input buffer fd=%d", + drv_ctx.ptr_inputbuffer[index].pmem_fd); + DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %d", + drv_ctx.ptr_inputbuffer[index].mmaped_size, + drv_ctx.ptr_inputbuffer[index].bufferaddr); + munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, + drv_ctx.ptr_inputbuffer[index].mmaped_size); + } + close (drv_ctx.ptr_inputbuffer[index].pmem_fd); + drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; + if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) + { + free(m_desc_buffer_ptr[index].buf_addr); + m_desc_buffer_ptr[index].buf_addr = NULL; + m_desc_buffer_ptr[index].desc_data_size = 0; + } +#ifdef USE_ION + free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); +#endif + } + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + + if (bufferHdr == NULL || m_out_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("\nfree_output_buffer ERROR"); + return OMX_ErrorBadParameter; + } + + index = bufferHdr - m_out_mem_ptr; + DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index); + + if (index < drv_ctx.op_buf.actualcount + && drv_ctx.ptr_outputbuffer) + { + DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %x", index, + drv_ctx.ptr_outputbuffer[index].bufferaddr); + + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + struct vdec_setbuffer_cmd setbuffers; + setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], + sizeof (vdec_bufferpayload)); + ioctl_msg.in = &setbuffers; + ioctl_msg.out = NULL; + DEBUG_PRINT_LOW("Release the Output Buffer"); + if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_BUFFER, + &ioctl_msg) < 0) + DEBUG_PRINT_ERROR("\n Release output buffer failed in VCD"); + +#ifdef _ANDROID_ + if(m_enable_android_native_buffers) { + if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { + if(!secure_mode) { + munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, + drv_ctx.ptr_outputbuffer[index].mmaped_size); + } + } + drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; + } else { +#endif + if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) + { + if(!secure_mode) { + DEBUG_PRINT_LOW("unmap the output buffer fd = %d", + drv_ctx.ptr_outputbuffer[index].pmem_fd); + DEBUG_PRINT_LOW("unmap the ouput buffer size=%d address = %d", + drv_ctx.ptr_outputbuffer[index].mmaped_size, + drv_ctx.ptr_outputbuffer[index].bufferaddr); + munmap (drv_ctx.ptr_outputbuffer[index].bufferaddr, + drv_ctx.ptr_outputbuffer[index].mmaped_size); + } + close (drv_ctx.ptr_outputbuffer[index].pmem_fd); + drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[index]); +#endif +#ifdef _ANDROID_ + m_heap_ptr[index].video_heap_ptr = NULL; + m_heap_count = m_heap_count - 1; + if (m_heap_count == 0) + { + free(m_heap_ptr); + m_heap_ptr = NULL; + } +#endif // _ANDROID_ + } +#ifdef _ANDROID_ + } +#endif + } +#ifdef MAX_RES_1080P + if(secure_mode) + { + vdec_dealloc_meta_buffers(); + } + if(drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + vdec_dealloc_h264_mv(); + } +#endif + + return OMX_ErrorNone; + +} + +OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes) +{ + OMX_BUFFERHEADERTYPE *input = NULL; + unsigned char *buf_addr = NULL; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned i = 0; + + /* Sanity Check*/ + if (bufferHdr == NULL) + { + return OMX_ErrorBadParameter; + } + + if (m_inp_heap_ptr == NULL) + { + m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), + drv_ctx.ip_buf.actualcount); + m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), + drv_ctx.ip_buf.actualcount); + + if (m_inp_heap_ptr == NULL) + { + DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + } + + /*Find a Free index*/ + for(i=0; i< drv_ctx.ip_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) + { + DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); + break; + } + } + + if (i < drv_ctx.ip_buf.actualcount) + { + buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); + + if (buf_addr == NULL) + { + return OMX_ErrorInsufficientResources; + } + + *bufferHdr = (m_inp_heap_ptr + i); + input = *bufferHdr; + BITMASK_SET(&m_heap_inp_bm_count,i); + + input->pBuffer = (OMX_U8 *)buf_addr; + input->nSize = sizeof(OMX_BUFFERHEADERTYPE); + input->nVersion.nVersion = OMX_SPEC_VERSION; + input->nAllocLen = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; + input->pAppPrivate = appData; + input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; + DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr ); + eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); + DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] ); + /*Add the Buffers to freeq*/ + if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); + return OMX_ErrorInsufficientResources; + } + } + else + { + return OMX_ErrorBadParameter; + } + + return eRet; + +} + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateInputBuffer + +DESCRIPTION + Helper function for allocate buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_input_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct vdec_setbuffer_cmd setbuffers; + OMX_BUFFERHEADERTYPE *input = NULL; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + unsigned i = 0; + unsigned char *buf_addr = NULL; + int pmem_fd = -1; + + if((bytes + DEVICE_SCRATCH) != drv_ctx.ip_buf.buffer_size) + { + DEBUG_PRINT_LOW("Requested Size is wrong %d epected is %d", + bytes, drv_ctx.ip_buf.buffer_size); + //return OMX_ErrorBadParameter; + } + + if(!m_inp_mem_ptr) + { + DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)", + drv_ctx.ip_buf.actualcount, + drv_ctx.ip_buf.buffer_size); + + m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); + + if (m_inp_mem_ptr == NULL) + { + return OMX_ErrorInsufficientResources; + } + + drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ + calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); + + if (drv_ctx.ptr_inputbuffer == NULL) + { + return OMX_ErrorInsufficientResources; + } +#ifdef USE_ION + drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ + calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); + + if (drv_ctx.ip_buf_ion_info == NULL) + { + return OMX_ErrorInsufficientResources; + } +#endif + + for (i=0; i < drv_ctx.ip_buf.actualcount; i++) + { + drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; +#ifdef USE_ION + drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; +#endif + } + } + + for(i=0; i< drv_ctx.ip_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_inp_bm_count,i)) + { + DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); + break; + } + } + + if(i < drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_LOW("Allocate input Buffer"); + +#ifdef USE_ION + drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( + drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, + &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, + &drv_ctx.ip_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED); + if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; +#else + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); + return OMX_ErrorInsufficientResources; + } + + if (pmem_fd == 0) + { + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, + drv_ctx.ip_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if (!secure_mode) { + buf_addr = (unsigned char *)mmap(NULL, + drv_ctx.ip_buf.buffer_size, + PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); + + if (buf_addr == MAP_FAILED) + { + close(pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); +#endif + DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); + return OMX_ErrorInsufficientResources; + } + } + *bufferHdr = (m_inp_mem_ptr + i); + if (secure_mode) + drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; + else + drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; + drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; + drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; + drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; + drv_ctx.ptr_inputbuffer [i].offset = 0; + + setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer [i], + sizeof (vdec_bufferpayload)); + ioctl_msg.in = &setbuffers; + ioctl_msg.out = NULL; + + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, + &ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set Buffers Failed"); + return OMX_ErrorInsufficientResources; + } + + input = *bufferHdr; + BITMASK_SET(&m_inp_bm_count,i); + DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr); + if (secure_mode) + input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; + else + input->pBuffer = (OMX_U8 *)buf_addr; + input->nSize = sizeof(OMX_BUFFERHEADERTYPE); + input->nVersion.nVersion = OMX_SPEC_VERSION; + input->nAllocLen = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; + input->pAppPrivate = appData; + input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; + input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; + + if (drv_ctx.disable_dmx) + { + eRet = allocate_desc_buffer(i); + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateOutputBuffer + +DESCRIPTION + Helper fn for AllocateBuffer in the output pin + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything went well. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + struct vdec_setbuffer_cmd setbuffers; +#ifdef USE_ION + int ion_device_fd =-1; + struct ion_allocation_data ion_alloc_data; + struct ion_fd_data fd_ion_data; +#endif + + int nBufHdrSize = 0; + int nPlatformEntrySize = 0; + int nPlatformListSize = 0; + int nPMEMInfoSize = 0; + int pmem_fd = -1; + unsigned char *pmem_baseaddress = NULL; + + OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; + + if (!m_out_mem_ptr) + { + DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)", + drv_ctx.op_buf.actualcount, + drv_ctx.op_buf.buffer_size); + + DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)", + drv_ctx.op_buf.actualcount); + + nBufHdrSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_BUFFERHEADERTYPE); + + nPMEMInfoSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); + nPlatformListSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); + nPlatformEntrySize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); + + DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize, + sizeof(OMX_BUFFERHEADERTYPE), + nPMEMInfoSize, + nPlatformListSize); + DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize, + drv_ctx.op_buf.actualcount); + + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + // Alloc mem for platform specific info + char *pPtr=NULL; + pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + + nPMEMInfoSize,1); + drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ + calloc (sizeof(struct vdec_bufferpayload), + drv_ctx.op_buf.actualcount); + drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ + calloc (sizeof (struct vdec_output_frameinfo), + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ + calloc (sizeof(struct vdec_ion), + drv_ctx.op_buf.actualcount); +#endif +#ifdef _ANDROID_ + m_heap_ptr = (struct vidc_heap *)\ + calloc (sizeof(struct vidc_heap), + drv_ctx.op_buf.actualcount); +#endif + + if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer + && drv_ctx.ptr_respbuffer +#ifdef _ANDROID_ + && m_heap_ptr +#endif + ) + { + drv_ctx.ptr_outputbuffer[0].mmaped_size = + (drv_ctx.op_buf.buffer_size * + drv_ctx.op_buf.actualcount); + bufHdr = m_out_mem_ptr; + m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); + m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) + (((char *) m_platform_list) + nPlatformListSize); + m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + (((char *) m_platform_entry) + nPlatformEntrySize); + pPlatformList = m_platform_list; + pPlatformEntry = m_platform_entry; + pPMEMInfo = m_pmem_info; + + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); + + // Settting the entire storage nicely + DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry); + DEBUG_PRINT_LOW("Pmem Info = %p",pPMEMInfo); + for(i=0; i < drv_ctx.op_buf.actualcount ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = 0; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = NULL; + bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + // Platform specific PMEM Information + // Initialize the Platform Entry + //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i); + pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pPlatformEntry->entry = pPMEMInfo; + // Initialize the Platform List + pPlatformList->nEntries = 1; + pPlatformList->entryList = pPlatformEntry; + // Keep pBuffer NULL till vdec is opened + bufHdr->pBuffer = NULL; + + pPMEMInfo->offset = 0; + pPMEMInfo->pmem_fd = 0; + bufHdr->pPlatformPrivate = pPlatformList; + drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; +#endif + /*Create a mapping between buffers*/ + bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; + drv_ctx.ptr_respbuffer[i].client_data = (void *)\ + &drv_ctx.ptr_outputbuffer[i]; +#ifdef _ANDROID_ + m_heap_ptr[i].video_heap_ptr = NULL; +#endif + // Move the buffer and buffer header pointers + bufHdr++; + pPMEMInfo++; + pPlatformEntry++; + pPlatformList++; + } +#ifdef MAX_RES_1080P + if(eRet == OMX_ErrorNone && secure_mode) + { + eRet = vdec_alloc_meta_buffers(); + if (eRet) { + DEBUG_PRINT_ERROR("ERROR in allocating meta buffers\n"); + return OMX_ErrorInsufficientResources; + } + } + + if(eRet == OMX_ErrorNone && drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + //Allocate the h264_mv_buffer + eRet = vdec_alloc_h264_mv(); + if(eRet) { + DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n"); + return OMX_ErrorInsufficientResources; + } + } +#endif + } + else + { + DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ + m_out_mem_ptr, pPtr); + if(m_out_mem_ptr) + { + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(pPtr) + { + free(pPtr); + pPtr = NULL; + } + if(drv_ctx.ptr_outputbuffer) + { + free(drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } + if(drv_ctx.ptr_respbuffer) + { + free(drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif + eRet = OMX_ErrorInsufficientResources; + } + } + + for (i=0; i< drv_ctx.op_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + DEBUG_PRINT_LOW("Found a Free Output Buffer Index %d",i); + break; + } + } + + if (i < drv_ctx.op_buf.actualcount) + { + DEBUG_PRINT_LOW("Allocate Output Buffer"); + +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( + drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, + &drv_ctx.op_buf_ion_info[i].ion_alloc_data, + &drv_ctx.op_buf_ion_info[i].fd_ion_data, ION_FLAG_CACHED); + if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + pmem_fd = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; +#else + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", + drv_ctx.op_buf.buffer_size); + return OMX_ErrorInsufficientResources; + } + + if (pmem_fd == 0) + { + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", + drv_ctx.op_buf.buffer_size); + return OMX_ErrorInsufficientResources; + } + } + + if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size, + drv_ctx.op_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if (!secure_mode) { + pmem_baseaddress = (unsigned char *)mmap(NULL, + drv_ctx.op_buf.buffer_size, + PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); + + if (pmem_baseaddress == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\n MMAP failed for Size %d", + drv_ctx.op_buf.buffer_size); + close(pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[i]); +#endif + return OMX_ErrorInsufficientResources; + } + } + + *bufferHdr = (m_out_mem_ptr + i); + if (secure_mode) + drv_ctx.ptr_outputbuffer [i].bufferaddr = *bufferHdr; + else + drv_ctx.ptr_outputbuffer [i].bufferaddr = pmem_baseaddress; + + drv_ctx.ptr_outputbuffer [i].pmem_fd = pmem_fd; + drv_ctx.ptr_outputbuffer [i].buffer_len = drv_ctx.op_buf.buffer_size; + drv_ctx.ptr_outputbuffer [i].mmaped_size = drv_ctx.op_buf.buffer_size; + drv_ctx.ptr_outputbuffer [i].offset = 0; + +#ifdef _ANDROID_ + #ifdef USE_ION + m_heap_ptr[i].video_heap_ptr = new VideoHeap (drv_ctx.op_buf_ion_info[i].ion_device_fd, + drv_ctx.op_buf.buffer_size, + pmem_baseaddress, + ion_alloc_data.handle, + pmem_fd); + m_heap_count = m_heap_count + 1; +#else + m_heap_ptr[i].video_heap_ptr = new VideoHeap (pmem_fd, + drv_ctx.op_buf.buffer_size, + pmem_baseaddress); +#endif +#endif + + m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; +#ifdef _ANDROID_ + m_pmem_info[i].pmem_fd = (OMX_U32) m_heap_ptr[i].video_heap_ptr.get (); +#else + m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd ; +#endif + setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer [i], + sizeof (vdec_bufferpayload)); + ioctl_msg.in = &setbuffers; + ioctl_msg.out = NULL; + + DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, + &ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Set output buffer failed"); + return OMX_ErrorInsufficientResources; + } + + // found an empty buffer at i + (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; + (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; + (*bufferHdr)->pAppPrivate = appData; + BITMASK_SET(&m_out_bm_count,i); + + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Output Buffer Index not found"); + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + + +// AllocateBuffer -- API Call +/* ====================================================================== +FUNCTION + omx_vdec::AllocateBuffer + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + unsigned i = 0; + OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type + + DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if(port == OMX_CORE_INPUT_PORT_INDEX) + { + if (arbitrary_bytes) + { + eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); + } + else + { + eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); + } + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + { + eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, + appData,bytes); + } + else + { + DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); + if(eRet == OMX_ErrorNone) + { + if(allocate_done()){ + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + } + DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet); + return eRet; +} + +// Free Buffer - API call +/* ====================================================================== +FUNCTION + omx_vdec::FreeBuffer + +DESCRIPTION + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int nPortIndex; + + DEBUG_PRINT_LOW("In for decoder free_buffer"); + + if(m_state == OMX_StateIdle && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + DEBUG_PRINT_LOW(" free buffer while Component in Loading pending"); + } + else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| + (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) + { + DEBUG_PRINT_LOW("Free Buffer while port %d disabled", port); + } + else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) + { + DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + + return OMX_ErrorIncorrectStateOperation; + } + else if (m_state != OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + } + + if(port == OMX_CORE_INPUT_PORT_INDEX) + { + /*Check if arbitrary bytes*/ + if(!arbitrary_bytes && !input_use_buffer) + nPortIndex = buffer - m_inp_mem_ptr; + else + nPortIndex = buffer - m_inp_heap_ptr; + + DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex); + if(nPortIndex < drv_ctx.ip_buf.actualcount) + { + // Clear the bit associated with it. + BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); + BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); + if (input_use_buffer == true) + { + + DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex); + if(m_phdr_pmem_ptr) + free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); + } + else + { + if (arbitrary_bytes) + { + if(m_phdr_pmem_ptr) + free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); + else + free_input_buffer(nPortIndex,NULL); + } + else + free_input_buffer(buffer); + } + m_inp_bPopulated = OMX_FALSE; + /*Free the Buffer Header*/ + if (release_input_done()) + { + DEBUG_PRINT_HIGH("ALL input buffers are freed/released"); + free_input_buffer_header(); + } + } + else + { + DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) + && release_input_done()) + { + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); + post_event(OMX_CommandPortDisable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + { + // check if the buffer is valid + nPortIndex = buffer - client_buffers.get_il_buf_hdr(); + if(nPortIndex < drv_ctx.op_buf.actualcount) + { + DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex); + // Clear the bit associated with it. + BITMASK_CLEAR(&m_out_bm_count,nPortIndex); + m_out_bPopulated = OMX_FALSE; + client_buffers.free_output_buffer (buffer); + + if (release_output_done()) + { + free_output_buffer_header(); + } + } + else + { + DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) + && release_output_done()) + { + DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it"); + + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); + memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); + } +#endif + + post_event(OMX_CommandPortDisable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else + { + eRet = OMX_ErrorBadPortIndex; + } + if((eRet == OMX_ErrorNone) && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + if(release_done()) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); + post_event(OMX_CommandStateSet, OMX_StateLoaded, + OMX_COMPONENT_GENERATE_EVENT); + } + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::EmptyThisBuffer + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE ret1 = OMX_ErrorNone; + unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; + + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) + { + codec_config_flag = true; + DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); + } + else + { + codec_config_flag = false; + } + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (buffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); + return OMX_ErrorBadParameter; + } + + if (!m_inp_bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled."); + return OMX_ErrorIncorrectStateOperation; + } + + if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) + { + DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %d", buffer->nInputPortIndex); + return OMX_ErrorBadPortIndex; + } + +#ifdef _ANDROID_ + if(iDivXDrmDecrypt) + { + OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer); + if(drmErr != OMX_ErrorNone) { + // this error can be ignored + DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr); + } + } + if (perf_flag) + { + if (!latency) + { + dec_time.stop(); + latency = dec_time.processing_time_us(); + dec_time.start(); + } + } +#endif //_ANDROID_ + + if (arbitrary_bytes) + { + nBufferIndex = buffer - m_inp_heap_ptr; + } + else + { + if (input_use_buffer == true) + { + nBufferIndex = buffer - m_inp_heap_ptr; + m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; + m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; + m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; + buffer = &m_inp_mem_ptr[nBufferIndex]; + DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d", + &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); + } + else{ + nBufferIndex = buffer - m_inp_mem_ptr; + } + } + + if (nBufferIndex > drv_ctx.ip_buf.actualcount ) + { + DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", + buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); + if (arbitrary_bytes) + { + post_event ((unsigned)hComp,(unsigned)buffer, + OMX_COMPONENT_GENERATE_ETB_ARBITRARY); + } + else + { + if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) + set_frame_rate(buffer->nTimeStamp); + post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::empty_this_buffer_proxy + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + int push_cnt = 0,i=0; + unsigned nPortIndex = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + struct vdec_input_frameinfo frameinfo; + struct vdec_bufferpayload *temp_buffer; + struct vdec_ioctl_msg ioctl_msg; + struct vdec_seqheader seq_header; + bool port_setting_changed = true; +#ifdef MAX_RES_1080P + bool not_coded_vop = false; +#endif + + /*Should we generate a Aync error event*/ + if (buffer == NULL || buffer->pInputPortPrivate == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); + return OMX_ErrorBadParameter; + } + + nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + + if (nPortIndex > drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", + nPortIndex); + return OMX_ErrorBadParameter; + } + + pending_input_buffers++; + + /* return zero length and not an EOS buffer */ + if (!arbitrary_bytes && (buffer->nFilledLen == 0) && + ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) + { + DEBUG_PRINT_HIGH("return zero legth buffer"); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorNone; + } + +#ifdef MAX_RES_1080P + if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){ + mp4StreamType psBits; + psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); + psBits.numBytes = buffer->nFilledLen; + mp4_headerparser.parseHeader(&psBits); + not_coded_vop = mp4_headerparser.is_notcodec_vop( + (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); + if(not_coded_vop) { + DEBUG_PRINT_HIGH("Found Not coded vop len %d frame number %d", + buffer->nFilledLen,frame_count); + if(buffer->nFlags & OMX_BUFFERFLAG_EOS){ + DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero"); + not_coded_vop = false; + buffer->nFilledLen = 0; + } + } + } +#endif + if(input_flush_progress == true +#ifdef MAX_RES_1080P + || not_coded_vop +#endif + ) + { + DEBUG_PRINT_LOW("Flush in progress return buffer "); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorNone; + } + + temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; + + if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) + { + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + /*for use buffer we need to memcpy the data*/ + temp_buffer->buffer_len = buffer->nFilledLen; + + if (input_use_buffer) + { + if (buffer->nFilledLen <= temp_buffer->buffer_len) + { + if(arbitrary_bytes) + { + memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); + } + else + { + memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), + buffer->nFilledLen); + } + } + else + { + return OMX_ErrorBadParameter; + } + + } + + frameinfo.bufferaddr = temp_buffer->bufferaddr; + frameinfo.client_data = (void *) buffer; + frameinfo.datalen = temp_buffer->buffer_len; + frameinfo.flags = 0; + frameinfo.offset = buffer->nOffset; + frameinfo.pmem_fd = temp_buffer->pmem_fd; + frameinfo.pmem_offset = temp_buffer->offset; + frameinfo.timestamp = buffer->nTimeStamp; + if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) + { + DEBUG_PRINT_LOW("ETB: dmx enabled"); + if (m_demux_entries == 0) + { + extract_demux_addr_offsets(buffer); + } + + DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries); + handle_demux_data(buffer); + frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; + frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; + } + else + { + frameinfo.desc_addr = NULL; + frameinfo.desc_size = 0; + } + if(!arbitrary_bytes) + { + frameinfo.flags |= buffer->nFlags; + } + + +#ifdef _ANDROID_ + if (m_debug_timestamp) + { + if(arbitrary_bytes) + { + DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); + m_timestamp_list.insert_ts(buffer->nTimeStamp); + } + else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) + { + DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); + m_timestamp_list.insert_ts(buffer->nTimeStamp); + } + } +#endif + +#ifdef INPUT_BUFFER_LOG + if (inputBufferFile1) + { + fwrite((const char *)temp_buffer->bufferaddr, + temp_buffer->buffer_len,1,inputBufferFile1); + } + +#endif + if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) + { + frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; + } + + if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) + { + DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached"); + frameinfo.flags |= VDEC_BUFFERFLAG_EOS; + h264_scratch.nFilledLen = 0; + nal_count = 0; + look_ahead_nal = false; + frame_count = 0; + if (m_frame_parser.mutils) + m_frame_parser.mutils->initialize_frame_checking_environment(); + m_frame_parser.flush(); + h264_last_au_ts = LLONG_MAX; + h264_last_au_flags = 0; + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + } + DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", + frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); + ioctl_msg.in = &frameinfo; + ioctl_msg.out = NULL; + if (ioctl(drv_ctx.video_driver_fd,VDEC_IOCTL_DECODE_FRAME, + &ioctl_msg) < 0) + { + /*Generate an async error and move to invalid state*/ + DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy VDEC_IOCTL_DECODE_FRAME failed"); + if (!arbitrary_bytes) + { + DEBUG_PRINT_LOW("Return failed buffer"); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + } + return OMX_ErrorBadParameter; + } else + time_stamp_dts.insert_timestamp(buffer); + + return ret; +} + +/* ====================================================================== +FUNCTION + omx_vdec::FillThisBuffer + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("FTB in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (!m_out_bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled."); + return OMX_ErrorIncorrectStateOperation; + } + + if (buffer == NULL || + ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) + { + return OMX_ErrorBadParameter; + } + + if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) + { + DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex); + return OMX_ErrorBadPortIndex; + } + + DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + post_event((unsigned) hComp, (unsigned)buffer,m_fill_output_msg); + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_vdec::fill_this_buffer_proxy + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) +{ + OMX_ERRORTYPE nRet = OMX_ErrorNone; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + OMX_BUFFERHEADERTYPE *buffer = bufferAdd; + struct vdec_fillbuffer_cmd fillbuffer; + struct vdec_bufferpayload *ptr_outputbuffer = NULL; + struct vdec_output_frameinfo *ptr_respbuffer = NULL; + + + if (bufferAdd == NULL || ((buffer - client_buffers.get_il_buf_hdr()) > + drv_ctx.op_buf.actualcount) ) + return OMX_ErrorBadParameter; + + DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", + bufferAdd, bufferAdd->pBuffer); + /*Return back the output buffer to client*/ + if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true) + { + DEBUG_PRINT_LOW("Output Buffers return flush/disable condition"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + return OMX_ErrorNone; + } + pending_output_buffers++; + buffer = client_buffers.get_dr_buf_hdr(bufferAdd); + ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; + if (ptr_respbuffer) + { + ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; + } + + if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) + { + DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + pending_output_buffers--; + return OMX_ErrorBadParameter; + } + + memcpy (&fillbuffer.buffer,ptr_outputbuffer,\ + sizeof(struct vdec_bufferpayload)); + fillbuffer.client_data = buffer; + +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + // Acquire a write lock on this buffer. + if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle, + GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { + DEBUG_PRINT_ERROR("Failed to acquire genlock"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + pending_output_buffers--; + return OMX_ErrorInsufficientResources; + } else { + native_buffer[buffer - m_out_mem_ptr].inuse = true; + } + } +#endif + + ioctl_msg.in = &fillbuffer; + ioctl_msg.out = NULL; + if (ioctl (drv_ctx.video_driver_fd, + VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n Decoder frame failed"); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + // Unlock the buffer + if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { + DEBUG_PRINT_ERROR("Releasing genlock failed"); + return OMX_ErrorInsufficientResources; + } else { + native_buffer[buffer - m_out_mem_ptr].inuse = false; + } + } +#endif + m_cb.FillBufferDone (hComp,m_app_data,buffer); + pending_output_buffers--; + return OMX_ErrorBadParameter; + } + + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SetCallbacks + +DESCRIPTION + Set the callbacks. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_CALLBACKTYPE* callbacks, + OMX_IN OMX_PTR appData) +{ + + m_cb = *callbacks; + DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ + m_cb.EventHandler,m_cb.FillBufferDone); + m_app_data = appData; + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentDeInit + +DESCRIPTION + Destroys the component and release memory allocated to the heap. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) +{ +#ifndef JB_MR1 + sp sm; + sp hwcBinder = NULL; +#endif +#ifdef _ANDROID_ + if(iDivXDrmDecrypt) + { + delete iDivXDrmDecrypt; + iDivXDrmDecrypt=NULL; + } +#endif //_ANDROID_ + int i = 0; + if (OMX_StateLoaded != m_state) + { + DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ + m_state); + DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); + } + else + { + DEBUG_PRINT_HIGH("Playback Ended - PASSED"); + } +#ifndef JB_MR1 + if (secure_mode) { + sm = defaultServiceManager(); + hwcBinder = + interface_cast(sm->getService(String16("display.hwcservice"))); + if (hwcBinder != NULL) { + hwcBinder->setCloseSecureStart(); + } else { + DEBUG_PRINT_HIGH("Failed to get hwcbinder, " + "failed to call close secure start"); + } + } +#endif + /*Check if the output buffers have to be cleaned up*/ + if(m_out_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing the Output Memory"); + for (i=0; i < drv_ctx.op_buf.actualcount; i++ ) + { + free_output_buffer (&m_out_mem_ptr[i]); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + if (native_buffer[i].inuse) + { + if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) { + DEBUG_PRINT_ERROR("Unlocking genlock failed"); + } + native_buffer[i].inuse = false; + } + } +#endif + } +#ifdef _ANDROID_ICS_ + memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); +#endif + } + + /*Check if the input buffers have to be cleaned up*/ + if(m_inp_mem_ptr || m_inp_heap_ptr) + { + DEBUG_PRINT_LOW("Freeing the Input Memory"); + for (i=0; isetCloseSecureEnd(); + } else { + DEBUG_PRINT_HIGH("Failed to get hwcbinder, " + "failed to call close secure start"); + } + } +#endif + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::UseEGLImage + +DESCRIPTION + OMX Use EGL Image method implementation . + +PARAMETERS + . + +RETURN VALUE + Not Implemented error. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN void* eglImage) +{ + OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; + +#ifdef USE_EGL_IMAGE_GPU + PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; + EGLint fd = -1, offset = 0,pmemPtr = 0; +#else + int fd = -1, offset = 0; +#endif + DEBUG_PRINT_HIGH("use EGL image support for decoder"); + if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { + DEBUG_PRINT_ERROR("\n "); + } +#ifdef USE_EGL_IMAGE_GPU + if(m_display_id == NULL) { + DEBUG_PRINT_ERROR("Display ID is not set by IL client \n"); + return OMX_ErrorInsufficientResources; + } + egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) + eglGetProcAddress("eglQueryImageKHR"); + egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); + egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); + egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); +#else //with OMX test app + struct temp_egl { + int pmem_fd; + int offset; + }; + struct temp_egl *temp_egl_id = NULL; + void * pmemPtr = (void *) eglImage; + temp_egl_id = (struct temp_egl *)eglImage; + if (temp_egl_id != NULL) + { + fd = temp_egl_id->pmem_fd; + offset = temp_egl_id->offset; + } +#endif + if (fd < 0) { + DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd); + return OMX_ErrorInsufficientResources; + } + pmem_info.pmem_fd = (OMX_U32) fd; + pmem_info.offset = (OMX_U32) offset; + pmem_entry.entry = (void *) &pmem_info; + pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pmem_list.entryList = &pmem_entry; + pmem_list.nEntries = 1; + ouput_egl_buffers = true; + if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, + (void *)&pmem_list, drv_ctx.op_buf.buffer_size, + (OMX_U8 *)pmemPtr)) { + DEBUG_PRINT_ERROR("use buffer call failed for egl image\n"); + return OMX_ErrorInsufficientResources; + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentRoleEnum + +DESCRIPTION + OMX Component Role Enum method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_U8* role, + OMX_IN OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s",role); + } + else + { + DEBUG_PRINT_LOW("No more roles"); + eRet = OMX_ErrorNoMore; + } + } +#ifdef MAX_RES_1080P + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) + ) +#else + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) +#endif + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s",role); + } + else + { + DEBUG_PRINT_LOW("No more roles"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s",role); + } + else + { + DEBUG_PRINT_LOW("No more roles"); + eRet = OMX_ErrorNoMore; + } + } + else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s",role); + } + else + { + DEBUG_PRINT_LOW("No more roles"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component"); + eRet = OMX_ErrorInvalidComponentName; + } + return eRet; +} + + + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateDone + +DESCRIPTION + Checks if entire buffer pool is allocated by IL Client or not. + Need this to move to IDLE state. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_vdec::allocate_done(void) +{ + bool bRet = false; + bool bRet_In = false; + bool bRet_Out = false; + + bRet_In = allocate_input_done(); + bRet_Out = allocate_output_done(); + + if(bRet_In && bRet_Out) + { + bRet = true; + } + + return bRet; +} +/* ====================================================================== +FUNCTION + omx_vdec::AllocateInputDone + +DESCRIPTION + Checks if I/P buffer pool is allocated by IL Client or not. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_vdec::allocate_input_done(void) +{ + bool bRet = false; + unsigned i=0; + + if (m_inp_mem_ptr == NULL) + { + return bRet; + } + if(m_inp_mem_ptr ) + { + for(;i= drv_ctx.op_buf.actualcount) + { + DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer); + return OMX_ErrorBadParameter; + } + else if (output_flush_progress) + { + DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); + buffer->nFilledLen = 0; + buffer->nTimeStamp = 0; + buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; + buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; + } + +#ifdef _ANDROID_ + char value[PROPERTY_VALUE_MAX]; + property_get("vidc.dec.debug.panframedata", value, NULL); + + if (atoi(value)) + { + if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) + { + DEBUG_PRINT_HIGH("\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + } + + if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) + { + DEBUG_PRINT_HIGH("\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + } + } +#endif + + DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", + buffer, buffer->pBuffer); + pending_output_buffers --; + + if (buffer->nFlags & OMX_BUFFERFLAG_EOS) + { + DEBUG_PRINT_HIGH("Output EOS has been reached"); + if (!output_flush_progress) + post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE); + + if (psource_frame) + { + m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); + psource_frame = NULL; + } + if (pdest_frame) + { + pdest_frame->nFilledLen = 0; + m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); + pdest_frame = NULL; + } + } + + DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer); +#ifdef OUTPUT_BUFFER_LOG + if (outputBufferFile1) + { + OMX_U32 index = buffer - m_out_mem_ptr; + OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; + + fwrite (pBuffer,1,buffer->nFilledLen, + outputBufferFile1); + } +#endif + + /* For use buffer we need to copy the data */ + if (!output_flush_progress) + { + time_stamp_dts.get_next_timestamp(buffer, + (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + } + if (m_cb.FillBufferDone) + { + if (buffer->nFilledLen > 0) + { + if (client_extradata) + { + if(secure_mode) + handle_extradata_secure(buffer); + else + handle_extradata(buffer); + } + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + // Keep min timestamp interval to handle corrupted bit stream scenario + set_frame_rate(buffer->nTimeStamp); + else if (arbitrary_bytes) + adjust_timestamp(buffer->nTimeStamp); +#ifdef _ANDROID_ + if (perf_flag) + { + if (!proc_frms) + { + dec_time.stop(); + latency = dec_time.processing_time_us() - latency; + DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); + dec_time.start(); + fps_metrics.start(); + } + proc_frms++; + if (buffer->nFlags & OMX_BUFFERFLAG_EOS) + { + OMX_U64 proc_time = 0; + fps_metrics.stop(); + proc_time = fps_metrics.processing_time_us(); + DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", + proc_frms, (float)proc_time / 1e6, + (float)(1e6 * proc_frms) / proc_time); + proc_frms = 0; + } + } +#endif //_ANDROID_ + +#ifdef OUTPUT_EXTRADATA_LOG + if (outputExtradataFile) + { + + OMX_U32 index = buffer - m_out_mem_ptr; + OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; + + OMX_OTHER_EXTRADATATYPE *p_extra = NULL; + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(pBuffer + buffer->nOffset + + buffer->nFilledLen + 3)&(~3)); + while(p_extra && + (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) + { + DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); + fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); + if (p_extra->eType == OMX_ExtraDataNone) + { + break; + } + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + } +#endif + } + if (buffer->nFlags & OMX_BUFFERFLAG_EOS){ + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } + + pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) + buffer->pPlatformPrivate)->entryList->entry; + DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + if (native_buffer[buffer - m_out_mem_ptr].inuse) { + if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { + DEBUG_PRINT_ERROR("Unlocking genlock failed"); + return OMX_ErrorInsufficientResources; + } + else { + native_buffer[buffer - m_out_mem_ptr].inuse = false; + } + } + } +#endif + OMX_BUFFERHEADERTYPE *il_buffer; + il_buffer = client_buffers.get_il_buf_hdr(buffer); + if (il_buffer) + m_cb.FillBufferDone (hComp,m_app_data,il_buffer); + else { + DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd); + } + else + { + return OMX_ErrorBadParameter; + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE* buffer) +{ + + if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) + { + DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer); + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", + buffer, buffer->pBuffer); + pending_input_buffers--; + + if (arbitrary_bytes) + { + if (pdest_frame == NULL && input_flush_progress == false) + { + DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer); + pdest_frame = buffer; + buffer->nFilledLen = 0; + buffer->nTimeStamp = LLONG_MAX; + push_input_buffer (hComp); + } + else + { + DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer); + buffer->nFilledLen = 0; + if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); + } + } + } + else if(m_cb.EmptyBufferDone) + { + buffer->nFilledLen = 0; + if (input_use_buffer == true){ + buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; + } + m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); + } + return OMX_ErrorNone; +} + + +int omx_vdec::async_message_process (void *context, void* message) +{ + omx_vdec* omx = NULL; + struct vdec_msginfo *vdec_msg = NULL; + OMX_BUFFERHEADERTYPE* omxhdr = NULL; + struct vdec_output_frameinfo *output_respbuf = NULL; + + if (context == NULL || message == NULL) + { + DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); + return -1; + } + vdec_msg = (struct vdec_msginfo *)message; + + omx = reinterpret_cast(context); + +#ifdef _ANDROID_ + if (omx->m_debug_timestamp) + { + if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) && + !(omx->output_flush_progress) ) + { + OMX_TICKS expected_ts = 0; + omx->m_timestamp_list.pop_min_ts(expected_ts); + DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", + vdec_msg->msgdata.output_frame.time_stamp, expected_ts); + + if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts) + { + DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check"); + } + } + } +#endif + + switch (vdec_msg->msgcode) + { + + case VDEC_MSG_EVT_HW_ERROR: + omx->post_event (NULL,vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_HARDWARE_ERROR); + break; + + case VDEC_MSG_RESP_START_DONE: + omx->post_event (NULL,vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_START_DONE); + break; + + case VDEC_MSG_RESP_STOP_DONE: + omx->post_event (NULL,vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + break; + + case VDEC_MSG_RESP_RESUME_DONE: + omx->post_event (NULL,vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_RESUME_DONE); + break; + + case VDEC_MSG_RESP_PAUSE_DONE: + omx->post_event (NULL,vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_PAUSE_DONE); + break; + + case VDEC_MSG_RESP_FLUSH_INPUT_DONE: + omx->post_event (NULL,vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); + break; + case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: + omx->post_event (NULL,vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); + break; + case VDEC_MSG_RESP_INPUT_FLUSHED: + case VDEC_MSG_RESP_INPUT_BUFFER_DONE: + + omxhdr = (OMX_BUFFERHEADERTYPE* )\ + vdec_msg->msgdata.input_frame_clientdata; + + + if (omxhdr == NULL || + ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) + { + omxhdr = NULL; + vdec_msg->status_code = VDEC_S_EFATAL; + } + + omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, + OMX_COMPONENT_GENERATE_EBD); + break; + case VDEC_MSG_EVT_INFO_FIELD_DROPPED: + int64_t *timestamp; + timestamp = (int64_t *) malloc(sizeof(int64_t)); + if (timestamp) { + *timestamp = vdec_msg->msgdata.output_frame.time_stamp; + omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); + DEBUG_PRINT_HIGH("Field dropped time stamp is %lld", + vdec_msg->msgdata.output_frame.time_stamp); + } + break; + case VDEC_MSG_RESP_OUTPUT_FLUSHED: + case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: + omxhdr = (OMX_BUFFERHEADERTYPE*)vdec_msg->msgdata.output_frame.client_data; + DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", + omxhdr, vdec_msg->msgdata.output_frame.time_stamp, + vdec_msg->msgdata.output_frame.pic_type); + + /* update SYNCFRAME flag */ + if (omx->eCompressionFormat == OMX_VIDEO_CodingAVC) + { + /* set SYNCFRAME flag if picture type is IDR for h264 */ + if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_IDR) + vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME; + else + vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME; + } + else + { + /* set SYNCFRAME flag if picture type is I_TYPE */ + if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_I) + vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME; + else + vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME; + } + + if (omxhdr && omxhdr->pOutputPortPrivate && + ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && + (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate + - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) + { + if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) + { + omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; + omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; + omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; + omxhdr->nFlags = (vdec_msg->msgdata.output_frame.flags); + + output_respbuf = (struct vdec_output_frameinfo *)\ + omxhdr->pOutputPortPrivate; + output_respbuf->framesize.bottom = + vdec_msg->msgdata.output_frame.framesize.bottom; + output_respbuf->framesize.left = + vdec_msg->msgdata.output_frame.framesize.left; + output_respbuf->framesize.right = + vdec_msg->msgdata.output_frame.framesize.right; + output_respbuf->framesize.top = + vdec_msg->msgdata.output_frame.framesize.top; + output_respbuf->len = vdec_msg->msgdata.output_frame.len; + output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; + output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp; + output_respbuf->flags = vdec_msg->msgdata.output_frame.flags; + output_respbuf->pic_type = vdec_msg->msgdata.output_frame.pic_type; + output_respbuf->interlaced_format = vdec_msg->msgdata.output_frame.interlaced_format; + output_respbuf->aspect_ratio_info = + vdec_msg->msgdata.output_frame.aspect_ratio_info; + + if (omx->output_use_buffer) + memcpy ( omxhdr->pBuffer, + (vdec_msg->msgdata.output_frame.bufferaddr + + vdec_msg->msgdata.output_frame.offset), + vdec_msg->msgdata.output_frame.len ); + } + else + omxhdr->nFilledLen = 0; + omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_FBD); + } + else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) + omx->post_event (NULL, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_EOS_DONE); + else + omx->post_event (NULL, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_HARDWARE_ERROR); + break; + case VDEC_MSG_EVT_CONFIG_CHANGED: + DEBUG_PRINT_HIGH("Port settings changed"); + omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, + OMX_COMPONENT_GENERATE_PORT_RECONFIG); + break; + case VDEC_MSG_EVT_INFO_CONFIG_CHANGED: + { + DEBUG_PRINT_HIGH("Port settings changed info"); + // get_buffer_req and populate port defn structure + OMX_ERRORTYPE eRet = OMX_ErrorNone; + omx->m_port_def.nPortIndex = 1; + eRet = omx->update_portdef(&(omx->m_port_def)); + omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, + OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG); + break; + } + default: + break; + } + return 1; +} + +OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ) +{ + unsigned address,p2,id; + DEBUG_PRINT_LOW("Empty this arbitrary"); + + if (buffer == NULL) + { + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %d, timestamp %u", + buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp); + + /* return zero length and not an EOS buffer */ + /* return buffer if input flush in progress */ + if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && + ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) + { + DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress"); + m_cb.EmptyBufferDone (hComp,m_app_data,buffer); + return OMX_ErrorNone; + } + + if (psource_frame == NULL) + { + DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp); + psource_frame = buffer; + DEBUG_PRINT_LOW("Try to Push One Input Buffer "); + push_input_buffer (hComp); + } + else + { + DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer); + if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL)) + { + return OMX_ErrorBadParameter; + } + } + + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) +{ + unsigned address,p2,id; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (pdest_frame == NULL || psource_frame == NULL) + { + /*Check if we have a destination buffer*/ + if (pdest_frame == NULL) + { + DEBUG_PRINT_LOW("Get a Destination buffer from the queue"); + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *)address; + pdest_frame->nFilledLen = 0; + pdest_frame->nTimeStamp = LLONG_MAX; + DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame); + } + } + + /*Check if we have a destination buffer*/ + if (psource_frame == NULL) + { + DEBUG_PRINT_LOW("Get a source buffer from the queue"); + if (m_input_pending_q.m_size) + { + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *)address; + DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame, + psource_frame->nTimeStamp); + DEBUG_PRINT_LOW("Next source Buffer flag %d length %d", + psource_frame->nFlags,psource_frame->nFilledLen); + + } + } + + } + + while ((pdest_frame != NULL) && (psource_frame != NULL)) + { + switch (codec_type_parse) + { + case CODEC_TYPE_MPEG4: + case CODEC_TYPE_H263: + case CODEC_TYPE_MPEG2: + ret = push_input_sc_codec(hComp); + break; + case CODEC_TYPE_H264: + ret = push_input_h264(hComp); + break; + case CODEC_TYPE_VC1: + ret = push_input_vc1(hComp); + break; + } + if (ret != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); + omx_report_error (); + break; + } + } + + return ret; +} + +OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) +{ + OMX_U32 partial_frame = 1; + OMX_BOOL generate_ebd = OMX_TRUE; + unsigned address,p2,id; + + DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %d", + psource_frame,psource_frame->nTimeStamp); + if (m_frame_parser.parse_sc_frame(psource_frame, + pdest_frame,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); + return OMX_ErrorBadParameter; + } + + if (partial_frame == 0) + { + DEBUG_PRINT_LOW("Frame size %d source %p frame count %d", + pdest_frame->nFilledLen,psource_frame,frame_count); + + + DEBUG_PRINT_LOW("TimeStamp updated %d",pdest_frame->nTimeStamp); + /*First Parsed buffer will have only header Hence skip*/ + if (frame_count == 0) + { + DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame "); +#ifdef MAX_RES_1080P + if(codec_type_parse == CODEC_TYPE_MPEG4 || + codec_type_parse == CODEC_TYPE_DIVX) { + mp4StreamType psBits; + psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; + psBits.numBytes = pdest_frame->nFilledLen; + mp4_headerparser.parseHeader(&psBits); + } +#endif + frame_count++; + } + else + { + pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; + if(pdest_frame->nFilledLen) + { + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *) address; + pdest_frame->nFilledLen = 0; + } + } + else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) + { + DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL"); + m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); + pdest_frame = NULL; + } + } + } + else + { + DEBUG_PRINT_LOW("Not a Complete Frame %d",pdest_frame->nFilledLen); + /*Check if Destination Buffer is full*/ + if (pdest_frame->nAllocLen == + pdest_frame->nFilledLen + pdest_frame->nOffset) + { + DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); + return OMX_ErrorStreamCorrupt; + } + } + + if (psource_frame->nFilledLen == 0) + { + if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) + { + if (pdest_frame) + { + pdest_frame->nFlags |= psource_frame->nFlags; + DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("Found a frame size = %d number = %d", + pdest_frame->nFilledLen,frame_count++); + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + } + else + { + DEBUG_PRINT_LOW("Last frame in else dest addr") ; + generate_ebd = OMX_FALSE; + } + } + if(generate_ebd) + { + DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame); + m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); + psource_frame = NULL; + + if (m_input_pending_q.m_size) + { + DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame, + psource_frame->nTimeStamp); + DEBUG_PRINT_LOW("Next source Buffer flag %d length %d", + psource_frame->nFlags,psource_frame->nFilledLen); + } + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) +{ + OMX_U32 partial_frame = 1; + unsigned address,p2,id; + OMX_BOOL isNewFrame = OMX_FALSE; + OMX_BOOL generate_ebd = OMX_TRUE; + + if (h264_scratch.pBuffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %d " + "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); + DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); + if (h264_scratch.nFilledLen && look_ahead_nal) + { + look_ahead_nal = false; + if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame"); + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + if (nal_length == 0) + { + DEBUG_PRINT_LOW("Zero NAL, hence parse using start code"); + if (m_frame_parser.parse_sc_frame(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); + return OMX_ErrorBadParameter; + } + } + else + { + DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); + if (m_frame_parser.parse_h264_nallength(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); + return OMX_ErrorBadParameter; + } + } + + if (partial_frame == 0) + { + if (nal_count == 0 && h264_scratch.nFilledLen == 0) + { + DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); + nal_count++; + h264_scratch.nTimeStamp = psource_frame->nTimeStamp; + h264_scratch.nFlags = psource_frame->nFlags; + } + else + { + DEBUG_PRINT_LOW("Parsed New NAL Length = %d",h264_scratch.nFilledLen); + if(h264_scratch.nFilledLen) + { + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, + NALU_TYPE_SPS); +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, + h264_scratch.nFilledLen, NALU_TYPE_SEI); + else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + // If timeinfo is present frame info from SEI is already processed + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, + h264_scratch.nFilledLen, NALU_TYPE_SEI); +#endif + m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); + nal_count++; + if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { + pdest_frame->nTimeStamp = h264_last_au_ts; + pdest_frame->nFlags = h264_last_au_flags; +#ifdef PANSCAN_HDLR + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + h264_parser->update_panscan_data(h264_last_au_ts); +#endif + } + if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || + m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { + h264_last_au_ts = h264_scratch.nTimeStamp; + h264_last_au_flags = h264_scratch.nFlags; +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); + if (!VALID_TS(h264_last_au_ts)) + h264_last_au_ts = ts_in_sei; + } +#endif + } else + h264_last_au_ts = LLONG_MAX; + } + + if (!isNewFrame) + { + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %d", + h264_scratch.nFilledLen); + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) + pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\n Error:2: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + else + { + look_ahead_nal = true; + DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("Found a frame size = %d number = %d", + pdest_frame->nFilledLen,frame_count++); + + if (pdest_frame->nFilledLen == 0) + { + DEBUG_PRINT_LOW("Copy the Current Frame since and push it"); + look_ahead_nal = false; + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + else + { + if(psource_frame->nFilledLen || h264_scratch.nFilledLen) + { + DEBUG_PRINT_LOW("Reset the EOS Flag"); + pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; + } + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + //frame_count++; + pdest_frame = NULL; + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame); + pdest_frame->nFilledLen = 0; + pdest_frame->nFlags = 0; + pdest_frame->nTimeStamp = LLONG_MAX; + } + } + } + } + } + else + { + DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); + /*Check if Destination Buffer is full*/ + if (h264_scratch.nAllocLen == + h264_scratch.nFilledLen + h264_scratch.nOffset) + { + DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); + return OMX_ErrorStreamCorrupt; + } + } + + if (!psource_frame->nFilledLen) + { + DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame); + + if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) + { + if (pdest_frame) + { + DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; + pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; +#ifdef MAX_RES_720P + if (frame_count == 0) + { + DEBUG_PRINT_HIGH("No frames sent to driver yet, " + "So send zero length EOS buffer"); + pdest_frame->nFilledLen = 0; + } +#endif + DEBUG_PRINT_LOW("pdest_frame->nFilledLen = %d, nFlags = 0x%x, TimeStamp = %x", + pdest_frame->nFilledLen, pdest_frame->nFlags, pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++); +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); + if (!VALID_TS(pdest_frame->nTimeStamp)) + pdest_frame->nTimeStamp = ts_in_sei; + } +#endif + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + } + else + { + DEBUG_PRINT_LOW("Last frame in else dest addr %p size %d", + pdest_frame,h264_scratch.nFilledLen); + generate_ebd = OMX_FALSE; + } + } + } + if(generate_ebd && !psource_frame->nFilledLen) + { + m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); + psource_frame = NULL; + if (m_input_pending_q.m_size) + { + DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("Next source Buffer flag %d src length %d", + psource_frame->nFlags,psource_frame->nFilledLen); + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) +{ + OMX_U8 *buf, *pdest; + OMX_U32 partial_frame = 1; + OMX_U32 buf_len, dest_len; + + if(first_frame == 0) + { + first_frame = 1; + DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes"); + if(!m_vendor_config.pData) + { + DEBUG_PRINT_LOW("Check profile type in 1st source buffer"); + buf = psource_frame->pBuffer; + buf_len = psource_frame->nFilledLen; + + if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == + VC1_SP_MP_START_CODE) + { + m_vc1_profile = VC1_SP_MP_RCV; + } + else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) + { + m_vc1_profile = VC1_AP; + } + else + { + DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer"); + return OMX_ErrorStreamCorrupt; + } + } + else + { + pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + + pdest_frame->nOffset; + dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + + pdest_frame->nOffset); + + if(dest_len < m_vendor_config.nDataSize) + { + DEBUG_PRINT_ERROR("\nDestination buffer full"); + return OMX_ErrorBadParameter; + } + else + { + memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); + pdest_frame->nFilledLen += m_vendor_config.nDataSize; + } + } + } + + switch(m_vc1_profile) + { + case VC1_AP: + DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code"); + if (push_input_sc_codec(hComp) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); + return OMX_ErrorBadParameter; + } + break; + + case VC1_SP_MP_RCV: + default: + DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode"); + return OMX_ErrorBadParameter; + } + return OMX_ErrorNone; +} + +#ifndef USE_ION +bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, + OMX_U32 alignment) +{ + struct pmem_allocation allocation; + allocation.size = buffer_size; + allocation.align = clip2(alignment); + if (allocation.align < 4096) + { + allocation.align = 4096; + } + if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) + { + DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", + allocation.align, allocation.size); + return false; + } + return true; +} +#endif + +#ifdef USE_ION +int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, + OMX_U32 alignment, struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data,int flag) +{ + int fd = -EINVAL; + int rc = -EINVAL; + int ion_dev_flag; + struct vdec_ion ion_buf_info; + if (!alloc_data || buffer_size <= 0 || !fd_data) { + DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n"); + return -EINVAL; + } + + ion_dev_flag = O_RDONLY; + fd = open (MEM_DEVICE, ion_dev_flag); + if (fd < 0) { + DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd); + return fd; + } + alloc_data->flags = 0; + if(!secure_mode && (flag & ION_FLAG_CACHED)) + { + alloc_data->flags |= ION_FLAG_CACHED; + } + + alloc_data->len = buffer_size; + alloc_data->align = clip2(alignment); + if (alloc_data->align < 4096) + { + alloc_data->align = 4096; + } + if(secure_mode) { + if(external_meta_buffer) { + alloc_data->heap_mask = ION_HEAP(ION_CP_MFC_HEAP_ID); + alloc_data->flags |= ION_SECURE; + } else if (external_meta_buffer_iommu) { + alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); + } else { + alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); + alloc_data->flags |= ION_SECURE; + } + } else { +#ifdef MAX_RES_720P + alloc_data->len = (buffer_size + (alloc_data->align - 1)) & ~(alloc_data->align - 1); + alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); +#else + alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID)); +#endif + } + + rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); + if (rc || !alloc_data->handle) { + DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); + alloc_data->handle = NULL; + close(fd); + fd = -ENOMEM; + return fd; + } + fd_data->handle = alloc_data->handle; + rc = ioctl(fd,ION_IOC_MAP,fd_data); + if (rc) { + DEBUG_PRINT_ERROR("\n ION MAP failed "); + ion_buf_info.ion_alloc_data = *alloc_data; + ion_buf_info.ion_device_fd = fd; + ion_buf_info.fd_ion_data = *fd_data; + free_ion_memory(&ion_buf_info); + fd_data->fd =-1; + close(fd); + fd = -ENOMEM; + } + DEBUG_PRINT_HIGH("ION: alloc_data: handle(0x%X), len(%u), align(%u), " + "flags(0x%x), fd_data: handle(0x%x), fd(0x%x)", + alloc_data->handle, alloc_data->len, alloc_data->align, + alloc_data->flags, fd_data->handle, fd_data->fd); + return fd; +} + +void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) { + + if(!buf_ion_info) { + DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata"); + return; + } + DEBUG_PRINT_HIGH("ION: free: handle(0x%X), len(%u), fd(0x%x)", + buf_ion_info->ion_alloc_data.handle, + buf_ion_info->ion_alloc_data.len, + buf_ion_info->fd_ion_data.fd); + if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, + &buf_ion_info->ion_alloc_data.handle)) { + DEBUG_PRINT_ERROR("\n ION: free failed" ); + } + close(buf_ion_info->ion_device_fd); + buf_ion_info->ion_device_fd = -1; + buf_ion_info->ion_alloc_data.handle = NULL; + buf_ion_info->fd_ion_data.fd = -1; +} +#endif +void omx_vdec::free_output_buffer_header() +{ + DEBUG_PRINT_HIGH("ALL output buffers are freed/released"); + output_use_buffer = false; + ouput_egl_buffers = false; + + if (m_out_mem_ptr) + { + free (m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + + if(m_platform_list) + { + free(m_platform_list); + m_platform_list = NULL; + } + + if (drv_ctx.ptr_respbuffer) + { + free (drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } + if (drv_ctx.ptr_outputbuffer) + { + free (drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif +} + +void omx_vdec::free_input_buffer_header() +{ + input_use_buffer = false; + if (arbitrary_bytes) + { + if (m_frame_parser.mutils) + { + DEBUG_PRINT_LOW("Free utils parser"); + delete (m_frame_parser.mutils); + m_frame_parser.mutils = NULL; + } + + if (m_inp_heap_ptr) + { + DEBUG_PRINT_LOW("Free input Heap Pointer"); + free (m_inp_heap_ptr); + m_inp_heap_ptr = NULL; + } + + if (m_phdr_pmem_ptr) + { + DEBUG_PRINT_LOW("Free input pmem header Pointer"); + free (m_phdr_pmem_ptr); + m_phdr_pmem_ptr = NULL; + } + } + if (m_inp_mem_ptr) + { + DEBUG_PRINT_LOW("Free input pmem Pointer area"); + free (m_inp_mem_ptr); + m_inp_mem_ptr = NULL; + } + if (drv_ctx.ptr_inputbuffer) + { + DEBUG_PRINT_LOW("Free Driver Context pointer"); + free (drv_ctx.ptr_inputbuffer); + drv_ctx.ptr_inputbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.ip_buf_ion_info) { + DEBUG_PRINT_LOW("Free ion context"); + free(drv_ctx.ip_buf_ion_info); + drv_ctx.ip_buf_ion_info = NULL; + } +#endif +} + +OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) +{ + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int buf_size = 0, extra_data_size = 0; + DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + ioctl_msg.in = NULL; + ioctl_msg.out = buffer_prop; + if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_GET_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + buf_size = buffer_prop->buffer_size; + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + { + DEBUG_PRINT_HIGH("Frame info extra data enabled!"); + extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; + } + if (client_extradata & OMX_INTERLACE_EXTRADATA) + { + DEBUG_PRINT_HIGH("Interlace extra data enabled!"); + extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; + } + if (client_extradata & OMX_PORTDEF_EXTRADATA) + { + extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; + DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d", + extra_data_size); + } + if (extra_data_size) + { + extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator + buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit + } + buf_size += extra_data_size; + buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); + DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size, buf_size); + if (in_reconfig) // BufReq will be set to driver when port is disabled + buffer_prop->buffer_size = buf_size; + else if (buf_size != buffer_prop->buffer_size) + { + buffer_prop->buffer_size = buf_size; + eRet = set_buffer_req(buffer_prop); + } + } + DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + return eRet; +} + +OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) +{ + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned buf_size = 0; + DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); + if (buf_size != buffer_prop->buffer_size) + { + DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", + buffer_prop->buffer_size, buf_size); + eRet = OMX_ErrorBadParameter; + } + else + { + ioctl_msg.in = buffer_prop; + ioctl_msg.out = NULL; + if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Setting buffer requirements failed"); + eRet = OMX_ErrorInsufficientResources; + } else { + if (!client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); + eRet = OMX_ErrorInsufficientResources; + } + } + } + return eRet; +} + +OMX_ERRORTYPE omx_vdec::start_port_reconfig() +{ + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + eRet = update_picture_resolution(); + if (eRet == OMX_ErrorNone) + { + ioctl_msg.out = &drv_ctx.interlace; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_INTERLACE_FORMAT, &ioctl_msg)) + { + DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_INTERLACE_FORMAT"); + eRet = OMX_ErrorHardware; + } + else + { + if (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + { + DEBUG_PRINT_HIGH("Interlace format detected (%x)!", drv_ctx.interlace); + client_extradata |= OMX_INTERLACE_EXTRADATA; + } + in_reconfig = true; + op_buf_rcnfg.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + eRet = get_buffer_req(&op_buf_rcnfg); + } + } + + if (eRet == OMX_ErrorNone) { + //update power HAL with new width, height and bitrate + power_module_deregister(); + power_module_register(); + } + + return eRet; +} + +OMX_ERRORTYPE omx_vdec::update_picture_resolution() +{ + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + ioctl_msg.in = NULL; + ioctl_msg.out = &drv_ctx.video_resolution; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)) + { + DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES"); + eRet = OMX_ErrorHardware; + } + return eRet; +} + +OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (!portDefn) + { + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("omx_vdec::update_portdef"); + portDefn->nVersion.nVersion = OMX_SPEC_VERSION; + portDefn->nSize = sizeof(portDefn); + portDefn->eDomain = OMX_PortDomainVideo; + if (drv_ctx.frame_rate.fps_denominator > 0) + portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / + drv_ctx.frame_rate.fps_denominator; + else { + DEBUG_PRINT_ERROR("Error: Divide by zero \n"); + return OMX_ErrorBadParameter; + } + if (0 == portDefn->nPortIndex) + { + portDefn->eDir = OMX_DirInput; + portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; + portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; + portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; + portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; + portDefn->format.video.eCompressionFormat = eCompressionFormat; + portDefn->bEnabled = m_inp_bEnabled; + portDefn->bPopulated = m_inp_bPopulated; + } + else if (1 == portDefn->nPortIndex) + { + portDefn->eDir = OMX_DirOutput; + if (update_picture_resolution() != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("update_picture_resolution failed \n"); + return OMX_ErrorHardware; + } + if (!client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed"); + return OMX_ErrorHardware; + } + if (in_reconfig) + { + portDefn->nBufferCountActual = op_buf_rcnfg.actualcount; + portDefn->nBufferCountMin = op_buf_rcnfg.mincount; + portDefn->nBufferSize = op_buf_rcnfg.buffer_size; + } + else + { + portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; + portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; + portDefn->nBufferSize = drv_ctx.op_buf.buffer_size; + } + unsigned int buf_size = 0; + if (!client_buffers.get_buffer_req(buf_size)) { + DEBUG_PRINT_ERROR("\n update buffer requirements"); + return OMX_ErrorHardware; + } + portDefn->nBufferSize = buf_size; + portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + portDefn->bEnabled = m_out_bEnabled; + portDefn->bPopulated = m_out_bPopulated; + if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { + DEBUG_PRINT_ERROR("\n Error in getting color format"); + return OMX_ErrorHardware; + } + } + else + { + portDefn->eDir = OMX_DirMax; + DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; + portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; + portDefn->format.video.nStride = drv_ctx.video_resolution.stride; + portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; + DEBUG_PRINT_LOW("update_portdef: PortIndex = %u, Width = %d Height = %d " + "Stride = %u SliceHeight = %u output format = 0x%x, eColorFormat = 0x%x", + portDefn->nPortIndex, + portDefn->format.video.nFrameHeight, + portDefn->format.video.nFrameWidth, + portDefn->format.video.nStride, + portDefn->format.video.nSliceHeight, + drv_ctx.output_format, + portDefn->format.video.eColorFormat); + return eRet; +} + +OMX_ERRORTYPE omx_vdec::allocate_output_headers() +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr = NULL; + unsigned i= 0; + + if(!m_out_mem_ptr) { + DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation"); + int nBufHdrSize = 0; + int nPlatformEntrySize = 0; + int nPlatformListSize = 0; + int nPMEMInfoSize = 0; + OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; + + DEBUG_PRINT_LOW("Setting First Output Buffer(%d)", + drv_ctx.op_buf.actualcount); + nBufHdrSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_BUFFERHEADERTYPE); + + nPMEMInfoSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); + nPlatformListSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); + nPlatformEntrySize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); + + DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize, + sizeof(OMX_BUFFERHEADERTYPE), + nPMEMInfoSize, + nPlatformListSize); + DEBUG_PRINT_LOW("PE %d bmSize %d ",nPlatformEntrySize, + m_out_bm_count); + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + // Alloc mem for platform specific info + char *pPtr=NULL; + pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + + nPMEMInfoSize,1); + drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ + calloc (sizeof(struct vdec_bufferpayload), + drv_ctx.op_buf.actualcount); + drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ + calloc (sizeof (struct vdec_output_frameinfo), + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ + calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); +#endif + + if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer + && drv_ctx.ptr_respbuffer) + { + bufHdr = m_out_mem_ptr; + m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); + m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) + (((char *) m_platform_list) + nPlatformListSize); + m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + (((char *) m_platform_entry) + nPlatformEntrySize); + pPlatformList = m_platform_list; + pPlatformEntry = m_platform_entry; + pPMEMInfo = m_pmem_info; + + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); + + // Settting the entire storage nicely + DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, + m_out_mem_ptr,pPlatformEntry); + DEBUG_PRINT_LOW(" Pmem Info = %p ",pPMEMInfo); + for(i=0; i < drv_ctx.op_buf.actualcount ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = 0; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = NULL; + bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pPlatformEntry->entry = pPMEMInfo; + // Initialize the Platform List + pPlatformList->nEntries = 1; + pPlatformList->entryList = pPlatformEntry; + // Keep pBuffer NULL till vdec is opened + bufHdr->pBuffer = NULL; + pPMEMInfo->offset = 0; + pPMEMInfo->pmem_fd = 0; + bufHdr->pPlatformPrivate = pPlatformList; + drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; +#endif + /*Create a mapping between buffers*/ + bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; + drv_ctx.ptr_respbuffer[i].client_data = (void *) \ + &drv_ctx.ptr_outputbuffer[i]; + // Move the buffer and buffer header pointers + bufHdr++; + pPMEMInfo++; + pPlatformEntry++; + pPlatformList++; + } + } + else + { + DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ + m_out_mem_ptr, pPtr); + if(m_out_mem_ptr) + { + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(pPtr) + { + free(pPtr); + pPtr = NULL; + } + if(drv_ctx.ptr_outputbuffer) + { + free(drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } + if(drv_ctx.ptr_respbuffer) + { + free(drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif + eRet = OMX_ErrorInsufficientResources; + } + } else { + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + +void omx_vdec::complete_pending_buffer_done_cbs() +{ + unsigned p1; + unsigned p2; + unsigned ident; + omx_cmd_queue tmp_q, pending_bd_q; + pthread_mutex_lock(&m_lock); + // pop all pending GENERATE FDB from ftb queue + while (m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_FBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to ftb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_ftb_q.insert_entry(p1,p2,ident); + } + // pop all pending GENERATE EDB from etb queue + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_EBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to etb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_etb_q.insert_entry(p1,p2,ident); + } + pthread_mutex_unlock(&m_lock); + // process all pending buffer dones + while(pending_bd_q.m_size) + { + pending_bd_q.pop_entry(&p1,&p2,&ident); + switch(ident) + { + case OMX_COMPONENT_GENERATE_EBD: + if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); + omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FBD: + if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); + omx_report_error (); + } + break; + } + } +} + +void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) +{ + OMX_U32 new_frame_interval = 0; + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts + && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000)) + { + new_frame_interval = (act_timestamp > prev_ts)? + act_timestamp - prev_ts : + prev_ts - act_timestamp; + if (new_frame_interval < frm_int || frm_int == 0) + { + frm_int = new_frame_interval; + if(frm_int) + { + drv_ctx.frame_rate.fps_numerator = 1e6; + drv_ctx.frame_rate.fps_denominator = frm_int; + DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", + frm_int, drv_ctx.frame_rate.fps_numerator / + (float)drv_ctx.frame_rate.fps_denominator); + ioctl_msg.in = &drv_ctx.frame_rate; + if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Setting frame rate failed"); + } + } + } + } + prev_ts = act_timestamp; +} + +void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) +{ + if (rst_prev_ts && VALID_TS(act_timestamp)) + { + prev_ts = act_timestamp; + rst_prev_ts = false; + } + else if (VALID_TS(prev_ts)) + { + bool codec_cond = (drv_ctx.timestamp_adjust)? + (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? + (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): + (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); + if(frm_int > 0 && codec_cond) + { + DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); + act_timestamp = prev_ts + frm_int; + DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); + prev_ts = act_timestamp; + } + else + set_frame_rate(act_timestamp); + } + else if (frm_int > 0) // In this case the frame rate was set along + { // with the port definition, start ts with 0 + act_timestamp = prev_ts = 0; // and correct if a valid ts is received. + rst_prev_ts = true; + } +} + +void omx_vdec::handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr) +{ + OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_extn_user[32]; + struct vdec_output_frameinfo *output_respbuf; + OMX_U32 num_conceal_MB = 0; + OMX_S64 ts_in_sei = 0; + OMX_U32 frame_rate = 0; + OMX_U32 extn_user_data_cnt = 0; + + OMX_U32 index = p_buf_hdr - m_out_mem_ptr; + OMX_U8 *meta_buffer_virtual = (OMX_U8 *)meta_buff.buffer; + + + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(meta_buffer_virtual + + index * drv_ctx.op_buf.meta_buffer_size + 3)&(~3)); + + //mapping of ouput buffer to the corresponding meta buffer + output_respbuf = (struct vdec_output_frameinfo *)\ + p_buf_hdr->pOutputPortPrivate; + output_respbuf->metadata_info.metabufaddr = (OMX_U8 *)p_extra; + output_respbuf->metadata_info.size = + drv_ctx.op_buf.meta_buffer_size; + + meta_buffer_virtual = (OMX_U8 *)p_extra; + + if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)) + { + // Process driver extradata + while(p_extra && p_extra->eType != VDEC_EXTRADATA_NONE) + { + DEBUG_PRINT_LOW("handle_extradata_secure : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)", + p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize); + if (p_extra->nSize < p_extra->nDataSize) + { + DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d", + p_extra->nSize, p_extra->nDataSize); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + if((OMX_U8*)p_extra > (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size) || + p_extra->nDataSize == 0 || p_extra->nSize == 0) + p_extra = NULL; + continue; + } + if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP) + { + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + num_conceal_MB = count_MB_in_extradata(p_extra); + if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP) + // Map driver extradata to corresponding OMX type + p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB; + else + p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client +#ifdef _ANDROID_ + if (m_debug_concealedmb) { + DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB); + } +#endif /* _ANDROID_ */ + } + else if (p_extra->eType == VDEC_EXTRADATA_SEI) + { + p_sei = p_extra; +#ifdef MAX_RES_1080P + h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); +#endif + p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client + } + else if (p_extra->eType == VDEC_EXTRADATA_VUI) + { + p_vui = p_extra; +#ifdef MAX_RES_1080P + h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); +#endif + p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client + } + else if (p_extra->eType == VDEC_EXTRADATA_EXT_DATA) + { + OMX_U8 *data_ptr = (OMX_U8*)p_extra->data; + OMX_U32 value = 0; + p_extn_user[extn_user_data_cnt] = p_extra; + extn_user_data_cnt++; + if((*data_ptr & 0xf0) == 0x20) + { + value = ((*data_ptr) & 0x01); + data_ptr++; + if (value) + data_ptr += 3; + value = *((OMX_U32*)data_ptr); + value = ((value << 24) | (((value >> 8)<<24)>>8) | + (((value >> 16)<<24)>>16) | (value >> 24)); + m_disp_hor_size = (value & 0xfffc0000)>>18; + m_disp_vert_size = (value & 0x0001fff8)>>3; + DEBUG_PRINT_LOW("Display Vertical Size = %d Display Horizontal Size = %d", + m_disp_vert_size, m_disp_hor_size); + } + } + else if (p_extra->eType == VDEC_EXTRADATA_USER_DATA) + { + p_extn_user[extn_user_data_cnt] = p_extra; + extn_user_data_cnt++; + } + print_debug_extradata(p_extra); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + + if((OMX_U8*)p_extra > (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size) || + p_extra->nDataSize == 0 || p_extra->nSize == 0) + p_extra = NULL; + } + if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)) + { + //moving p_extra to the starting location of the metadata buffer + p_extra = (OMX_OTHER_EXTRADATATYPE *)meta_buffer_virtual; + // Driver extradata is only exposed if MB map is requested by client, + // otherwise can be overwritten by omx extradata. + p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + } + } + + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + if (p_vui) + h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); + if (p_sei) + h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); + ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp); + if (!VALID_TS(p_buf_hdr->nTimeStamp)) + p_buf_hdr->nTimeStamp = ts_in_sei; + } + else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei) + // If timeinfo is present frame info from SEI is already processed + h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); + } + + if (client_extradata & OMX_EXTNUSER_EXTRADATA && p_extra) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + for(int i = 0; i < extn_user_data_cnt; i++) + { + if (((OMX_U8*)p_extra + p_extn_user[i]->nSize) < + (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) + { + if (p_extn_user[i]->eType == VDEC_EXTRADATA_EXT_DATA) + { + append_extn_extradata(p_extra, p_extn_user[i]); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + else if (p_extn_user[i]->eType == VDEC_EXTRADATA_USER_DATA) + { + append_user_extradata(p_extra, p_extn_user[i]); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + } + } + } + if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra && + ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) < + (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + append_interlace_extradata(p_extra, + ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format, index); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra && + ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < + (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + /* vui extra data (frame_rate) information */ + if (h264_parser) + h264_parser->get_frame_rate(&frame_rate); + append_frame_info_extradata(p_extra, num_conceal_MB, + ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, + p_buf_hdr->nTimeStamp, frame_rate, + &((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + if ((client_extradata & OMX_PORTDEF_EXTRADATA) && + p_extra != NULL && + ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) < + (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + append_portdef_extradata(p_extra); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) + if (p_extra && + ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < + (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) + append_terminator_extradata(p_extra); + else + { + DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added"); + p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + } +} + +void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) +{ + OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_extn_user[32]; + OMX_U32 num_conceal_MB = 0; + OMX_S64 ts_in_sei = 0; + OMX_U32 frame_rate = 0; + OMX_U32 extn_user_data_cnt = 0; + + OMX_U32 index = p_buf_hdr - m_out_mem_ptr; + OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(pBuffer + p_buf_hdr->nOffset + + p_buf_hdr->nFilledLen + 3)&(~3)); + if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) + p_extra = NULL; + if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)) + { + // Process driver extradata + while(p_extra && p_extra->eType != VDEC_EXTRADATA_NONE) + { + DEBUG_PRINT_LOW("handle_extradata : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)", + p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize); + if (p_extra->nSize < p_extra->nDataSize) + { + DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d", + p_extra->nSize, p_extra->nDataSize); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) || + p_extra->nDataSize == 0 || p_extra->nSize == 0) + p_extra = NULL; + continue; + } + if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP) + { + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + num_conceal_MB = count_MB_in_extradata(p_extra); + if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP) + // Map driver extradata to corresponding OMX type + p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB; + else + p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client +#ifdef _ANDROID_ + if (m_debug_concealedmb) { + DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB); + } +#endif /* _ANDROID_ */ + } + else if (p_extra->eType == VDEC_EXTRADATA_SEI) + { + p_sei = p_extra; +#ifdef MAX_RES_1080P + h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); +#endif + p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client + } + else if (p_extra->eType == VDEC_EXTRADATA_VUI) + { + p_vui = p_extra; +#ifdef MAX_RES_1080P + h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); +#endif + p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client + } + else if (p_extra->eType == VDEC_EXTRADATA_EXT_DATA) + { + OMX_U8 *data_ptr = (OMX_U8*)p_extra->data; + OMX_U32 value = 0; + p_extn_user[extn_user_data_cnt] = p_extra; + extn_user_data_cnt++; + if((*data_ptr & 0xf0) == 0x20) + { + value = ((*data_ptr) & 0x01); + data_ptr++; + if (value) + data_ptr += 3; + value = *((OMX_U32*)data_ptr); + value = ((value << 24) | (((value >> 8)<<24)>>8) | + (((value >> 16)<<24)>>16) | (value >> 24)); + m_disp_hor_size = (value & 0xfffc0000)>>18; + m_disp_vert_size = (value & 0x0001fff8)>>3; + DEBUG_PRINT_LOW("Display Vertical Size = %d Display Horizontal Size = %d", + m_disp_vert_size, m_disp_hor_size); + } + } + else if (p_extra->eType == VDEC_EXTRADATA_USER_DATA) + { + p_extn_user[extn_user_data_cnt] = p_extra; + extn_user_data_cnt++; + } + print_debug_extradata(p_extra); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) || + p_extra->nDataSize == 0 || p_extra->nSize == 0) + p_extra = NULL; + } + if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)) + { + // Driver extradata is only exposed if MB map is requested by client, + // otherwise can be overwritten by omx extradata. + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(pBuffer + p_buf_hdr->nOffset + + p_buf_hdr->nFilledLen + 3)&(~3)); + p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + } + } + +#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + if (p_vui) + h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); + if (p_sei) + h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); + ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp); + if (!VALID_TS(p_buf_hdr->nTimeStamp)) + p_buf_hdr->nTimeStamp = ts_in_sei; + } + else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei) + // If timeinfo is present frame info from SEI is already processed + h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); + } +#endif + if (client_extradata & OMX_EXTNUSER_EXTRADATA && p_extra) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + for(int i = 0; i < extn_user_data_cnt; i++) + { + if (((OMX_U8*)p_extra + p_extn_user[i]->nSize) < + (pBuffer + p_buf_hdr->nAllocLen)) + { + if (p_extn_user[i]->eType == VDEC_EXTRADATA_EXT_DATA) + { + append_extn_extradata(p_extra, p_extn_user[i]); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + else if (p_extn_user[i]->eType == VDEC_EXTRADATA_USER_DATA) + { + append_user_extradata(p_extra, p_extn_user[i]); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + } + } + } + if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra && + ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) < + (pBuffer + p_buf_hdr->nAllocLen)) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + append_interlace_extradata(p_extra, + ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format, index); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra && + ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < + (pBuffer + p_buf_hdr->nAllocLen)) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + /* vui extra data (frame_rate) information */ + if (h264_parser) + h264_parser->get_frame_rate(&frame_rate); + append_frame_info_extradata(p_extra, num_conceal_MB, + ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, + p_buf_hdr->nTimeStamp, frame_rate, + &((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + if ((client_extradata & OMX_PORTDEF_EXTRADATA) && + p_extra != NULL && + ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) < + (pBuffer + p_buf_hdr->nAllocLen)) + { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + append_portdef_extradata(p_extra); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) + if (p_extra && + ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < + (pBuffer + p_buf_hdr->nAllocLen)) + append_terminator_extradata(p_extra); + else + { + DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added"); + p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + } +} + +OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, bool enable) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_U32 driver_extradata = 0, extradata_size = 0; + struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); + return OMX_ErrorIncorrectStateOperation; + } + if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) + extradata_size += OMX_FRAMEINFO_EXTRADATA_SIZE; + if (requested_extradata & OMX_INTERLACE_EXTRADATA) + extradata_size += OMX_INTERLACE_EXTRADATA_SIZE; + if (requested_extradata & OMX_PORTDEF_EXTRADATA) + { + extradata_size += OMX_PORTDEF_EXTRADATA_SIZE; + } + DEBUG_PRINT_ERROR("enable_extradata: actual[%x] requested[%x] enable[%d]", + client_extradata, requested_extradata, enable); + + if (enable) + requested_extradata |= client_extradata; + else + { + requested_extradata = client_extradata & ~requested_extradata; + extradata_size *= -1; + } + + driver_extradata = requested_extradata & DRIVER_EXTRADATA_MASK; + + if(secure_mode) + driver_extradata = driver_extradata | VDEC_EXTRADATA_EXT_BUFFER; + + if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) + driver_extradata |= VDEC_EXTRADATA_MB_ERROR_MAP; // Required for conceal MB frame info + if (drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) + { + driver_extradata |= ((requested_extradata & OMX_EXTNUSER_EXTRADATA)? + VDEC_EXTRADATA_EXT_DATA | VDEC_EXTRADATA_USER_DATA : 0); + } +#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + driver_extradata |= ((requested_extradata & OMX_FRAMEINFO_EXTRADATA)? + VDEC_EXTRADATA_SEI : 0); // Required for pan scan frame info + driver_extradata |= ((requested_extradata & OMX_TIMEINFO_EXTRADATA)? + VDEC_EXTRADATA_VUI | VDEC_EXTRADATA_SEI : 0); //Required for time info + } + +#endif + if (driver_extradata != drv_ctx.extradata) + { + client_extradata = requested_extradata; + drv_ctx.extradata = driver_extradata; + ioctl_msg.in = &drv_ctx.extradata; + ioctl_msg.out = NULL; + if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_EXTRADATA, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nSet extradata failed"); + ret = OMX_ErrorUnsupportedSetting; + } + else + ret = get_buffer_req(&drv_ctx.op_buf); + } + else if ((client_extradata & ~DRIVER_EXTRADATA_MASK) != (requested_extradata & ~DRIVER_EXTRADATA_MASK)) + { + client_extradata = requested_extradata; + drv_ctx.op_buf.buffer_size += extradata_size; + // align the buffer size + drv_ctx.op_buf.buffer_size = (drv_ctx.op_buf.buffer_size + drv_ctx.op_buf.alignment - 1)&(~(drv_ctx.op_buf.alignment - 1)); + DEBUG_PRINT_LOW("Aligned buffer size with exreadata = %d", drv_ctx.op_buf.buffer_size); + if (!(client_extradata & ~DRIVER_EXTRADATA_MASK)) // If no omx extradata is required remove space for terminator + drv_ctx.op_buf.buffer_size -= sizeof(OMX_OTHER_EXTRADATATYPE); + ret = set_buffer_req(&drv_ctx.op_buf); + } + return ret; +} + +OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; + OMX_U8 *data_ptr = extra->data, data = 0; + while (byte_count < extra->nDataSize) + { + data = *data_ptr; + while (data) + { + num_MB += (data&0x01); + data >>= 1; + } + data_ptr++; + byte_count++; + } + num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * + (drv_ctx.video_resolution.frame_height + 15)) >> 8; + return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); +} + +void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ +#ifdef _ANDROID_ + if (!m_debug_extradata) + return; + + DEBUG_PRINT_HIGH( + "============== Extra Data ==============\n" + " Size: %u \n" + " Version: %u \n" + " PortIndex: %u \n" + " Type: %x \n" + " DataSize: %u \n", + extra->nSize, extra->nVersion.nVersion, + extra->nPortIndex, extra->eType, extra->nDataSize); + + if (extra->eType == OMX_ExtraDataInterlaceFormat) + { + OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; + DEBUG_PRINT_HIGH( + "------ Interlace Format ------\n" + " Size: %u \n" + " Version: %u \n" + " PortIndex: %u \n" + " Is Interlace Format: %u \n" + " Interlace Formats: %u \n" + "=========== End of Interlace ===========\n", + intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, + intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); + } + else if (extra->eType == OMX_ExtraDataFrameInfo) + { + OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; + + DEBUG_PRINT_HIGH( + "-------- Frame Format --------\n" + " Picture Type: %u \n" + " Interlace Type: %u \n" + " Pan Scan Total Frame Num: %u \n" + " Concealed Macro Blocks: %u \n" + " frame rate: %u \n" + " Aspect Ratio X: %u \n" + " Aspect Ratio Y: %u \n", + fminfo->ePicType, + fminfo->interlaceType, + fminfo->panScan.numWindows, + fminfo->nConcealedMacroblocks, + fminfo->nFrameRate, + fminfo->aspectRatio.aspectRatioX, + fminfo->aspectRatio.aspectRatioY); + + for (int i = 0; i < fminfo->panScan.numWindows; i++) + { + DEBUG_PRINT_HIGH( + "------------------------------\n" + " Pan Scan Frame Num: %d \n" + " Rectangle x: %d \n" + " Rectangle y: %d \n" + " Rectangle dx: %d \n" + " Rectangle dy: %d \n", + i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, + fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); + } + + DEBUG_PRINT_HIGH("========= End of Frame Format =========="); + } + else if (extra->eType == OMX_ExtraDataNone) + { + DEBUG_PRINT_HIGH("========== End of Terminator ==========="); + } + else + { + DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); + } +#endif /* _ANDROID_ */ +} + +void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 interlaced_format_type, OMX_U32 buf_index) +{ + OMX_STREAMINTERLACEFORMAT *interlace_format; + OMX_U32 mbaff = 0; +#if defined(_ANDROID_ICS_) + OMX_U32 enable = 0; + private_handle_t *handle = NULL; + handle = (private_handle_t *)native_buffer[buf_index].nativehandle; + if(!handle) + DEBUG_PRINT_LOW("%s: Native Buffer handle is NULL",__func__); +#endif + extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; + extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); + interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; + interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); + interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; + interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; + if ((interlaced_format_type == VDEC_InterlaceFrameProgressive) && !mbaff) + { + interlace_format->bInterlaceFormat = OMX_FALSE; + interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; +#if defined(_ANDROID_ICS_) + if(handle) + { + setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable); + } +#endif + } + else + { + interlace_format->bInterlaceFormat = OMX_TRUE; + interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; + drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; +#if defined(_ANDROID_ICS_) + enable = 1; + if(handle) + { + setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable); + } +#endif + } + print_debug_extradata(extra); +} + +void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_S64 timestamp, + OMX_U32 frame_rate, struct vdec_aspectratioinfo *aspect_ratio_info) +{ + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; + extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; + extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); + frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; + + switch (picture_type) + { + case PICTURE_TYPE_I: + frame_info->ePicType = OMX_VIDEO_PictureTypeI; + break; + case PICTURE_TYPE_P: + frame_info->ePicType = OMX_VIDEO_PictureTypeP; + break; + case PICTURE_TYPE_B: + frame_info->ePicType = OMX_VIDEO_PictureTypeB; + break; + default: + frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; + } + if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) + frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; + else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) + frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; + else + frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; + memset(&frame_info->panScan,0,sizeof(frame_info->panScan)); + memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); + memset(&frame_info->displayAspectRatio, 0, sizeof(frame_info->displayAspectRatio)); + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + h264_parser->fill_pan_scan_data(&frame_info->panScan, timestamp); + } + + fill_aspect_ratio_info(aspect_ratio_info, frame_info); + if (drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) + { + if (m_disp_hor_size && m_disp_vert_size) + { + frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size; + frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size; + } + } + frame_info->nConcealedMacroblocks = num_conceal_mb; + frame_info->nFrameRate = frame_rate; + print_debug_extradata(extra); +} + +void omx_vdec::fill_aspect_ratio_info( + struct vdec_aspectratioinfo *aspect_ratio_info, + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) +{ + m_extradata = frame_info; + if(drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) + { + switch(aspect_ratio_info->aspect_ratio) + { + case 1: + m_extradata->aspectRatio.aspectRatioX = 1; + m_extradata->aspectRatio.aspectRatioY = 1; + break; + case 2: + if (m_disp_hor_size && m_disp_vert_size) + { + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * + m_disp_vert_size; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * + m_disp_hor_size; + } + else + { + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * + drv_ctx.video_resolution.frame_height; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * + drv_ctx.video_resolution.frame_width; + } + break; + case 3: + if (m_disp_hor_size && m_disp_vert_size) + { + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * + m_disp_vert_size; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * + m_disp_hor_size; + } + else + { + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * + drv_ctx.video_resolution.frame_height; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * + drv_ctx.video_resolution.frame_width; + } + break; + case 4: + if (m_disp_hor_size && m_disp_vert_size) + { + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * + m_disp_vert_size; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * + m_disp_hor_size; + } + else + { + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * + drv_ctx.video_resolution.frame_height; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * + drv_ctx.video_resolution.frame_width; + } + break; + default: + m_extradata->aspectRatio.aspectRatioX = 1; + m_extradata->aspectRatio.aspectRatioY = 1; + } + } + else + { + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; + } + DEBUG_PRINT_LOW("aspectRatioX %d aspectRatioX %d", m_extradata->aspectRatio.aspectRatioX, + m_extradata->aspectRatio.aspectRatioY); +} + +void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; + extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; + extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; + *portDefn = m_port_def; + DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u" + "sliceheight = %u",portDefn->format.video.nFrameHeight, + portDefn->format.video.nFrameWidth, + portDefn->format.video.nStride, + portDefn->format.video.nSliceHeight); +} + +void omx_vdec::append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_OTHER_EXTRADATATYPE *p_extn) +{ + extra->nDataSize = p_extn->nDataSize; + extra->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + extra->nDataSize); + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2ExtnData; + if (extra->data && p_extn->data && extra->nDataSize) + memcpy(extra->data, p_extn->data, extra->nDataSize); +} + +void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_OTHER_EXTRADATATYPE *p_user) +{ + extra->nDataSize = p_user->nDataSize; + extra->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + extra->nDataSize); + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData; + if (extra->data && p_user->data && extra->nDataSize) + memcpy(extra->data, p_user->data, extra->nDataSize); +} + +void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->eType = OMX_ExtraDataNone; + extra->nDataSize = 0; + extra->data[0] = 0; + + print_debug_extradata(extra); +} + +OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (index >= drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found"); + return OMX_ErrorInsufficientResources; + } + if (m_desc_buffer_ptr == NULL) + { + m_desc_buffer_ptr = (desc_buffer_hdr*) \ + calloc( (sizeof(desc_buffer_hdr)), + drv_ctx.ip_buf.actualcount); + if (m_desc_buffer_ptr == NULL) + { + DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + } + + m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); + if (m_desc_buffer_ptr[index].buf_addr == NULL) + { + DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed "); + return OMX_ErrorInsufficientResources; + } + + return eRet; +} + +void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) +{ + DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries); + if (m_demux_entries < 8192) + { + m_demux_offsets[m_demux_entries++] = address_offset; + } + return; +} + +void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) +{ + OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; + OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; + OMX_U32 index = 0; + OMX_U32 prev_sc_index = 0; + + m_demux_entries = 0; + + while (index < bytes_to_parse) + { + if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && + (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || + ((buf[index] == 0x00) && (buf[index+1] == 0x00) && + (buf[index+2] == 0x01)) ) + { + if ((((index+3) - prev_sc_index) <= 4) && m_demux_entries) + { + DEBUG_PRINT_ERROR("FOUND Consecutive start Code, Hence skip one"); + m_demux_entries--; + } + //Found start code, insert address offset + insert_demux_addr_offset(index); + if (buf[index+2] == 0x01) // 3 byte start code + index += 3; + else //4 byte start code + index += 4; + prev_sc_index = index; + } + else + index++; + } + DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries); + return; +} + +OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) +{ + //fix this, handle 3 byte start code, vc1 terminator entry + OMX_U8 *p_demux_data = NULL; + OMX_U32 desc_data = 0; + OMX_U32 start_addr = 0; + OMX_U32 nal_size = 0; + OMX_U32 suffix_byte = 0; + OMX_U32 demux_index = 0; + OMX_U32 buffer_index = 0; + + if (m_desc_buffer_ptr == NULL) + { + DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); + return OMX_ErrorBadParameter; + } + + buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + if (buffer_index > drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index); + return OMX_ErrorBadParameter; + } + + p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; + + if ( ((OMX_U8*)p_demux_data == NULL) || + ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) + { + DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); + return OMX_ErrorBadParameter; + } + else + { + for (; demux_index < m_demux_entries; demux_index++) + { + desc_data = 0; + start_addr = m_demux_offsets[demux_index]; + if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) + { + suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; + } + else + { + suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; + } + if (demux_index < (m_demux_entries - 1)) + { + nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; + } + else + { + nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; + } + DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)", + start_addr, + suffix_byte, + nal_size, + demux_index); + desc_data = (start_addr >> 3) << 1; + desc_data |= (start_addr & 7) << 21; + desc_data |= suffix_byte << 24; + + memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); + memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); + memset(p_demux_data + 8, 0, sizeof(OMX_U32)); + memset(p_demux_data + 12, 0, sizeof(OMX_U32)); + + p_demux_data += 16; + } + if (codec_type_parse == CODEC_TYPE_VC1) + { + DEBUG_PRINT_LOW("VC1 terminator entry"); + desc_data = 0; + desc_data = 0x82 << 24; + memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); + memset(p_demux_data + 4, 0, sizeof(OMX_U32)); + memset(p_demux_data + 8, 0, sizeof(OMX_U32)); + memset(p_demux_data + 12, 0, sizeof(OMX_U32)); + p_demux_data += 16; + m_demux_entries++; + } + //Add zero word to indicate end of descriptors + memset(p_demux_data, 0, sizeof(OMX_U32)); + + m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); + DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size); + } + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + DEBUG_PRINT_LOW("Demux table complete!"); + return OMX_ErrorNone; +} + +#ifdef MAX_RES_1080P + +OMX_ERRORTYPE omx_vdec::vdec_alloc_meta_buffers() +{ + OMX_U32 pmem_fd = -1, pmem_fd_iommu = -1; + OMX_U32 size, alignment; + void *buf_addr = NULL; + struct vdec_ioctl_msg ioctl_msg; +#ifndef USE_ION + struct pmem_allocation allocation; +#endif + struct vdec_meta_buffers meta_buffer; + + memset ((unsigned char*)&meta_buffer,0,sizeof (struct vdec_meta_buffers)); + + //we already have meta buffer size. + size = drv_ctx.op_buf.meta_buffer_size * drv_ctx.op_buf.actualcount; + alignment = 8192; + + +#ifdef USE_ION + external_meta_buffer = true; + drv_ctx.meta_buffer.ion_device_fd = alloc_map_ion_memory( + size, 8192, + &drv_ctx.meta_buffer.ion_alloc_data, + &drv_ctx.meta_buffer.fd_ion_data, 0); + if (drv_ctx.meta_buffer.ion_device_fd < 0) { + external_meta_buffer = false; + return OMX_ErrorInsufficientResources; + } + external_meta_buffer = false; + pmem_fd = drv_ctx.meta_buffer.fd_ion_data.fd; + + external_meta_buffer_iommu = true; + drv_ctx.meta_buffer_iommu.ion_device_fd = alloc_map_ion_memory( + size, 8192, + &drv_ctx.meta_buffer_iommu.ion_alloc_data, + &drv_ctx.meta_buffer_iommu.fd_ion_data, 0); + if (drv_ctx.meta_buffer_iommu.ion_device_fd < 0) { + external_meta_buffer_iommu = false; + return OMX_ErrorInsufficientResources; + } + external_meta_buffer_iommu = false; + pmem_fd_iommu = drv_ctx.meta_buffer_iommu.fd_ion_data.fd; +#else + allocation.size = size; + allocation.align = clip2(alignment); + if (allocation.align != 8192) + allocation.align = 8192; + + pmem_fd = open(MEM_DEVICE, O_RDWR); + + if ((int)(pmem_fd) < 0) + return OMX_ErrorInsufficientResources; + + if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) + { + DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", + allocation.align, allocation.size); + return OMX_ErrorInsufficientResources; + } +#endif + + buf_addr = mmap(NULL, size, + PROT_READ | PROT_WRITE, + MAP_SHARED, pmem_fd_iommu, 0); + + if (buf_addr == (void*) MAP_FAILED) + { + close(pmem_fd); + close(pmem_fd_iommu); +#ifdef USE_ION + free_ion_memory(&drv_ctx.meta_buffer); + free_ion_memory(&drv_ctx.meta_buffer_iommu); +#endif + pmem_fd = -1; + pmem_fd_iommu = -1; + DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr); + return OMX_ErrorInsufficientResources; + } + + meta_buffer.size = size; + meta_buffer.count = drv_ctx.op_buf.actualcount; + meta_buffer.pmem_fd = pmem_fd; + meta_buffer.pmem_fd_iommu = pmem_fd_iommu; + meta_buffer.offset = 0; + + ioctl_msg.in = (void*)&meta_buffer; + ioctl_msg.out = NULL; + + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_META_BUFFERS, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Failed to set the meta_buffers\n"); + return OMX_ErrorInsufficientResources; + } + + meta_buff.buffer = (unsigned char *) buf_addr; + meta_buff.size = size; + meta_buff.count = drv_ctx.op_buf.actualcount; + meta_buff.offset = 0; + meta_buff.pmem_fd = pmem_fd; + meta_buff.pmem_fd_iommu = pmem_fd_iommu; + DEBUG_PRINT_HIGH("Saving virt:%p, FD: %d and FD_IOMMU %d of size %d count: %d", meta_buff.buffer, + meta_buff.pmem_fd, meta_buff.pmem_fd_iommu, meta_buff.size, drv_ctx.op_buf.actualcount); + return OMX_ErrorNone; +} + +void omx_vdec::vdec_dealloc_meta_buffers() +{ + if(meta_buff.pmem_fd > 0) + { + if(ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_META_BUFFERS,NULL) < 0) + DEBUG_PRINT_ERROR("VDEC_IOCTL_FREE_META_BUFFERS failed"); + close(meta_buff.pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.meta_buffer); +#endif + } + if(meta_buff.pmem_fd_iommu > 0) + { + munmap(meta_buff.buffer, meta_buff.size); + close(meta_buff.pmem_fd_iommu); +#ifdef USE_ION + free_ion_memory(&drv_ctx.meta_buffer_iommu); +#endif + DEBUG_PRINT_LOW("Cleaning Meta buffer of size %d",meta_buff.size); + meta_buff.pmem_fd = -1; + meta_buff.pmem_fd_iommu = -1; + meta_buff.offset = 0; + meta_buff.size = 0; + meta_buff.count = 0; + meta_buff.buffer = NULL; + } +} + +OMX_ERRORTYPE omx_vdec::vdec_alloc_h264_mv() +{ + OMX_U32 pmem_fd = -1; + OMX_U32 width, height, size, alignment; + void *buf_addr = NULL; + struct vdec_ioctl_msg ioctl_msg; +#ifndef USE_ION + struct pmem_allocation allocation; +#endif + struct vdec_h264_mv h264_mv; + struct vdec_mv_buff_size mv_buff_size; + + mv_buff_size.width = drv_ctx.video_resolution.stride; + mv_buff_size.height = drv_ctx.video_resolution.scan_lines>>2; + + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&mv_buff_size; + + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_GET_MV_BUFFER_SIZE, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n GET_MV_BUFFER_SIZE Failed for width: %d, Height %d" , + mv_buff_size.width, mv_buff_size.height); + return OMX_ErrorInsufficientResources; + } + + DEBUG_PRINT_ERROR("GET_MV_BUFFER_SIZE returned: Size: %d and alignment: %d", + mv_buff_size.size, mv_buff_size.alignment); + + size = mv_buff_size.size * drv_ctx.op_buf.actualcount; + alignment = mv_buff_size.alignment; + + DEBUG_PRINT_LOW("Entered vdec_alloc_h264_mv act_width: %d, act_height: %d, size: %d, alignment %d", + drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height,size,alignment); + + +#ifdef USE_ION + drv_ctx.h264_mv.ion_device_fd = alloc_map_ion_memory( + size, 8192, + &drv_ctx.h264_mv.ion_alloc_data, + &drv_ctx.h264_mv.fd_ion_data,ION_FLAG_CACHED); + if (drv_ctx.h264_mv.ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + pmem_fd = drv_ctx.h264_mv.fd_ion_data.fd; +#else + allocation.size = size; + allocation.align = clip2(alignment); + if (allocation.align != 8192) + allocation.align = 8192; + + pmem_fd = open(MEM_DEVICE, O_RDWR); + + if ((int)(pmem_fd) < 0) + return OMX_ErrorInsufficientResources; + + if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) + { + DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", + allocation.align, allocation.size); + return OMX_ErrorInsufficientResources; + } +#endif + if(!secure_mode) { + buf_addr = mmap(NULL, size, + PROT_READ | PROT_WRITE, + MAP_SHARED, pmem_fd, 0); + + if (buf_addr == (void*) MAP_FAILED) + { + close(pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.h264_mv); +#endif + pmem_fd = -1; + DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr); + return OMX_ErrorInsufficientResources; + } + } else + buf_addr =(unsigned char *) (pmem_fd + 1234); + DEBUG_PRINT_LOW("Allocated virt:%p, FD: %d of size %d count: %d", buf_addr, + pmem_fd, size, drv_ctx.op_buf.actualcount); + + h264_mv.size = size; + h264_mv.count = drv_ctx.op_buf.actualcount; + h264_mv.pmem_fd = pmem_fd; + h264_mv.offset = 0; + + ioctl_msg.in = (void*)&h264_mv; + ioctl_msg.out = NULL; + + if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_H264_MV_BUFFER, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Failed to set the H264_mv_buffers\n"); + return OMX_ErrorInsufficientResources; + } + + h264_mv_buff.buffer = (unsigned char *) buf_addr; + h264_mv_buff.size = size; + h264_mv_buff.count = drv_ctx.op_buf.actualcount; + h264_mv_buff.offset = 0; + h264_mv_buff.pmem_fd = pmem_fd; + DEBUG_PRINT_LOW("Saving virt:%p, FD: %d of size %d count: %d", h264_mv_buff.buffer, + h264_mv_buff.pmem_fd, h264_mv_buff.size, drv_ctx.op_buf.actualcount); + return OMX_ErrorNone; +} + +void omx_vdec::vdec_dealloc_h264_mv() +{ + if(h264_mv_buff.pmem_fd > 0) + { + if(ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_H264_MV_BUFFER,NULL) < 0) + DEBUG_PRINT_ERROR("VDEC_IOCTL_FREE_H264_MV_BUFFER failed"); + if(!secure_mode) + munmap(h264_mv_buff.buffer, h264_mv_buff.size); + close(h264_mv_buff.pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.h264_mv); +#endif + DEBUG_PRINT_LOW("Cleaning H264_MV buffer of size %d",h264_mv_buff.size); + h264_mv_buff.pmem_fd = -1; + h264_mv_buff.offset = 0; + h264_mv_buff.size = 0; + h264_mv_buff.count = 0; + h264_mv_buff.buffer = NULL; + } +} + +#endif + +#ifdef _ANDROID_ +OMX_ERRORTYPE omx_vdec::createDivxDrmContext() +{ + OMX_ERRORTYPE err = OMX_ErrorNone; + iDivXDrmDecrypt = DivXDrmDecrypt::Create(); + if (iDivXDrmDecrypt) { + OMX_ERRORTYPE err = iDivXDrmDecrypt->Init(); + if(err!=OMX_ErrorNone) { + DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err); + delete iDivXDrmDecrypt; + iDivXDrmDecrypt = NULL; + } + } + else { + DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM"); + err = OMX_ErrorUndefined; + } + return err; +} +#endif //_ANDROID_ + +OMX_ERRORTYPE omx_vdec::power_module_register() +{ + char powerHintMetadata[512]; + + if (m_power_hinted) { + return OMX_ErrorBadParameter; //need a proper error code + } + + PowerModule * pm = PowerModule::getInstance(); + + if (pm == NULL) { + DEBUG_PRINT_ERROR("failed to get power module instance"); + return OMX_ErrorBadParameter; + } + + power_module_t * ph = pm->getPowerModuleHandle(); + + if (ph == NULL) { + DEBUG_PRINT_ERROR("failed to get power module handle"); + return OMX_ErrorBadParameter; + } + + if (ph->powerHint) { + snprintf(powerHintMetadata, sizeof(powerHintMetadata) - 1, + "state=1;framewidth=%u;frameheight=%u;bitrate=%u", + m_port_def.format.video.nFrameWidth, m_port_def.format.video.nFrameHeight, + m_port_def.format.video.nBitrate); + powerHintMetadata[sizeof(powerHintMetadata) - 1] = '\0'; + + ph->powerHint(ph, POWER_HINT_VIDEO_DECODE, (void *)powerHintMetadata); + m_power_hinted = true; + } else { + DEBUG_PRINT_ERROR("No hint called for register"); + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::power_module_deregister() +{ + if (!m_power_hinted) { + return OMX_ErrorBadParameter; //need a proper error code + } + + PowerModule * pm = PowerModule::getInstance(); + + if (pm == NULL) { + DEBUG_PRINT_ERROR("failed to get power module instance"); + return OMX_ErrorBadParameter; + } + + power_module_t * ph = pm->getPowerModuleHandle(); + + if (ph == NULL) { + DEBUG_PRINT_ERROR("failed to get power module handle"); + return OMX_ErrorBadParameter; + } + + if (ph->powerHint) { + ph->powerHint(ph, POWER_HINT_VIDEO_DECODE, (void *)"state=0"); + m_power_hinted = false; + } else { + DEBUG_PRINT_ERROR("No hint called for deregister"); + } + return OMX_ErrorNone; +} +omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() +{ + enabled = false; + omx = NULL; + init_members(); + ColorFormat = OMX_COLOR_FormatMax; +} + +void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) +{ + omx = reinterpret_cast(client); +} + +void omx_vdec::allocate_color_convert_buf::init_members() { + allocated_count = 0; + buffer_size_req = 0; + buffer_alignment_req = 0; + memset(m_platform_list_client,0,sizeof(m_platform_list_client)); + memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); + memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); + memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); + memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); + for (int i = 0; i < MAX_COUNT;i++) + pmem_fd[i] = -1; +} + +omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() { + c2d.destroy(); +} + +bool omx_vdec::allocate_color_convert_buf::update_buffer_req() +{ + bool status = true; + unsigned int src_size = 0, destination_size = 0; + OMX_COLOR_FORMATTYPE drv_color_format; + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid client in color convert"); + return false; + } + if (!enabled){ + DEBUG_PRINT_ERROR("\n No color conversion required"); + return status; + } + if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_TILE_4x2 && + ColorFormat != OMX_COLOR_FormatYUV420Planar) { + DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion"); + return false; + } + c2d.close(); + status = c2d.open(omx->drv_ctx.video_resolution.frame_height, + omx->drv_ctx.video_resolution.frame_width, + YCbCr420Tile,YCbCr420P); + if (status) { + status = c2d.get_buffer_size(C2D_INPUT,src_size); + if (status) + status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); + } + if (status) { + if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || + !destination_size) { + DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d" + "driver size %d destination size %d", + src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); + status = false; + c2d.close(); + buffer_size_req = 0; + } else { + buffer_size_req = destination_size; + if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) + buffer_size_req = omx->drv_ctx.op_buf.buffer_size; + if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) + buffer_alignment_req = omx->drv_ctx.op_buf.alignment; + } + } + return status; +} + +bool omx_vdec::allocate_color_convert_buf::set_color_format( + OMX_COLOR_FORMATTYPE dest_color_format) +{ + bool status = true; + OMX_COLOR_FORMATTYPE drv_color_format; + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid client in color convert"); + return false; + } + if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2) + drv_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; + else { + DEBUG_PRINT_ERROR("\n Incorrect color format"); + status = false; + } + if (status && (drv_color_format != dest_color_format)) { + DEBUG_PRINT_ERROR(""); + if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { + DEBUG_PRINT_ERROR("\n Unsupported color format for c2d"); + status = false; + } else { + ColorFormat = OMX_COLOR_FormatYUV420Planar; + if (enabled) + c2d.destroy(); + enabled = false; + if (!c2d.init()) { + DEBUG_PRINT_ERROR("\n open failed for c2d"); + status = false; + } else + enabled = true; + } + } else { + if (enabled) + c2d.destroy(); + enabled = false; + } + return status; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return omx->m_out_mem_ptr; + return m_out_mem_ptr_client; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr + (OMX_BUFFERHEADERTYPE *bufadd) +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return bufadd; + unsigned index = 0; + index = bufadd - omx->m_out_mem_ptr; + if (index < omx->drv_ctx.op_buf.actualcount) { + m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); + m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; + bool status; + if (!omx->in_reconfig && !omx->output_flush_progress) { + status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, + bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]); + m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; + if (!status){ + DEBUG_PRINT_ERROR("\n Failed color conversion %d", status); + return NULL; + } + } else + m_out_mem_ptr_client[index].nFilledLen = 0; + return &m_out_mem_ptr_client[index]; + } + DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr"); + return NULL; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr + (OMX_BUFFERHEADERTYPE *bufadd) +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return bufadd; + unsigned index = 0; + index = bufadd - m_out_mem_ptr_client; + if (index < omx->drv_ctx.op_buf.actualcount) { + return &omx->m_out_mem_ptr[index]; + } + DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr"); + return NULL; +} +bool omx_vdec::allocate_color_convert_buf::get_buffer_req + (unsigned int &buffer_size) +{ + if (!enabled) + buffer_size = omx->drv_ctx.op_buf.buffer_size; + else + if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { + DEBUG_PRINT_ERROR("\n Get buffer size failed"); + return false; + } + if (buffer_size < omx->drv_ctx.op_buf.buffer_size) + buffer_size = omx->drv_ctx.op_buf.buffer_size; + if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) + buffer_alignment_req = omx->drv_ctx.op_buf.alignment; + return true; +} +OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( + OMX_BUFFERHEADERTYPE *bufhdr) { + unsigned int index = 0; + + if (!enabled) + return omx->free_output_buffer(bufhdr); + if (enabled && omx->is_component_secure()) + return OMX_ErrorNone; + if (!allocated_count || !bufhdr) { + DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr); + return OMX_ErrorBadParameter; + } + index = bufhdr - m_out_mem_ptr_client; + if (index >= omx->drv_ctx.op_buf.actualcount){ + DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer"); + return OMX_ErrorBadParameter; + } + if (pmem_fd[index] > 0) { + munmap(pmem_baseaddress[index], buffer_size_req); + close(pmem_fd[index]); + } + pmem_fd[index] = -1; + omx->free_ion_memory(&op_buf_ion_info[index]); + m_heap_ptr[index].video_heap_ptr = NULL; + if (allocated_count > 0) + allocated_count--; + else + allocated_count = 0; + if (!allocated_count) { + c2d.close(); + init_members(); + } + return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); +} + +OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (!enabled){ + eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); + return eRet; + } + if (enabled && omx->is_component_secure()) { + DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d", + omx->is_component_secure()); + return OMX_ErrorUnsupportedSetting; + } + if (!bufferHdr || bytes > buffer_size_req) { + DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr); + DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %d", + buffer_size_req,bytes); + return OMX_ErrorBadParameter; + } + if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert"); + return OMX_ErrorInsufficientResources; + } + OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; + eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, + port,appData,omx->drv_ctx.op_buf.buffer_size); + if (eRet != OMX_ErrorNone || !temp_bufferHdr){ + DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert"); + return eRet; + } + if ((temp_bufferHdr - omx->m_out_mem_ptr) >= + omx->drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("\n Invalid header index %d", + (temp_bufferHdr - omx->m_out_mem_ptr)); + return OMX_ErrorUndefined; + } + unsigned int i = allocated_count; + op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( + buffer_size_req,buffer_alignment_req, + &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, + ION_FLAG_CACHED); + + pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; + if (op_buf_ion_info[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert"); + return OMX_ErrorInsufficientResources; + } + pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, + PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); + + if (pmem_baseaddress[i] == MAP_FAILED) { + DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req); + close(pmem_fd[i]); + omx->free_ion_memory(&op_buf_ion_info[i]); + return OMX_ErrorInsufficientResources; + } + m_heap_ptr[i].video_heap_ptr = new VideoHeap ( + op_buf_ion_info[i].ion_device_fd,buffer_size_req, + pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); + m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); + m_pmem_info_client[i].offset = 0; + m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; + m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + m_platform_list_client[i].nEntries = 1; + m_platform_list_client[i].entryList = &m_platform_entry_client[i]; + m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; + m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; + m_out_mem_ptr_client[i].nFilledLen = 0; + m_out_mem_ptr_client[i].nFlags = 0; + m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); + m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; + m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; + m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; + m_out_mem_ptr_client[i].pAppPrivate = appData; + *bufferHdr = &m_out_mem_ptr_client[i]; + DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr); + allocated_count++; + return eRet; +} + +bool omx_vdec::is_component_secure() +{ + return secure_mode; +} + +bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) +{ + bool status = true; + if (!enabled) { + if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2) + dest_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; + else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) + dest_color_format = OMX_COLOR_FormatYUV420SemiPlanar; + else + status = false; + } else { + if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { + status = false; + } else + dest_color_format = OMX_COLOR_FormatYUV420Planar; + } + return status; +} diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp new file mode 100644 index 00000000..2b8fc200 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp @@ -0,0 +1,9516 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +/*============================================================================ + O p e n M A X w r a p p e r s + O p e n M A X C o r e + +*//** @file omx_vdec.cpp + This module contains the implementation of the OpenMAX core & component. + +*//*========================================================================*/ + +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include "omx_vdec_hevc.h" +#include +#include +#include + +#ifndef _ANDROID_ +#include +#include +#endif //_ANDROID_ + +#ifdef _ANDROID_ +#include +#undef USE_EGL_IMAGE_GPU +#endif + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +#include +#endif + +#if defined (_ANDROID_ICS_) +#include +#include +#endif + +#ifdef _ANDROID_ +#include "DivXDrmDecrypt.h" +#endif //_ANDROID_ + +#ifdef USE_EGL_IMAGE_GPU +#include +#include +#define EGL_BUFFER_HANDLE_QCOM 0x4F00 +#define EGL_BUFFER_OFFSET_QCOM 0x4F01 +#endif + +#ifdef INPUT_BUFFER_LOG +#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" +#define INPUT_BUFFER_FILE_NAME_LEN 30 +FILE *inputBufferFile1; +char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; +#endif +#ifdef OUTPUT_BUFFER_LOG +FILE *outputBufferFile1; +char outputfilename [] = "/data/output.yuv"; +#endif +#ifdef OUTPUT_EXTRADATA_LOG +FILE *outputExtradataFile; +char ouputextradatafilename [] = "/data/extradata"; +#endif + +#define DEFAULT_FPS 30 +#define MAX_INPUT_ERROR DEFAULT_FPS +#define MAX_SUPPORTED_FPS 120 + +#define VC1_SP_MP_START_CODE 0xC5000000 +#define VC1_SP_MP_START_CODE_MASK 0xFF000000 +#define VC1_AP_SEQ_START_CODE 0x0F010000 +#define VC1_STRUCT_C_PROFILE_MASK 0xF0 +#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 +#define VC1_SIMPLE_PROFILE 0 +#define VC1_MAIN_PROFILE 1 +#define VC1_ADVANCE_PROFILE 3 +#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 +#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 +#define VC1_STRUCT_C_LEN 4 +#define VC1_STRUCT_C_POS 8 +#define VC1_STRUCT_A_POS 12 +#define VC1_STRUCT_B_POS 24 +#define VC1_SEQ_LAYER_SIZE 36 +#define POLL_TIMEOUT 0x7fffffff + +#define MEM_DEVICE "/dev/ion" +#define MEM_HEAP_ID ION_CP_MM_HEAP_ID + +#ifdef _ANDROID_ + extern "C"{ + #include + } +#endif//_ANDROID_ + +#define SZ_4K 0x1000 +#define SZ_1M 0x100000 + +#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } +#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } +#define EXTRADATA_IDX(__num_planes) (__num_planes - 1) + +#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA) +void* async_message_thread (void *input) +{ + OMX_BUFFERHEADERTYPE *buffer; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + struct pollfd pfd; + struct v4l2_buffer v4l2_buf; + memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); + struct v4l2_event dqevent; + omx_vdec *omx = reinterpret_cast(input); + pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; + pfd.fd = omx->drv_ctx.video_driver_fd; + int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; + DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n"); + prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); + while (1) + { + rc = poll(&pfd, 1, POLL_TIMEOUT); + if (!rc) { + DEBUG_PRINT_ERROR("Poll timedout\n"); + break; + } else if (rc < 0) { + DEBUG_PRINT_ERROR("Error while polling: %d\n", rc); + break; + } + if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { + struct vdec_msginfo vdec_msg; + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + v4l2_buf.memory = V4L2_MEMORY_USERPTR; + v4l2_buf.length = omx->drv_ctx.num_planes; + v4l2_buf.m.planes = plane; + while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { + vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; + vdec_msg.msgdata.output_frame.len=plane[0].bytesused; + vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; + vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + + (uint64_t)v4l2_buf.timestamp.tv_usec; + if (vdec_msg.msgdata.output_frame.len) { + vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2]; + vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3]; + vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4]; + vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5]; + } + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } + } + if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { + struct vdec_msginfo vdec_msg; + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + v4l2_buf.memory = V4L2_MEMORY_USERPTR; + v4l2_buf.length = 1; + v4l2_buf.m.planes = plane; + while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { + vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } + } + if (pfd.revents & POLLPRI){ + rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); + if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { + struct vdec_msginfo vdec_msg; + vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT ) { + struct vdec_msginfo vdec_msg; + vdec_msg.msgcode=VDEC_MSG_EVT_INFO_CONFIG_CHANGED; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { + struct vdec_msginfo vdec_msg; + vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { + DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n"); + break; + } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { + struct vdec_msginfo vdec_msg; + vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("\n SYS Error Recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } else { + DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n"); + continue; + } + } + } + DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n"); + return NULL; +} + +void* message_thread(void *input) +{ + omx_vdec* omx = reinterpret_cast(input); + unsigned char id; + int n; + if (omx == NULL) + { + DEBUG_PRINT_ERROR("message thread null pointer rxd\n"); + return NULL; + } + + DEBUG_PRINT_HIGH("omx_vdec: message thread start\n"); + prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); + while (1) + { + + n = read(omx->m_pipe_in, &id, 1); + + if(0 == n) + { + break; + } + + if (1 == n) + { + omx->process_event_cb(omx, id); + } + if ((n < 0) && (errno != EINTR)) + { + DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); + break; + } + } + DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n"); + return NULL; +} + +void post_message(omx_vdec *omx, unsigned char id) +{ + int ret_value; + + if (omx == NULL) + { + DEBUG_PRINT_ERROR("message thread null pointer rxd\n"); + return; + } + DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out); + ret_value = write(omx->m_pipe_out, &id, 1); + DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value); +} + +// omx_cmd_queue destructor +omx_vdec::omx_cmd_queue::~omx_cmd_queue() +{ + // Nothing to do +} + +// omx cmd queue constructor +omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) +{ + memset(m_q,0,sizeof(m_q)); +} + +// omx cmd queue insert +bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) +{ + bool ret = true; + if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_q[m_write].id = id; + m_q[m_write].param1 = p1; + m_q[m_write].param2 = p2; + m_write++; + m_size ++; + if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_write = 0; + } + } + else + { + ret = false; + DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__); + } + return ret; +} + +// omx cmd queue pop +bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) +{ + bool ret = true; + if (m_size > 0) + { + *id = m_q[m_read].id; + *p1 = m_q[m_read].param1; + *p2 = m_q[m_read].param2; + // Move the read pointer ahead + ++m_read; + --m_size; + if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_read = 0; + } + } + else + { + ret = false; + } + return ret; +} + +// Retrieve the first mesg type in the queue +unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() +{ + return m_q[m_read].id; +} + +#ifdef _ANDROID_ +omx_vdec::ts_arr_list::ts_arr_list() +{ + //initialize timestamps array + memset(m_ts_arr_list, 0, sizeof(m_ts_arr_list) ); +} +omx_vdec::ts_arr_list::~ts_arr_list() +{ + //free m_ts_arr_list? +} + +bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) +{ + bool ret = true; + bool duplicate_ts = false; + int idx = 0; + + //insert at the first available empty location + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + if (!m_ts_arr_list[idx].valid) + { + //found invalid or empty entry, save timestamp + m_ts_arr_list[idx].valid = true; + m_ts_arr_list[idx].timestamp = ts; + DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", + ts, idx); + break; + } + } + + if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) + { + DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); + ret = false; + } + return ret; +} + +bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) +{ + bool ret = true; + int min_idx = -1; + OMX_TICKS min_ts = 0; + int idx = 0; + + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + + if (m_ts_arr_list[idx].valid) + { + //found valid entry, save index + if (min_idx < 0) + { + //first valid entry + min_ts = m_ts_arr_list[idx].timestamp; + min_idx = idx; + } + else if (m_ts_arr_list[idx].timestamp < min_ts) + { + min_ts = m_ts_arr_list[idx].timestamp; + min_idx = idx; + } + } + + } + + if (min_idx < 0) + { + //no valid entries found + DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); + ts = 0; + ret = false; + } + else + { + ts = m_ts_arr_list[min_idx].timestamp; + m_ts_arr_list[min_idx].valid = false; + DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", + ts, min_idx); + } + + return ret; + +} + + +bool omx_vdec::ts_arr_list::reset_ts_list() +{ + bool ret = true; + int idx = 0; + + DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + m_ts_arr_list[idx].valid = false; + } + return ret; +} +#endif + +// factory function executed by the core to create instances +void *get_omx_component_factory_fn(void) +{ + return (new omx_vdec); +} + +#ifdef _ANDROID_ +#ifdef USE_ION +VideoHeap::VideoHeap(int devicefd, size_t size, void* base, + struct ion_handle *handle, int ionMapfd) +{ +// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); +} +#else +VideoHeap::VideoHeap(int fd, size_t size, void* base) +{ + // dup file descriptor, map once, use pmem + init(dup(fd), base, size, 0 , MEM_DEVICE); +} +#endif +#endif // _ANDROID_ +/* ====================================================================== +FUNCTION + omx_vdec::omx_vdec + +DESCRIPTION + Constructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_vdec::omx_vdec(): m_error_propogated(false), + m_state(OMX_StateInvalid), + m_app_data(NULL), + m_inp_mem_ptr(NULL), + m_out_mem_ptr(NULL), + m_inp_err_count(0), + input_flush_progress (false), + output_flush_progress (false), + input_use_buffer (false), + output_use_buffer (false), + ouput_egl_buffers(false), + m_use_output_pmem(OMX_FALSE), + m_out_mem_region_smi(OMX_FALSE), + m_out_pvt_entry_pmem(OMX_FALSE), + pending_input_buffers(0), + pending_output_buffers(0), + m_out_bm_count(0), + m_inp_bm_count(0), + m_inp_bPopulated(OMX_FALSE), + m_out_bPopulated(OMX_FALSE), + m_flags(0), +#ifdef _ANDROID_ + m_heap_ptr(NULL), +#endif + m_inp_bEnabled(OMX_TRUE), + m_out_bEnabled(OMX_TRUE), + m_in_alloc_cnt(0), + m_platform_list(NULL), + m_platform_entry(NULL), + m_pmem_info(NULL), + arbitrary_bytes (true), + psource_frame (NULL), + pdest_frame (NULL), + m_inp_heap_ptr (NULL), + m_phdr_pmem_ptr(NULL), + m_heap_inp_bm_count (0), + codec_type_parse ((codec_type)0), + first_frame_meta (true), + frame_count (0), + nal_count (0), + nal_length(0), + look_ahead_nal (false), + first_frame(0), + first_buffer(NULL), + first_frame_size (0), + m_device_file_ptr(NULL), + m_vc1_profile((vc1_profile_type)0), + h264_last_au_ts(LLONG_MAX), + h264_last_au_flags(0), + prev_ts(LLONG_MAX), + rst_prev_ts(true), + frm_int(0), + in_reconfig(false), + m_display_id(NULL), + h264_parser(NULL), + client_extradata(0), +#ifdef _ANDROID_ + m_enable_android_native_buffers(OMX_FALSE), + m_use_android_native_buffers(OMX_FALSE), + iDivXDrmDecrypt(NULL), +#endif + m_desc_buffer_ptr(NULL), + secure_mode(false) +{ + /* Assumption is that , to begin with , we have all the frames with decoder */ + DEBUG_PRINT_HIGH("In OMX vdec Constructor"); +#ifdef _ANDROID_ + char property_value[PROPERTY_VALUE_MAX] = {0}; + property_get("vidc.dec.debug.perf", property_value, "0"); + perf_flag = atoi(property_value); + if (perf_flag) + { + DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); + dec_time.start(); + proc_frms = latency = 0; + } + property_value[0] = '\0'; + property_get("vidc.dec.debug.ts", property_value, "0"); + m_debug_timestamp = atoi(property_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); + if (m_debug_timestamp) + { + time_stamp_dts.set_timestamp_reorder_mode(true); + time_stamp_dts.enable_debug_print(true); + } + + property_value[0] = '\0'; + property_get("vidc.dec.debug.concealedmb", property_value, "0"); + m_debug_concealedmb = atoi(property_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); + +#endif + memset(&m_cmp,0,sizeof(m_cmp)); + memset(&m_cb,0,sizeof(m_cb)); + memset (&drv_ctx,0,sizeof(drv_ctx)); + memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); + memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); + memset(m_demux_offsets, 0, sizeof(m_demux_offsets) ); + m_demux_entries = 0; +#ifdef _ANDROID_ICS_ + memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); +#endif + memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); + drv_ctx.timestamp_adjust = false; + drv_ctx.video_driver_fd = -1; + m_vendor_config.pData = NULL; + pthread_mutex_init(&m_lock, NULL); + pthread_mutex_init(&c_lock, NULL); + sem_init(&m_cmd_lock,0,0); + streaming[CAPTURE_PORT] = + streaming[OUTPUT_PORT] = false; +#ifdef _ANDROID_ + char extradata_value[PROPERTY_VALUE_MAX] = {0}; + property_get("vidc.dec.debug.extradata", extradata_value, "0"); + m_debug_extradata = atoi(extradata_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); +#endif + m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; + client_buffers.set_vdec_client(this); +} + +static const int event_type[] = { + V4L2_EVENT_MSM_VIDC_FLUSH_DONE, + V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, + V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, + V4L2_EVENT_MSM_VIDC_CLOSE_DONE, + V4L2_EVENT_MSM_VIDC_SYS_ERROR +}; + +static OMX_ERRORTYPE subscribe_to_events(int fd) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_event_subscription sub; + int array_sz = sizeof(event_type)/sizeof(int); + int i,rc; + if (fd < 0) { + printf("Invalid input: %d\n", fd); + return OMX_ErrorBadParameter; + } + + for (i = 0; i < array_sz; ++i) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + if (rc) { + printf("Failed to subscribe event: 0x%x\n", sub.type); + break; + } + } + if (i < array_sz) { + for (--i; i >=0 ; i--) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); + if (rc) + printf("Failed to unsubscribe event: 0x%x\n", sub.type); + } + eRet = OMX_ErrorNotImplemented; + } + return eRet; +} + + +static OMX_ERRORTYPE unsubscribe_to_events(int fd) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_event_subscription sub; + int array_sz = sizeof(event_type)/sizeof(int); + int i,rc; + if (fd < 0) { + printf("Invalid input: %d\n", fd); + return OMX_ErrorBadParameter; + } + + for (i = 0; i < array_sz; ++i) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); + if (rc) { + printf("Failed to unsubscribe event: 0x%x\n", sub.type); + break; + } + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::~omx_vdec + +DESCRIPTION + Destructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_vdec::~omx_vdec() +{ + m_pmem_info = NULL; + struct v4l2_decoder_cmd dec; + DEBUG_PRINT_HIGH("In OMX vdec Destructor"); + if(m_pipe_in) close(m_pipe_in); + if(m_pipe_out) close(m_pipe_out); + m_pipe_in = -1; + m_pipe_out = -1; + DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); + pthread_join(msg_thread_id,NULL); + DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); + dec.cmd = V4L2_DEC_CMD_STOP; + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) + { + DEBUG_PRINT_ERROR("\n STOP Command failed\n"); + } + pthread_join(async_thread_id,NULL); + unsubscribe_to_events(drv_ctx.video_driver_fd); + close(drv_ctx.video_driver_fd); + pthread_mutex_destroy(&m_lock); + pthread_mutex_destroy(&c_lock); + sem_destroy(&m_cmd_lock); + if (perf_flag) + { + DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); + dec_time.end(); + } + DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); +} + +int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) { + struct v4l2_requestbuffers bufreq; + int rc = 0; + if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 0; + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); + } + return rc; +} + +/* ====================================================================== +FUNCTION + omx_vdec::OMXCntrlProcessMsgCb + +DESCRIPTION + IL Client callbacks are generated through this routine. The decoder + provides the thread context for this routine. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +void omx_vdec::process_event_cb(void *ctxt, unsigned char id) +{ + signed int p1; // Parameter - 1 + signed int p2; // Parameter - 2 + unsigned int ident; + unsigned int qsize=0; // qsize + omx_vdec *pThis = (omx_vdec *) ctxt; + + if(!pThis) + { + DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n", + __func__); + return; + } + + // Protect the shared queue data structure + do + { + /*Read the message id's from the queue*/ + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if(qsize) + { + pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); + } + + if (qsize == 0 && pThis->m_state != OMX_StatePause) + { + qsize = pThis->m_ftb_q.m_size; + if (qsize) + { + pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); + } + } + + if (qsize == 0 && pThis->m_state != OMX_StatePause) + { + qsize = pThis->m_etb_q.m_size; + if (qsize) + { + pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); + } + } + pthread_mutex_unlock(&pThis->m_lock); + + /*process message if we have one*/ + if(qsize > 0) + { + id = ident; + switch (id) + { + case OMX_COMPONENT_GENERATE_EVENT: + if (pThis->m_cb.EventHandler) + { + switch (p1) + { + case OMX_CommandStateSet: + pThis->m_state = (OMX_STATETYPE) p2; + DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d", + pThis->m_state); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL); + break; + + case OMX_EventError: + if(p2 == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); + pThis->m_state = (OMX_STATETYPE) p2; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError, OMX_ErrorInvalidState, p2, NULL); + } + else if (p2 == OMX_ErrorHardware) + { + pThis->omx_report_error(); + } + else + { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError, p2, (OMX_U32)NULL, NULL ); + } + break; + + case OMX_CommandPortDisable: + DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2); + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) + { + BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); + break; + } + if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig) + { + OMX_ERRORTYPE eRet = OMX_ErrorNone; + pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); + if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) + DEBUG_PRINT_HIGH("Failed to release output buffers\n"); + OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); + pThis->in_reconfig = false; + if(eRet != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); + pThis->omx_report_error(); + break; + } + } + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + case OMX_CommandPortEnable: + DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + default: + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__); + } + break; + case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: + if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); + pThis->omx_report_error (); + } + break; + case OMX_COMPONENT_GENERATE_ETB: + if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FTB: + if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_COMMAND: + pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ + (OMX_U32)p2,(OMX_PTR)NULL); + break; + + case OMX_COMPONENT_GENERATE_EBD: + + if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); + pThis->omx_report_error (); + } + else + { + if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) + { + pThis->m_inp_err_count++; + pThis->time_stamp_dts.remove_time_stamp( + ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, + (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + } + else + { + pThis->m_inp_err_count = 0; + } + if ( pThis->empty_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); + pThis->omx_report_error (); + } + if(pThis->m_inp_err_count >= MAX_INPUT_ERROR) + { + DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); + pThis->omx_report_error (); + } + } + break; + case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: + { + int64_t *timestamp = (int64_t *)p1; + if (p1) + { + pThis->time_stamp_dts.remove_time_stamp(*timestamp, + (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + free(timestamp); + } + } + break; + case OMX_COMPONENT_GENERATE_FBD: + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); + pThis->omx_report_error (); + } + else if ( pThis->fill_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: + DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete"); + if (!pThis->input_flush_progress) + { + DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); + } + else + { + pThis->execute_input_flush(); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); + pThis->omx_report_error (); + } + else + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_INPUT_FLUSH_PENDING)) + { + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); + DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client"); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + OMX_CORE_INPUT_PORT_INDEX,NULL ); + } + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_IDLE_PENDING)) + { + if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { + DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n"); + pThis->omx_report_error (); + } else { + pThis->streaming[OUTPUT_PORT] = false; + } + if (!pThis->output_flush_progress) + { + DEBUG_PRINT_LOW("\n Input flush done hence issue stop"); + pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + } + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: + DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete"); + if (!pThis->output_flush_progress) + { + DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); + } + else + { + pThis->execute_output_flush(); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); + pThis->omx_report_error (); + } + else + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) + { + DEBUG_PRINT_LOW("\n Notify Output Flush done"); + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + OMX_CORE_OUTPUT_PORT_INDEX,NULL ); + } + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) + { + DEBUG_PRINT_LOW("\n Internal flush complete"); + BITMASK_CLEAR (&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) + { + pThis->post_event(OMX_CommandPortDisable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + BITMASK_CLEAR (&pThis->m_flags, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); + + } + } + + if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) + { + if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { + DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n"); + pThis->omx_report_error (); + break; + } + pThis->streaming[CAPTURE_PORT] = false; + if (!pThis->input_flush_progress) + { + DEBUG_PRINT_LOW("\n Output flush done hence issue stop"); + pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + } + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_START_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE"); + + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); + pThis->omx_report_error (); + } + else + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("\n Move to executing"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting, NULL); + } + else if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_PAUSE_PENDING)) + { + if (/*ioctl (pThis->drv_ctx.video_driver_fd, + VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); + pThis->omx_report_error (); + } + } + } + } + else + { + DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); + } + break; + + case OMX_COMPONENT_GENERATE_PAUSE_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); + pThis->omx_report_error (); + } + else + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); + //Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); + pThis->m_state = OMX_StatePause; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StatePause, NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_RESUME_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); + pThis->omx_report_error (); + } + else + { + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("\n Moving the decoder to execute state"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting,NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_STOP_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); + pThis->omx_report_error (); + } + else + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); + pThis->m_state = OMX_StateIdle; + DEBUG_PRINT_LOW("\n Move to Idle State"); + pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateIdle,NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_PORT_RECONFIG: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); + + if (p2 == OMX_IndexParamPortDefinition) { + pThis->in_reconfig = true; + } + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventPortSettingsChanged, p1, p2, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + { + OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; + OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; + if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) + format = OMX_InterlaceInterleaveFrameTopFieldFirst; + else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) + format = OMX_InterlaceInterleaveFrameBottomFieldFirst; + else //unsupported interlace format; raise a error + event = OMX_EventError; + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + event, format, 0, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_EOS_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, + OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + pThis->prev_ts = LLONG_MAX; + pThis->rst_prev_ts = true; + break; + + case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); + pThis->omx_report_error (); + break; + case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: + { + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + default: + break; + } + } + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if (pThis->m_state != OMX_StatePause) + qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); + pthread_mutex_unlock(&pThis->m_lock); + } + while(qsize>0); + +} + +void omx_vdec::update_resolution(int width, int height) +{ + drv_ctx.video_resolution.frame_height = height; + drv_ctx.video_resolution.frame_width = width; + drv_ctx.video_resolution.scan_lines = height; + drv_ctx.video_resolution.stride = width; + rectangle.nLeft = 0; + rectangle.nTop = 0; + rectangle.nWidth = drv_ctx.video_resolution.frame_width; + rectangle.nHeight = drv_ctx.video_resolution.frame_height; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentInit + +DESCRIPTION + Initialize the component. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_fmtdesc fdesc; + struct v4l2_format fmt; + struct v4l2_requestbuffers bufreq; + struct v4l2_control control; + unsigned int alignment = 0,buffer_size = 0; + int fds[2]; + int r,ret=0; + bool codec_ambiguous = false; + OMX_STRING device_name = (OMX_STRING)"/dev/video/q6_dec"; + drv_ctx.video_driver_fd = open(device_name, O_RDWR); + + DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open device %s returned fd %d, errno %d", + device_name, drv_ctx.video_driver_fd, errno); + + if(drv_ctx.video_driver_fd == 0){ + drv_ctx.video_driver_fd = open(device_name, O_RDWR); + } + + if(drv_ctx.video_driver_fd < 0) + { + DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno); + return OMX_ErrorInsufficientResources; + } + drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; + drv_ctx.frame_rate.fps_denominator = 1; + + ret = pthread_create(&async_thread_id,0,async_message_thread,this); + if(ret < 0) { + close(drv_ctx.video_driver_fd); + DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n"); + return OMX_ErrorInsufficientResources; + } + +#ifdef INPUT_BUFFER_LOG + strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); +#endif +#ifdef OUTPUT_BUFFER_LOG + outputBufferFile1 = fopen (outputfilename, "ab"); +#endif +#ifdef OUTPUT_EXTRADATA_LOG + outputExtradataFile = fopen (ouputextradatafilename, "ab"); +#endif + + // Copy the role information which provides the decoder kind + strlcpy(drv_ctx.kind,role,128); + + if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE); + drv_ctx.timestamp_adjust = true; + drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; + eCompressionFormat = OMX_VIDEO_CodingMPEG4; + output_capability=V4L2_PIX_FMT_MPEG4; + /*Initialize Start Code for MPEG4*/ + codec_type_parse = CODEC_TYPE_MPEG4; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "m4v"); +#endif + } + else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ + OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; + output_capability = V4L2_PIX_FMT_MPEG2; + eCompressionFormat = OMX_VIDEO_CodingMPEG2; + /*Initialize Start Code for MPEG2*/ + codec_type_parse = CODEC_TYPE_MPEG2; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "mpg"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("\n H263 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_H263; + eCompressionFormat = OMX_VIDEO_CodingH263; + output_capability = V4L2_PIX_FMT_H263; + codec_type_parse = CODEC_TYPE_H263; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "263"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; + output_capability = V4L2_PIX_FMT_DIVX_311; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + m_frame_parser.init_start_codes (codec_type_parse); + + eRet = createDivxDrmContext(); + if (eRet != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + return eRet; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; + output_capability = V4L2_PIX_FMT_DIVX; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + codec_ambiguous = true; + m_frame_parser.init_start_codes (codec_type_parse); + + eRet = createDivxDrmContext(); + if (eRet != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + return eRet; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; + output_capability = V4L2_PIX_FMT_DIVX; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + codec_ambiguous = true; + m_frame_parser.init_start_codes (codec_type_parse); + + eRet = createDivxDrmContext(); + if (eRet != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + return eRet; + } + + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_H264; + output_capability=V4L2_PIX_FMT_H264; + eCompressionFormat = OMX_VIDEO_CodingAVC; + codec_type_parse = CODEC_TYPE_H264; + m_frame_parser.init_start_codes (codec_type_parse); + m_frame_parser.init_nal_length(nal_length); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "264"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC; + output_capability=V4L2_PIX_FMT_HEVC; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; + codec_type_parse = CODEC_TYPE_HEVC; + m_frame_parser.init_start_codes (codec_type_parse); + m_frame_parser.init_nal_length(nal_length); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "265"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; + eCompressionFormat = OMX_VIDEO_CodingWMV; + codec_type_parse = CODEC_TYPE_VC1; + output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "vc1"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; + eCompressionFormat = OMX_VIDEO_CodingWMV; + codec_type_parse = CODEC_TYPE_VC1; + output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "vc1"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); + output_capability=V4L2_PIX_FMT_VP8; + eCompressionFormat = OMX_VIDEO_CodingVPX; + codec_type_parse = CODEC_TYPE_VP8; + arbitrary_bytes = false; + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } +#ifdef INPUT_BUFFER_LOG + inputBufferFile1 = fopen (inputfilename, "ab"); +#endif + if (eRet == OMX_ErrorNone) + { + + drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; + OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + if (!client_buffers.set_color_format(dest_color_format)) { + DEBUG_PRINT_ERROR("\n Setting color format failed"); + eRet = OMX_ErrorInsufficientResources; + } + + capture_capability= V4L2_PIX_FMT_NV12; + ret = subscribe_to_events(drv_ctx.video_driver_fd); + if (ret) { + DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n"); + return OMX_ErrorInsufficientResources; + } + + struct v4l2_capability cap; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap); + if (ret) { + DEBUG_PRINT_ERROR("Failed to query capabilities\n"); + /*TODO: How to handle this case */ + } else { + DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s," + " version = %d, capabilities = %x\n", cap.driver, cap.card, + cap.bus_info, cap.version, cap.capabilities); + } + ret=0; + fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fdesc.index=0; + while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { + DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, + fdesc.pixelformat, fdesc.flags); + fdesc.index++; + } + fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fdesc.index=0; + while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { + + DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, + fdesc.pixelformat, fdesc.flags); + fdesc.index++; + } + update_resolution(320, 240); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = output_capability; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to set format on output port\n"); + } + DEBUG_PRINT_HIGH("\n Set Format was successful \n "); + if (codec_ambiguous) { + if (output_capability == V4L2_PIX_FMT_DIVX) { + struct v4l2_control divx_ctrl; + + if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { + divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; + } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { + divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; + } else { + divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; + } + + divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); + if (ret) { + DEBUG_PRINT_ERROR("Failed to set divx version\n"); + } + } else { + DEBUG_PRINT_ERROR("Codec should not be ambiguous"); + } + } + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = capture_capability; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to set format on capture port\n"); + } + DEBUG_PRINT_HIGH("\n Set Format was successful \n "); + if(secure_mode){ + control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; + control.value = 1; + DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret); + ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); + if (ret) { + DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret); + close(drv_ctx.video_driver_fd); + return OMX_ErrorInsufficientResources; + } + } + + /*Get the Buffer requirements for input and output ports*/ + drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; + drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + if (secure_mode) { + drv_ctx.op_buf.alignment=SZ_1M; + drv_ctx.ip_buf.alignment=SZ_1M; + } else { + drv_ctx.op_buf.alignment=SZ_4K; + drv_ctx.ip_buf.alignment=SZ_4K; + } + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; + drv_ctx.extradata = 0; + drv_ctx.picture_order = VDEC_ORDER_DISPLAY; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; + control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + drv_ctx.idr_only_decoding = 0; + + m_state = OMX_StateLoaded; +#ifdef DEFAULT_EXTRADATA + if (eRet == OMX_ErrorNone && !secure_mode) + enable_extradata(DEFAULT_EXTRADATA, true, true); +#endif + eRet=get_buffer_req(&drv_ctx.ip_buf); + DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size); + get_buffer_req(&drv_ctx.op_buf); + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || + drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC) + { + h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; + h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); + h264_scratch.nFilledLen = 0; + h264_scratch.nOffset = 0; + + if (h264_scratch.pBuffer == NULL) + { + DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); + return OMX_ErrorInsufficientResources; + } + } + + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + if (m_frame_parser.mutils == NULL) + { + m_frame_parser.mutils = new H264_Utils(); + + if (m_frame_parser.mutils == NULL) + { + DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); + eRet = OMX_ErrorInsufficientResources; + } + else + { + m_frame_parser.mutils->initialize_frame_checking_environment(); + m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); + } + } + + h264_parser = new h264_stream_parser(); + if (!h264_parser) + { + DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); + eRet = OMX_ErrorInsufficientResources; + } + } + + if(pipe(fds)) + { + DEBUG_PRINT_ERROR("pipe creation failed\n"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + int temp1[2]; + if(fds[0] == 0 || fds[1] == 0) + { + if (pipe (temp1)) + { + DEBUG_PRINT_ERROR("pipe creation failed\n"); + return OMX_ErrorInsufficientResources; + } + //close (fds[0]); + //close (fds[1]); + fds[0] = temp1 [0]; + fds[1] = temp1 [1]; + } + m_pipe_in = fds[0]; + m_pipe_out = fds[1]; + r = pthread_create(&msg_thread_id,0,message_thread,this); + + if(r < 0) + { + DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); + eRet = OMX_ErrorInsufficientResources; + } + } + } + + if (eRet != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Component Init Failed"); + DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG"); + (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, + NULL); + DEBUG_PRINT_HIGH("\n Calling close() on Video Driver"); + close (drv_ctx.video_driver_fd); + drv_ctx.video_driver_fd = -1; + } + else + { + DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success"); + } + //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetComponentVersion + +DESCRIPTION + Returns the component version. + +PARAMETERS + TBD. + +RETURN VALUE + OMX_ErrorNone. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_component_version + ( + OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STRING componentName, + OMX_OUT OMX_VERSIONTYPE* componentVersion, + OMX_OUT OMX_VERSIONTYPE* specVersion, + OMX_OUT OMX_UUIDTYPE* componentUUID + ) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n"); + return OMX_ErrorInvalidState; + } + /* TBD -- Return the proper version */ + if (specVersion) + { + specVersion->nVersion = OMX_SPEC_VERSION; + } + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_vdec::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX + && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) + { + DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush " + "to invalid port: %lu", param1); + return OMX_ErrorBadPortIndex; + } + post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); + sem_wait(&m_cmd_lock); + DEBUG_PRINT_LOW("\n send_command: Command Processed\n"); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_STATETYPE eState = (OMX_STATETYPE) param1; + int bFlag = 1,sem_posted = 0,ret=0; + + DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd); + DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d", + m_state, eState); + + if(cmd == OMX_CommandStateSet) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued"); + DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState); + /***************************/ + /* Current State is Loaded */ + /***************************/ + if(m_state == OMX_StateLoaded) + { + if(eState == OMX_StateIdle) + { + //if all buffers are allocated or all ports disabled + if(allocate_done() || + (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) + { + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n"); + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Loaded to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Loaded to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n"); + } + /* Requesting transition from Loaded to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ + eState); + eRet = OMX_ErrorBadParameter; + } + } + + /***************************/ + /* Current State is IDLE */ + /***************************/ + else if(m_state == OMX_StateIdle) + { + if(eState == OMX_StateLoaded) + { + if(release_done()) + { + /* + Since error is None , we will post an event at the end + of this function definition + */ + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n"); + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Idle to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); + //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); + bFlag = 1; + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); + m_state=OMX_StateExecuting; + DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n"); + } + /* Requesting transition from Idle to Idle */ + else if(eState == OMX_StateIdle) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Idle to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Idle to Pause */ + else if(eState == OMX_StatePause) + { + /*To pause the Video core we need to start the driver*/ + if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, + NULL) < */0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n"); + bFlag = 0; + } + } + /* Requesting transition from Idle to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + + /******************************/ + /* Current State is Executing */ + /******************************/ + else if(m_state == OMX_StateExecuting) + { + DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting"); + /* Requesting transition from Executing to Idle */ + if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition + */ + DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n"); + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + execute_omx_flush(OMX_ALL); + } + bFlag = 0; + } + /* Requesting transition from Executing to Paused */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_LOW("\n PAUSE Command Issued"); + m_state = OMX_StatePause; + bFlag = 1; + } + /* Requesting transition from Executing to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Executing to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is Pause */ + /***************************/ + else if(m_state == OMX_StatePause) + { + /* Requesting transition from Pause to Executing */ + if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_LOW("\n Pause --> Executing \n"); + m_state = OMX_StateExecuting; + bFlag = 1; + } + /* Requesting transition from Pause to Idle */ + else if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("\n Pause --> Idle \n"); + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + execute_omx_flush(OMX_ALL); + } + bFlag = 0; + } + /* Requesting transition from Pause to loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Pause to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is WaitForResources */ + /***************************/ + else if(m_state == OMX_StateWaitForResources) + { + /* Requesting transition from WaitForResources to Loaded */ + if(eState == OMX_StateLoaded) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n"); + } + /* Requesting transition from WaitForResources to WaitForResources */ + else if (eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorSameState, + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from WaitForResources to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + /* Requesting transition from WaitForResources to Loaded - + is NOT tested by Khronos TS */ + + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); + eRet = OMX_ErrorBadParameter; + } + } + /********************************/ + /* Current State is Invalid */ + /*******************************/ + else if(m_state == OMX_StateInvalid) + { + /* State Transition from Inavlid to any state */ + if(eState == (OMX_StateLoaded || OMX_StateWaitForResources + || OMX_StateIdle || OMX_StateExecuting + || OMX_StatePause || OMX_StateInvalid)) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); + post_event(OMX_EventError,OMX_ErrorInvalidState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + } + else if (cmd == OMX_CommandFlush) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued" + "with param1: %lu", param1); + if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); + } + if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) + { + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + } + if (!sem_posted){ + sem_posted = 1; + DEBUG_PRINT_LOW("\n Set the Semaphore"); + sem_post (&m_cmd_lock); + execute_omx_flush(param1); + } + bFlag = 0; + } + else if ( cmd == OMX_CommandPortEnable) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued" + "with param1: %lu", param1); + if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_inp_bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || allocate_input_done()) + { + post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) + { + DEBUG_PRINT_LOW("\n Enable output Port command recieved"); + m_out_bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || (allocate_output_done())) + { + post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + } + else if (cmd == OMX_CommandPortDisable) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued" + "with param1: %lu", param1); + if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_inp_bEnabled = OMX_FALSE; + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_input_done()) + { + post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + } + execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); + } + + // Skip the event notification + bFlag = 0; + } + } + if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_out_bEnabled = OMX_FALSE; + DEBUG_PRINT_LOW("\n Disable output Port command recieved"); + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_output_done()) + { + post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + if (!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + } + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); + execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); + } + // Skip the event notification + bFlag = 0; + + } + } + } + else + { + DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); + eRet = OMX_ErrorNotImplemented; + } + if(eRet == OMX_ErrorNone && bFlag) + { + post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); + } + if(!sem_posted) + { + sem_post(&m_cmd_lock); + } + + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ExecuteOmxFlush + +DESCRIPTION + Executes the OMX flush. + +PARAMETERS + flushtype - input flush(1)/output flush(0)/ both. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_vdec::execute_omx_flush(OMX_U32 flushType) +{ + bool bRet = false; + struct v4l2_plane plane; + struct v4l2_buffer v4l2_buf; + struct v4l2_decoder_cmd dec; + DEBUG_PRINT_LOW("in %s", __func__); + memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); + dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; + switch (flushType) + { + case OMX_CORE_INPUT_PORT_INDEX: + input_flush_progress = true; + dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT; + break; + case OMX_CORE_OUTPUT_PORT_INDEX: + output_flush_progress = true; + dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; + break; + default: + input_flush_progress = true; + output_flush_progress = true; + dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | + V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; + } + + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) + { + DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType); + bRet = false; + } + + return bRet; +} +/*========================================================================= +FUNCTION : execute_output_flush + +DESCRIPTION + Executes the OMX flush at OUTPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_vdec::execute_output_flush() +{ + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate FBD for all Buffers in the FTBq*/ + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_LOW("\n Initiate Output Flush"); + while (m_ftb_q.m_size) + { + DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d", + m_ftb_q.m_size,pending_output_buffers); + m_ftb_q.pop_entry(&p1,&p2,&ident); + DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2); + if(ident == m_fill_output_msg ) + { + m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + else if (ident == OMX_COMPONENT_GENERATE_FBD) + { + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + pthread_mutex_unlock(&m_lock); + output_flush_progress = false; + + if (arbitrary_bytes) + { + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } + DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); + return bRet; +} +/*========================================================================= +FUNCTION : execute_input_flush + +DESCRIPTION + Executes the OMX flush at INPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_vdec::execute_input_flush() +{ + unsigned i =0; + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate EBD for all Buffers in the ETBq*/ + DEBUG_PRINT_LOW("\n Initiate Input Flush \n"); + + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_LOW("\n Check if the Queue is empty \n"); + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + + if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) + { + DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_ETB) + { + pending_input_buffers++; + DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", + (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if (ident == OMX_COMPONENT_GENERATE_EBD) + { + DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", + (OMX_BUFFERHEADERTYPE *)p1); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + time_stamp_dts.flush_timestamp(); + /*Check if Heap Buffers are to be flushed*/ + if (arbitrary_bytes) + { + DEBUG_PRINT_LOW("\n Reset all the variables before flusing"); + h264_scratch.nFilledLen = 0; + nal_count = 0; + look_ahead_nal = false; + frame_count = 0; + h264_last_au_ts = LLONG_MAX; + h264_last_au_flags = 0; + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + DEBUG_PRINT_LOW("\n Initialize parser"); + if (m_frame_parser.mutils) + { + m_frame_parser.mutils->initialize_frame_checking_environment(); + } + + while (m_input_pending_q.m_size) + { + m_input_pending_q.pop_entry(&p1,&p2,&ident); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); + } + + if (psource_frame) + { + m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); + psource_frame = NULL; + } + + if (pdest_frame) + { + pdest_frame->nFilledLen = 0; + m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL, + (unsigned int)NULL); + pdest_frame = NULL; + } + m_frame_parser.flush(); + } + pthread_mutex_unlock(&m_lock); + input_flush_progress = false; + if (!arbitrary_bytes) + { + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } +#ifdef _ANDROID_ + if (m_debug_timestamp) + { + m_timestamp_list.reset_ts_list(); + } +#endif + DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); + return bRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::SendCommandEvent + +DESCRIPTION + Send the event to decoder pipe. This is needed to generate the callbacks + in decoder thread context. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_vdec::post_event(unsigned int p1, + unsigned int p2, + unsigned int id) +{ + bool bRet = false; + + + pthread_mutex_lock(&m_lock); + + if (id == m_fill_output_msg || + id == OMX_COMPONENT_GENERATE_FBD) + { + m_ftb_q.insert_entry(p1,p2,id); + } + else if (id == OMX_COMPONENT_GENERATE_ETB || + id == OMX_COMPONENT_GENERATE_EBD || + id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) + { + m_etb_q.insert_entry(p1,p2,id); + } + else + { + m_cmd_q.insert_entry(p1,p2,id); + } + + bRet = true; + DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); + post_message(this, id); + + pthread_mutex_unlock(&m_lock); + + return bRet; +} + +OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNoMore; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 0) { + if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) + { + // TODO + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + eRet = OMX_ErrorNoMore; + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; + profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetParameter + +DESCRIPTION + OMX Get Parameter method implementation + +PARAMETERS + . + +RETURN VALUE + Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_INOUT OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + DEBUG_PRINT_LOW("get_parameter: \n"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_LOW("Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + switch((unsigned long)paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn = + (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); + eRet = update_portdef(portDefn); + if (eRet == OMX_ErrorNone) + m_port_def = *portDefn; + break; + } + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); + + portParamType->nVersion.nVersion = OMX_SPEC_VERSION; + portParamType->nSize = sizeof(portParamType); + portParamType->nPorts = 2; + portParamType->nStartPortNumber = 0; + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); + + portFmt->nVersion.nVersion = OMX_SPEC_VERSION; + portFmt->nSize = sizeof(portFmt); + + if (0 == portFmt->nPortIndex) + { + if (0 == portFmt->nIndex) + { + portFmt->eColorFormat = OMX_COLOR_FormatUnused; + portFmt->eCompressionFormat = eCompressionFormat; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ + " NoMore compression formats\n"); + eRet = OMX_ErrorNoMore; + } + } + else if (1 == portFmt->nPortIndex) + { + portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; + + if(0 == portFmt->nIndex) + portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + else if (1 == portFmt->nIndex) + portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ + " NoMore Color formats\n"); + eRet = OMX_ErrorNoMore; + } + ALOGE("returning %d\n", portFmt->eColorFormat); + } + else + { + DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", + (int)portFmt->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamAudioInit: + { + OMX_PORT_PARAM_TYPE *audioPortParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); + audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; + audioPortParamType->nSize = sizeof(audioPortParamType); + audioPortParamType->nPorts = 0; + audioPortParamType->nStartPortNumber = 0; + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamImageInit: + { + OMX_PORT_PARAM_TYPE *imagePortParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); + imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; + imagePortParamType->nSize = sizeof(imagePortParamType); + imagePortParamType->nPorts = 0; + imagePortParamType->nStartPortNumber = 0; + break; + + } + /*Component should support this port definition*/ + case OMX_IndexParamOtherInit: + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", + paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + break; + } + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + comp_role->nVersion.nVersion = OMX_SPEC_VERSION; + comp_role->nSize = sizeof(*comp_role); + + DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", + paramIndex); + strlcpy((char*)comp_role->cRole,(const char*)m_cRole, + OMX_MAX_STRINGNAME_SIZE); + break; + } + /* Added for parameter test */ + case OMX_IndexParamPriorityMgmt: + { + + OMX_PRIORITYMGMTTYPE *priorityMgmType = + (OMX_PRIORITYMGMTTYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); + priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; + priorityMgmType->nSize = sizeof(priorityMgmType); + + break; + } + /* Added for parameter test */ + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = + (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); + + bufferSupplierType->nSize = sizeof(bufferSupplierType); + bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; + if(0 == bufferSupplierType->nPortIndex) + bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; + else if (1 == bufferSupplierType->nPortIndex) + bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; + else + eRet = OMX_ErrorBadPortIndex; + + + break; + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoH263: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg4: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg2: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex); + OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = + (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; + eRet = get_supported_profile_level_for_1080p(profileLevelType); + break; + } +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: + { + DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n"); + GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; + if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { + + if(secure_mode) { + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | + GRALLOC_USAGE_PRIVATE_UNCACHED); + } else { +#ifdef _HEVC_USE_ADSP_HEAP_ + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); +#else + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); +#endif + DEBUG_PRINT_HIGH("nativeBuffersUsage->nUsage %x\n", (unsigned int)nativeBuffersUsage->nUsage); + } + } else { + DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n"); + eRet = OMX_ErrorBadParameter; + } + } + break; +#endif + + default: + { + DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + } + + } + + DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n", + drv_ctx.video_resolution.frame_width, + drv_ctx.video_resolution.frame_height, + drv_ctx.video_resolution.stride, + drv_ctx.video_resolution.scan_lines); + + return eRet; +} + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) +{ + DEBUG_PRINT_LOW("Inside use_android_native_buffer"); + OMX_ERRORTYPE eRet = OMX_ErrorNone; + UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; + + if((params == NULL) || + (params->nativeBuffer == NULL) || + (params->nativeBuffer->handle == NULL) || + !m_enable_android_native_buffers) + return OMX_ErrorBadParameter; + m_use_android_native_buffers = OMX_TRUE; + sp nBuf = params->nativeBuffer; + private_handle_t *handle = (private_handle_t *)nBuf->handle; + if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port + OMX_U8 *buffer = NULL; + if(!secure_mode) { + buffer = (OMX_U8*)mmap(0, handle->size, + PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); + if(buffer == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); + return OMX_ErrorInsufficientResources; + } + } + eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); + } else { + eRet = OMX_ErrorBadParameter; + } + return eRet; +} +#endif +/* ====================================================================== +FUNCTION + omx_vdec::Setparameter + +DESCRIPTION + OMX Set Parameter method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_IN OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + int ret=0; + struct v4l2_format fmt; + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + if((m_state != OMX_StateLoaded) && + BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && + (m_out_bEnabled == OMX_TRUE) && + BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && + (m_inp_bEnabled == OMX_TRUE)) { + DEBUG_PRINT_ERROR("Set Param in Invalid State \n"); + return OMX_ErrorIncorrectStateOperation; + } + switch((unsigned long)paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has + //been called. + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", + (int)portDefn->format.video.nFrameHeight, + (int)portDefn->format.video.nFrameWidth); + if(OMX_DirOutput == portDefn->eDir) + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n"); + m_display_id = portDefn->format.video.pNativeWindow; + unsigned int buffer_size; + if (!client_buffers.get_buffer_req(buffer_size)) { + DEBUG_PRINT_ERROR("\n Error in getting buffer requirements"); + eRet = OMX_ErrorBadParameter; + } else { + if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && + portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) + { + drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; + drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; + eRet = set_buffer_req(&drv_ctx.op_buf); + if (eRet == OMX_ErrorNone) + m_port_def = *portDefn; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n", + drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, + portDefn->nBufferCountActual, portDefn->nBufferSize); + eRet = OMX_ErrorBadParameter; + } + } + } + else if(OMX_DirInput == portDefn->eDir) + { + if((portDefn->format.video.xFramerate >> 16) > 0 && + (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) + { + // Frame rate only should be set if this is a "known value" or to + // activate ts prediction logic (arbitrary mode only) sending input + // timestamps with max value (LLONG_MAX). + DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu", + portDefn->format.video.xFramerate >> 16); + Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, + drv_ctx.frame_rate.fps_denominator); + if(!drv_ctx.frame_rate.fps_numerator) + { + DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); + drv_ctx.frame_rate.fps_numerator = 30; + } + if(drv_ctx.frame_rate.fps_denominator) + drv_ctx.frame_rate.fps_numerator = (int) + drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; + drv_ctx.frame_rate.fps_denominator = 1; + frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / + drv_ctx.frame_rate.fps_numerator; + DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", + frm_int, drv_ctx.frame_rate.fps_numerator / + (float)drv_ctx.frame_rate.fps_denominator); + } + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n"); + if(drv_ctx.video_resolution.frame_height != + portDefn->format.video.nFrameHeight || + drv_ctx.video_resolution.frame_width != + portDefn->format.video.nFrameWidth) + { + DEBUG_PRINT_LOW("\n SetParam IP: WxH(%d x %d)\n", + portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight); + if (portDefn->format.video.nFrameHeight != 0x0 && + portDefn->format.video.nFrameWidth != 0x0) + { + update_resolution(portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = output_capability; + DEBUG_PRINT_LOW("\n fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d \n",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) + { + DEBUG_PRINT_ERROR("\n Set Resolution failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + else + eRet = get_buffer_req(&drv_ctx.op_buf); + } + } + else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount + || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) + { + vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; + drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; + drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & + (~(buffer_prop->alignment - 1)); + eRet = set_buffer_req(buffer_prop); + } + else + { + DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n", + drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, + portDefn->nBufferCountActual, portDefn->nBufferSize); + eRet = OMX_ErrorBadParameter; + } + } + else if (portDefn->eDir == OMX_DirMax) + { + DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + int ret=0; + struct v4l2_format fmt; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", + portFmt->eColorFormat); + + if(1 == portFmt->nPortIndex) + { + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = capture_capability; + enum vdec_output_fromat op_format; + if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) || + (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar)) + op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; + else if(portFmt->eColorFormat == + (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) + op_format = VDEC_YUV_FORMAT_TILE_4x2; + else + eRet = OMX_ErrorBadParameter; + + if(eRet == OMX_ErrorNone) + { + drv_ctx.output_format = op_format; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if(ret) + { + DEBUG_PRINT_ERROR("\n Set output format failed"); + eRet = OMX_ErrorUnsupportedSetting; + /*TODO: How to handle this case */ + } + else + { + eRet = get_buffer_req(&drv_ctx.op_buf); + } + } + if (eRet == OMX_ErrorNone){ + if (!client_buffers.set_color_format(portFmt->eColorFormat)) { + DEBUG_PRINT_ERROR("\n Set color format failed"); + eRet = OMX_ErrorBadParameter; + } + } + } + } + break; + + case OMX_QcomIndexPortDefn: + { + OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = + (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n", + portFmt->nFramePackingFormat); + + /* Input port */ + if (portFmt->nPortIndex == 0) + { + if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) + { + if(secure_mode) { + arbitrary_bytes = false; + DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); + eRet = OMX_ErrorUnsupportedSetting; + } else { + arbitrary_bytes = true; + } + } + else if (portFmt->nFramePackingFormat == + OMX_QCOM_FramePacking_OnlyOneCompleteFrame) + { + arbitrary_bytes = false; + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n", + portFmt->nFramePackingFormat); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n"); + if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && + portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && + portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) + { + m_out_mem_region_smi = OMX_TRUE; + if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n"); + m_use_output_pmem = OMX_TRUE; + } + } + } + } + break; + + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", + comp_role->cRole); + + if((m_state == OMX_StateLoaded)&& + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("Set Parameter called in valid state"); + } + else + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((char*)comp_role->cRole,"video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || + (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) + { + strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind); + eRet = OMX_ErrorInvalidComponentName; + } + break; + } + + case OMX_IndexParamPriorityMgmt: + { + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", + priorityMgmtype->nGroupID); + + DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", + priorityMgmtype->nGroupPriority); + + m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; + m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; + + break; + } + + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", + bufferSupplierType->eBufferSupplier); + if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) + m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; + + else + + eRet = OMX_ErrorBadPortIndex; + + break; + + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoH263: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg4: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg2: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n", + paramIndex); + break; + } + case OMX_QcomIndexParamVideoDecoderPictureOrder: + { + QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = + (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; + struct v4l2_control control; + int pic_order,rc=0; + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n", + pictureOrder->eOutputPictureOrder); + if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { + pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; + } + else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){ + pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; + time_stamp_dts.set_timestamp_reorder_mode(false); + } + else + eRet = OMX_ErrorBadParameter; + if (eRet == OMX_ErrorNone) + { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; + control.value = pic_order; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + if(rc) + { + DEBUG_PRINT_ERROR("\n Set picture order failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + } + break; + } + case OMX_QcomIndexParamConcealMBMapExtraData: + if(!secure_mode) + eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + case OMX_QcomIndexParamFrameInfoExtraData: + { + if(!secure_mode) + eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + } + case OMX_QcomIndexParamInterlaceExtraData: + if(!secure_mode) + eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + case OMX_QcomIndexParamH264TimeInfo: + if(!secure_mode) + eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + case OMX_QcomIndexParamVideoDivx: + { + QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; + } + break; + case OMX_QcomIndexPlatformPvt: + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n"); + OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; + if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) + { + DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); + eRet = OMX_ErrorUnsupportedSetting; + } + else + { + m_out_pvt_entry_pmem = OMX_TRUE; + if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n"); + m_use_output_pmem = OMX_TRUE; + } + } + + } + break; + case OMX_QcomIndexParamVideoSyncFrameDecodingMode: + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); + DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); + struct v4l2_control control; + int rc; + drv_ctx.idr_only_decoding = 1; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; + control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + if(rc) + { + DEBUG_PRINT_ERROR("\n Set picture order failed"); + eRet = OMX_ErrorUnsupportedSetting; + } else { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; + control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + if(rc) + { + DEBUG_PRINT_ERROR("\n Sync frame setting failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + } + } + break; + + case OMX_QcomIndexParamIndexExtraDataType: + { + if(!secure_mode) { + QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; + if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && + (extradataIndexType->bEnabled == OMX_TRUE) && + (extradataIndexType->nPortIndex == 1)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n"); + eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); + + } + } + } + break; + case OMX_QcomIndexParamEnableSmoothStreaming: + { + struct v4l2_control control; + struct v4l2_format fmt; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; + control.value = 1; + int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); + if(rc < 0) { + DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); + eRet = OMX_ErrorHardware; + } + } + break; +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + /* Need to allow following two set_parameters even in Idle + * state. This is ANDROID architecture which is not in sync + * with openmax standard. */ + case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: + { + EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; + if(enableNativeBuffers) { + m_enable_android_native_buffers = enableNativeBuffers->enable; + } + } + break; + case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: + { + eRet = use_android_native_buffer(hComp, paramData); + } + break; +#endif + case OMX_QcomIndexParamEnableTimeStampReorder: + { + QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; + if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { + if (reorder->bEnable == OMX_TRUE) { + frm_int =0; + time_stamp_dts.set_timestamp_reorder_mode(true); + } + else + time_stamp_dts.set_timestamp_reorder_mode(false); + } else { + time_stamp_dts.set_timestamp_reorder_mode(false); + if (reorder->bEnable == OMX_TRUE) + { + eRet = OMX_ErrorUnsupportedSetting; + } + } + } + break; + default: + { + DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); + eRet = OMX_ErrorUnsupportedIndex; + } + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetConfig + +DESCRIPTION + OMX Get Config Method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_INOUT OMX_PTR configData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + if (m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + switch ((unsigned long)configIndex) + { + case OMX_QcomIndexConfigInterlaced: + { + OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = + (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; + if (configFmt->nPortIndex == 1) + { + if (configFmt->nIndex == 0) + { + configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; + } + else if (configFmt->nIndex == 1) + { + configFmt->eInterlaceType = + OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; + } + else if (configFmt->nIndex == 2) + { + configFmt->eInterlaceType = + OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; + } + else + { + DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" + " NoMore Interlaced formats\n"); + eRet = OMX_ErrorNoMore; + } + + } + else + { + DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", + (int)configFmt->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + case OMX_QcomIndexQueryNumberOfVideoDecInstance: + { + QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = + (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; + decoderinstances->nNumOfInstances = 16; + /*TODO: How to handle this case */ + break; + } + case OMX_QcomIndexConfigVideoFramePackingArrangement: + { + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = + (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; + h264_parser->get_frame_pack_data(configFmt); + } + else + { + DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); + } + break; + } + case OMX_IndexConfigCommonOutputCrop: + { + OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; + memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); + break; + } + default: + { + DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); + eRet = OMX_ErrorBadParameter; + } + + } + + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SetConfig + +DESCRIPTION + OMX Set Config method implementation + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_IN OMX_PTR configData) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_VIDEO_CONFIG_NALSIZE *pNal; + + DEBUG_PRINT_LOW("\n Set Config Called"); + + if (m_state == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n"); + return ret; + } + + if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) + { + OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; + DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called"); + if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) + { + DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC"); + OMX_U32 extra_size; + // Parsing done here for the AVC atom is definitely not generic + // Currently this piece of code is working, but certainly + // not tested with all .mp4 files. + // Incase of failure, we might need to revisit this + // for a generic piece of code. + + // Retrieve size of NAL length field + // byte #4 contains the size of NAL lenght field + nal_length = (config->pData[4] & 0x03) + 1; + + extra_size = 0; + if (nal_length > 2) + { + /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ + extra_size = (nal_length - 2) * 2; + } + + // SPS starts from byte #6 + OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); + OMX_U8 *pDestBuf; + m_vendor_config.nPortIndex = config->nPortIndex; + + // minus 6 --> SPS starts from byte #6 + // minus 1 --> picture param set byte to be ignored from avcatom + m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; + m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); + OMX_U32 len; + OMX_U8 index = 0; + // case where SPS+PPS is sent as part of set_config + pDestBuf = m_vendor_config.pData; + + DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n", + m_vendor_config.nPortIndex, + m_vendor_config.nDataSize, + m_vendor_config.pData); + while (index < 2) + { + uint8 *psize; + len = *pSrcBuf; + len = len << 8; + len |= *(pSrcBuf + 1); + psize = (uint8 *) & len; + memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); + for (unsigned int i = 0; i < nal_length; i++) + { + pDestBuf[i] = psize[nal_length - 1 - i]; + } + //memcpy(pDestBuf,pSrcBuf,(len+2)); + pDestBuf += len + nal_length; + pSrcBuf += len + 2; + index++; + pSrcBuf++; // skip picture param set + len = 0; + } + } + else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || + !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) + { + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); + memcpy(m_vendor_config.pData, config->pData,config->nDataSize); + } + else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) + { + if(m_vendor_config.pData) + { + free(m_vendor_config.pData); + m_vendor_config.pData = NULL; + m_vendor_config.nDataSize = 0; + } + + if (((*((OMX_U32 *) config->pData)) & + VC1_SP_MP_START_CODE_MASK) == + VC1_SP_MP_START_CODE) + { + DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = + (OMX_U8 *) malloc(config->nDataSize); + memcpy(m_vendor_config.pData, config->pData, + config->nDataSize); + m_vc1_profile = VC1_SP_MP_RCV; + } + else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) + { + DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = + (OMX_U8 *) malloc((config->nDataSize)); + memcpy(m_vendor_config.pData, config->pData, + config->nDataSize); + m_vc1_profile = VC1_AP; + } + else if ((config->nDataSize == VC1_STRUCT_C_LEN)) + { + DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); + memcpy(m_vendor_config.pData,config->pData,config->nDataSize); + m_vc1_profile = VC1_SP_MP_RCV; + } + else + { + DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); + } + } + return ret; + } + else if (configIndex == OMX_IndexConfigVideoNalSize) + { + + pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); + nal_length = pNal->nNaluBytes; + m_frame_parser.init_nal_length(nal_length); + DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length); + return ret; + } + + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetExtensionIndex + +DESCRIPTION + OMX GetExtensionIndex method implementaion. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_STRING paramName, + OMX_OUT OMX_INDEXTYPE* indexType) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); + return OMX_ErrorInvalidState; + } + else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; + } + else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) + { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; + } +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; + } + else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; + } + else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { + DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName); + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; + } + else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; + } +#endif + else { + DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName); + return OMX_ErrorNotImplemented; + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetState + +DESCRIPTION + Returns the state information back to the caller. + +PARAMETERS + . + +RETURN VALUE + Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STATETYPE* state) +{ + *state = m_state; + DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentTunnelRequest + +DESCRIPTION + OMX Component Tunnel Request method implementation. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_HANDLETYPE peerComponent, + OMX_IN OMX_U32 peerPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) +{ + DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::UseOutputBuffer + +DESCRIPTION + Helper function for Use buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_extradata() +{ +#ifdef USE_ION + if (drv_ctx.extradata_info.buffer_size) { + if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { + munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); + close(drv_ctx.extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&drv_ctx.extradata_info.ion); + } + drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); + DEBUG_PRINT_HIGH("allocate extradata memory size %d\n", drv_ctx.extradata_info.size); + drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( + drv_ctx.extradata_info.size, 4096, + &drv_ctx.extradata_info.ion.ion_alloc_data, + &drv_ctx.extradata_info.ion.fd_ion_data, 0); + if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { + DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n"); + return OMX_ErrorInsufficientResources; + } + drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, + drv_ctx.extradata_info.size, + PROT_READ|PROT_WRITE, MAP_SHARED, + drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); + if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); + close(drv_ctx.extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&drv_ctx.extradata_info.ion); + return OMX_ErrorInsufficientResources; + } + memset(drv_ctx.extradata_info.uaddr, 0, drv_ctx.extradata_info.size); + } +#endif + return OMX_ErrorNone; +} + +void omx_vdec::free_extradata() { +#ifdef USE_ION + if (drv_ctx.extradata_info.uaddr) { + munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); + close(drv_ctx.extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&drv_ctx.extradata_info.ion); + } + memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); +#endif +} + +OMX_ERRORTYPE omx_vdec::use_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + struct vdec_setbuffer_cmd setbuffers; + OMX_PTR privateAppData = NULL; + private_handle_t *handle = NULL; + OMX_U8 *buff = buffer; + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + int extra_idx = 0; + + if (!m_out_mem_ptr) { + DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); + eRet = allocate_output_headers(); + if (eRet == OMX_ErrorNone) + eRet = allocate_extradata(); + } + + if (eRet == OMX_ErrorNone) { + for(i=0; i< drv_ctx.op_buf.actualcount; i++) { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + break; + } + } + } + + if(i >= drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount); + eRet = OMX_ErrorInsufficientResources; + } + + if (eRet == OMX_ErrorNone) { +#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) + if(m_enable_android_native_buffers) { + if (m_use_android_native_buffers) { + UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; + sp nBuf = params->nativeBuffer; + handle = (private_handle_t *)nBuf->handle; + privateAppData = params->pAppPrivate; + } else { + handle = (private_handle_t *)buff; + privateAppData = appData; + } + + if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { + DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," + " expected %u, got %lu", + drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); + return OMX_ErrorBadParameter; + } + + drv_ctx.op_buf.buffer_size = (OMX_U32)handle->size; + if (!m_use_android_native_buffers) { + if (!secure_mode) { + buff = (OMX_U8*)mmap(0, handle->size, + PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); + if (buff == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); + return OMX_ErrorInsufficientResources; + } + } + } +#if defined(_ANDROID_ICS_) + native_buffer[i].nativehandle = handle; + native_buffer[i].privatehandle = handle; +#endif + if(!handle) { + DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); + return OMX_ErrorBadParameter; + } + drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; + drv_ctx.ptr_outputbuffer[i].offset = 0; + drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; + drv_ctx.ptr_outputbuffer[i].mmaped_size = + drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; + } else +#endif + + if (!ouput_egl_buffers && !m_use_output_pmem) { +#ifdef USE_ION + DEBUG_PRINT_HIGH("allocate output buffer memory size %d\n", drv_ctx.op_buf.buffer_size); + drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( + drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, + &drv_ctx.op_buf_ion_info[i].ion_alloc_data, + &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); + if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd); + return OMX_ErrorInsufficientResources; + } + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; +#else + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + open (MEM_DEVICE,O_RDWR); + + if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { + DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); + return OMX_ErrorInsufficientResources; + } + + /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ + if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) + { + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + open (MEM_DEVICE,O_RDWR); + if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { + DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, + drv_ctx.op_buf.buffer_size, + drv_ctx.op_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(drv_ctx.ptr_outputbuffer[i].pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if(!secure_mode) { + drv_ctx.ptr_outputbuffer[i].bufferaddr = + (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, + PROT_READ|PROT_WRITE, MAP_SHARED, + drv_ctx.ptr_outputbuffer[i].pmem_fd,0); + if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { + close(drv_ctx.ptr_outputbuffer[i].pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[i]); +#endif + DEBUG_PRINT_ERROR("Unable to mmap output buffer\n"); + return OMX_ErrorInsufficientResources; + } + } + drv_ctx.ptr_outputbuffer[i].offset = 0; + privateAppData = appData; + } + else { + + DEBUG_PRINT_HIGH("Use_op_buf: out_pmem=%d",m_use_output_pmem); + if (!appData || !bytes ) { + if(!secure_mode && !buffer) { + DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case"); + return OMX_ErrorBadParameter; + } + } + + OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; + pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; + if (!pmem_list->entryList || !pmem_list->entryList->entry || + !pmem_list->nEntries || + pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { + DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer"); + return OMX_ErrorBadParameter; + } + pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + pmem_list->entryList->entry; + DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x", + pmem_info->pmem_fd); + drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; + drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; + drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; + drv_ctx.ptr_outputbuffer[i].mmaped_size = + drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; + privateAppData = appData; + } + m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; + m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; + + *bufferHdr = (m_out_mem_ptr + i ); + if(secure_mode) + drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; + //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], + sizeof (vdec_bufferpayload)); + + DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, + drv_ctx.ptr_outputbuffer[i].bufferaddr, + drv_ctx.ptr_outputbuffer[i].pmem_fd ); + + buf.index = i; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].length = drv_ctx.op_buf.buffer_size; + plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - + (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; + plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; + plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; + plane[0].data_offset = 0; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; + plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + buf.m.planes = plane; + buf.length = drv_ctx.num_planes; + + DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); + + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { + DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); + /*TODO: How to handle this case */ + return OMX_ErrorInsufficientResources; + } + + if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { + enum v4l2_buf_type buf_type; + buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { + return OMX_ErrorInsufficientResources; + } else { + streaming[CAPTURE_PORT] = true; + DEBUG_PRINT_LOW("\n STREAMON Successful \n "); + } + } + + (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; + if (m_enable_android_native_buffers) { + DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); + (*bufferHdr)->pBuffer = (OMX_U8 *)handle; + } else { + (*bufferHdr)->pBuffer = buff; + } + (*bufferHdr)->pAppPrivate = privateAppData; + BITMASK_SET(&m_out_bm_count,i); + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::use_input_heap_buffers + +DESCRIPTION + OMX Use Buffer Heap allocation method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer); + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!m_inp_heap_ptr) + m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), + drv_ctx.ip_buf.actualcount); + if(!m_phdr_pmem_ptr) + m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) + calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), + drv_ctx.ip_buf.actualcount); + if(!m_inp_heap_ptr || !m_phdr_pmem_ptr) + { + DEBUG_PRINT_ERROR("Insufficent memory"); + eRet = OMX_ErrorInsufficientResources; + } + else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) + { + input_use_buffer = true; + memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); + m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; + m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; + m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; + m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; + m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; + *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; + eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); + DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); + if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], + (unsigned)NULL, (unsigned)NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); + return OMX_ErrorInsufficientResources; + } + m_in_alloc_cnt++; + } + else + { + DEBUG_PRINT_ERROR("All i/p buffers have been set!"); + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::UseBuffer + +DESCRIPTION + OMX Use Buffer method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE error = OMX_ErrorNone; + struct vdec_setbuffer_cmd setbuffers; + + if (bufferHdr == NULL || bytes == 0) + { + if(!secure_mode && buffer == NULL) { + DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer); + return OMX_ErrorBadParameter; + } + } + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(port == OMX_CORE_INPUT_PORT_INDEX) + error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested + else + { + DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); + error = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error); + if(error == OMX_ErrorNone) + { + if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && + BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && + BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + return error; +} + +OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, + OMX_BUFFERHEADERTYPE *pmem_bufferHdr) +{ + if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) + { + if(m_inp_heap_ptr[bufferindex].pBuffer) + free(m_inp_heap_ptr[bufferindex].pBuffer); + m_inp_heap_ptr[bufferindex].pBuffer = NULL; + } + if (pmem_bufferHdr) + free_input_buffer(pmem_bufferHdr); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + if (bufferHdr == NULL || m_inp_mem_ptr == NULL) + { + return OMX_ErrorBadParameter; + } + + index = bufferHdr - m_inp_mem_ptr; + DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); + + if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) + { + DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); + if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) + { + struct vdec_setbuffer_cmd setbuffers; + setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], + sizeof (vdec_bufferpayload)); + DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d", + drv_ctx.ptr_inputbuffer[index].pmem_fd); + DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d", + drv_ctx.ptr_inputbuffer[index].mmaped_size, + drv_ctx.ptr_inputbuffer[index].bufferaddr); + munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, + drv_ctx.ptr_inputbuffer[index].mmaped_size); + close (drv_ctx.ptr_inputbuffer[index].pmem_fd); + drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; + if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) + { + free(m_desc_buffer_ptr[index].buf_addr); + m_desc_buffer_ptr[index].buf_addr = NULL; + m_desc_buffer_ptr[index].desc_data_size = 0; + } +#ifdef USE_ION + free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); +#endif + } + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + + if (bufferHdr == NULL || m_out_mem_ptr == NULL) + { + return OMX_ErrorBadParameter; + } + + index = bufferHdr - m_out_mem_ptr; + DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index); + + if (index < drv_ctx.op_buf.actualcount + && drv_ctx.ptr_outputbuffer) + { + DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index, + drv_ctx.ptr_outputbuffer[index].bufferaddr); + + struct vdec_setbuffer_cmd setbuffers; + setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], + sizeof (vdec_bufferpayload)); +#ifdef _ANDROID_ + if(m_enable_android_native_buffers) { + if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { + munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, + drv_ctx.ptr_outputbuffer[index].mmaped_size); + } + drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; + } else { +#endif + if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) + { + DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", + drv_ctx.ptr_outputbuffer[0].pmem_fd); + DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d", + drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, + drv_ctx.ptr_outputbuffer[0].bufferaddr); + munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, + drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); + close (drv_ctx.ptr_outputbuffer[0].pmem_fd); + drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[0]); +#endif + } +#ifdef _ANDROID_ + } +#endif + if (release_output_done()) { + free_extradata(); + } + } + + return OMX_ErrorNone; + +} + +OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes) +{ + OMX_BUFFERHEADERTYPE *input = NULL; + unsigned char *buf_addr = NULL; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned i = 0; + + /* Sanity Check*/ + if (bufferHdr == NULL) + { + return OMX_ErrorBadParameter; + } + + if (m_inp_heap_ptr == NULL) + { + m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), + drv_ctx.ip_buf.actualcount); + m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), + drv_ctx.ip_buf.actualcount); + + if (m_inp_heap_ptr == NULL) + { + DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + } + + /*Find a Free index*/ + for(i=0; i< drv_ctx.ip_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); + break; + } + } + + if (i < drv_ctx.ip_buf.actualcount) + { + buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); + + if (buf_addr == NULL) + { + return OMX_ErrorInsufficientResources; + } + + *bufferHdr = (m_inp_heap_ptr + i); + input = *bufferHdr; + BITMASK_SET(&m_heap_inp_bm_count,i); + + input->pBuffer = (OMX_U8 *)buf_addr; + input->nSize = sizeof(OMX_BUFFERHEADERTYPE); + input->nVersion.nVersion = OMX_SPEC_VERSION; + input->nAllocLen = drv_ctx.ip_buf.buffer_size; + input->pAppPrivate = appData; + input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; + DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr ); + eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); + DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); + /*Add the Buffers to freeq*/ + if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i], + (unsigned)NULL, (unsigned)NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); + return OMX_ErrorInsufficientResources; + } + } + else + { + return OMX_ErrorBadParameter; + } + + return eRet; + +} + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateInputBuffer + +DESCRIPTION + Helper function for allocate buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_input_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct vdec_setbuffer_cmd setbuffers; + OMX_BUFFERHEADERTYPE *input = NULL; + unsigned i = 0; + unsigned char *buf_addr = NULL; + int pmem_fd = -1; + + if(bytes != drv_ctx.ip_buf.buffer_size) + { + DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d", + bytes, drv_ctx.ip_buf.buffer_size); + return OMX_ErrorBadParameter; + } + + if(!m_inp_mem_ptr) + { + DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)", + drv_ctx.ip_buf.actualcount, + drv_ctx.ip_buf.buffer_size); + + m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); + + if (m_inp_mem_ptr == NULL) + { + return OMX_ErrorInsufficientResources; + } + + drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ + calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); + + if (drv_ctx.ptr_inputbuffer == NULL) + { + return OMX_ErrorInsufficientResources; + } +#ifdef USE_ION + drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ + calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); + + if (drv_ctx.ip_buf_ion_info == NULL) + { + return OMX_ErrorInsufficientResources; + } +#endif + + for (i=0; i < drv_ctx.ip_buf.actualcount; i++) + { + drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; +#ifdef USE_ION + drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; +#endif + } + } + + for(i=0; i< drv_ctx.ip_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_inp_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); + break; + } + } + + if(i < drv_ctx.ip_buf.actualcount) + { + struct v4l2_buffer buf; + struct v4l2_plane plane; + int rc; + +#ifdef USE_ION + DEBUG_PRINT_HIGH("\n Allocate input Buffer size %d\n", drv_ctx.ip_buf.buffer_size); + drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( + drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, + &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, + &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); + if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; +#else + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); + return OMX_ErrorInsufficientResources; + } + + if (pmem_fd == 0) + { + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, + drv_ctx.ip_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if (!secure_mode) { + buf_addr = (unsigned char *)mmap(NULL, + drv_ctx.ip_buf.buffer_size, + PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); + + if (buf_addr == MAP_FAILED) + { + close(pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); +#endif + DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); + return OMX_ErrorInsufficientResources; + } + } + *bufferHdr = (m_inp_mem_ptr + i); + if (secure_mode) + drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; + else + drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; + drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; + drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; + drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; + drv_ctx.ptr_inputbuffer [i].offset = 0; + + + buf.index = i; + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane.bytesused = 0; + plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; + plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; + plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; + plane.reserved[1] = 0; + plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; + buf.m.planes = &plane; + buf.length = 1; + + DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_inputbuffer[i]); + + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); + + if (rc) { + DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); + /*TODO: How to handle this case */ + return OMX_ErrorInsufficientResources; + } + + input = *bufferHdr; + BITMASK_SET(&m_inp_bm_count,i); + DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr); + if (secure_mode) + input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; + else + input->pBuffer = (OMX_U8 *)buf_addr; + input->nSize = sizeof(OMX_BUFFERHEADERTYPE); + input->nVersion.nVersion = OMX_SPEC_VERSION; + input->nAllocLen = drv_ctx.ip_buf.buffer_size; + input->pAppPrivate = appData; + input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; + input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; + + if (drv_ctx.disable_dmx) + { + eRet = allocate_desc_buffer(i); + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateOutputBuffer + +DESCRIPTION + Helper fn for AllocateBuffer in the output pin + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything went well. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + struct vdec_setbuffer_cmd setbuffers; + int extra_idx = 0; +#ifdef USE_ION + int ion_device_fd =-1; + struct ion_allocation_data ion_alloc_data; + struct ion_fd_data fd_ion_data; +#endif + if(!m_out_mem_ptr) + { + DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)", + drv_ctx.op_buf.actualcount, + drv_ctx.op_buf.buffer_size); + int nBufHdrSize = 0; + int nPlatformEntrySize = 0; + int nPlatformListSize = 0; + int nPMEMInfoSize = 0; + int pmem_fd = -1; + unsigned char *pmem_baseaddress = NULL; + + OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; + + DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n", + drv_ctx.op_buf.actualcount); + nBufHdrSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_BUFFERHEADERTYPE); + + nPMEMInfoSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); + nPlatformListSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); + nPlatformEntrySize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); + + DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, + sizeof(OMX_BUFFERHEADERTYPE), + nPMEMInfoSize, + nPlatformListSize); + DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize, + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + DEBUG_PRINT_HIGH("allocate outputBuffer size %d \n",drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount); + ion_device_fd = alloc_map_ion_memory( + drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount, + drv_ctx.op_buf.alignment, + &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0); + if (ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + pmem_fd = fd_ion_data.fd; +#else + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", + drv_ctx.op_buf.buffer_size); + return OMX_ErrorInsufficientResources; + } + + if(pmem_fd == 0) + { + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", + drv_ctx.op_buf.buffer_size); + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size * + drv_ctx.op_buf.actualcount, + drv_ctx.op_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if (!secure_mode) { + pmem_baseaddress = (unsigned char *)mmap(NULL, + (drv_ctx.op_buf.buffer_size * + drv_ctx.op_buf.actualcount), + PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); + if (pmem_baseaddress == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\n MMAP failed for Size %d", + drv_ctx.op_buf.buffer_size); + close(pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[i]); +#endif + return OMX_ErrorInsufficientResources; + } + } + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + // Alloc mem for platform specific info + char *pPtr=NULL; + pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + + nPMEMInfoSize,1); + drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ + calloc (sizeof(struct vdec_bufferpayload), + drv_ctx.op_buf.actualcount); + drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ + calloc (sizeof (struct vdec_output_frameinfo), + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ + calloc (sizeof(struct vdec_ion), + drv_ctx.op_buf.actualcount); +#endif + + if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer + && drv_ctx.ptr_respbuffer) + { + drv_ctx.ptr_outputbuffer[0].mmaped_size = + (drv_ctx.op_buf.buffer_size * + drv_ctx.op_buf.actualcount); + bufHdr = m_out_mem_ptr; + m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); + m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) + (((char *) m_platform_list) + nPlatformListSize); + m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + (((char *) m_platform_entry) + nPlatformEntrySize); + pPlatformList = m_platform_list; + pPlatformEntry = m_platform_entry; + pPMEMInfo = m_pmem_info; + + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); + + // Settting the entire storage nicely + DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry); + DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); + for(i=0; i < drv_ctx.op_buf.actualcount ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = bytes; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = appData; + bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + // Platform specific PMEM Information + // Initialize the Platform Entry + //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i); + pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pPlatformEntry->entry = pPMEMInfo; + // Initialize the Platform List + pPlatformList->nEntries = 1; + pPlatformList->entryList = pPlatformEntry; + // Keep pBuffer NULL till vdec is opened + bufHdr->pBuffer = NULL; + bufHdr->nOffset = 0; + + pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; + pPMEMInfo->pmem_fd = 0; + bufHdr->pPlatformPrivate = pPlatformList; + + drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd; + m_pmem_info[i].pmem_fd = pmem_fd; +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd; + drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data; + drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data; +#endif + + /*Create a mapping between buffers*/ + bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; + drv_ctx.ptr_respbuffer[i].client_data = (void *)\ + &drv_ctx.ptr_outputbuffer[i]; + drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; + drv_ctx.ptr_outputbuffer[i].bufferaddr = + pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); + + DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p", + pmem_fd, drv_ctx.ptr_outputbuffer[i].offset, + drv_ctx.ptr_outputbuffer[i].bufferaddr); + // Move the buffer and buffer header pointers + bufHdr++; + pPMEMInfo++; + pPlatformEntry++; + pPlatformList++; + } + } + else + { + DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ + m_out_mem_ptr, pPtr); + if(m_out_mem_ptr) + { + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(pPtr) + { + free(pPtr); + pPtr = NULL; + } + if(drv_ctx.ptr_outputbuffer) + { + free(drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } + if(drv_ctx.ptr_respbuffer) + { + free(drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif + eRet = OMX_ErrorInsufficientResources; + } + if (eRet == OMX_ErrorNone) + eRet = allocate_extradata(); + } + + for(i=0; i< drv_ctx.op_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); + break; + } + } + + if (eRet == OMX_ErrorNone) + { + if(i < drv_ctx.op_buf.actualcount) + { + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + int rc; + m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; + + drv_ctx.ptr_outputbuffer[i].buffer_len = + drv_ctx.op_buf.buffer_size; + + *bufferHdr = (m_out_mem_ptr + i ); + if (secure_mode) { + drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; + } + drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; + + buf.index = i; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].length = drv_ctx.op_buf.buffer_size; + plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - + (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; +#ifdef USE_ION + plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; +#endif + plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; + plane[0].data_offset = 0; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; + plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + buf.m.planes = plane; + buf.length = drv_ctx.num_planes; + DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); + if (rc) { + /*TODO: How to handle this case */ + return OMX_ErrorInsufficientResources; + } + + if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { + enum v4l2_buf_type buf_type; + buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); + if (rc) { + return OMX_ErrorInsufficientResources; + } else { + streaming[CAPTURE_PORT] = true; + DEBUG_PRINT_LOW("\n STREAMON Successful \n "); + } + } + + (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; + (*bufferHdr)->pAppPrivate = appData; + BITMASK_SET(&m_out_bm_count,i); + } + else + { + DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n"); + eRet = OMX_ErrorInsufficientResources; + } + } + + return eRet; +} + + +// AllocateBuffer -- API Call +/* ====================================================================== +FUNCTION + omx_vdec::AllocateBuffer + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + unsigned i = 0; + OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type + + DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if(port == OMX_CORE_INPUT_PORT_INDEX) + { + if (arbitrary_bytes) + { + eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); + } + else + { + eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); + } + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + { + eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, + appData,bytes); + } + else + { + DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); + if(eRet == OMX_ErrorNone) + { + if(allocate_done()){ + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + } + DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); + return eRet; +} + +// Free Buffer - API call +/* ====================================================================== +FUNCTION + omx_vdec::FreeBuffer + +DESCRIPTION + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int nPortIndex; + DEBUG_PRINT_LOW("In for decoder free_buffer \n"); + + if(m_state == OMX_StateIdle && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); + } + else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| + (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) + { + DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); + } + else if ((port == OMX_CORE_INPUT_PORT_INDEX && + BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || + (port == OMX_CORE_OUTPUT_PORT_INDEX && + BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) + { + DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port); + } + else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) + { + DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + + return OMX_ErrorIncorrectStateOperation; + } + else if (m_state != OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + } + + if(port == OMX_CORE_INPUT_PORT_INDEX) + { + /*Check if arbitrary bytes*/ + if(!arbitrary_bytes && !input_use_buffer) + nPortIndex = buffer - m_inp_mem_ptr; + else + nPortIndex = buffer - m_inp_heap_ptr; + + DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex); + if(nPortIndex < drv_ctx.ip_buf.actualcount) + { + // Clear the bit associated with it. + BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); + BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); + if (input_use_buffer == true) + { + + DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex); + if(m_phdr_pmem_ptr) + free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); + } + else + { + if (arbitrary_bytes) + { + if(m_phdr_pmem_ptr) + free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); + else + free_input_buffer(nPortIndex,NULL); + } + else + free_input_buffer(buffer); + } + m_inp_bPopulated = OMX_FALSE; + /*Free the Buffer Header*/ + if (release_input_done()) + { + DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released"); + free_input_buffer_header(); + } + } + else + { + DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) + && release_input_done()) + { + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); + post_event(OMX_CommandPortDisable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + { + // check if the buffer is valid + nPortIndex = buffer - client_buffers.get_il_buf_hdr(); + if(nPortIndex < drv_ctx.op_buf.actualcount) + { + DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex); + // Clear the bit associated with it. + BITMASK_CLEAR(&m_out_bm_count,nPortIndex); + m_out_bPopulated = OMX_FALSE; + client_buffers.free_output_buffer (buffer); + + if (release_output_done()) + { + free_output_buffer_header(); + } + } + else + { + DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) + && release_output_done()) + { + DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); + + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); + memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); + } +#endif + + post_event(OMX_CommandPortDisable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else + { + eRet = OMX_ErrorBadPortIndex; + } + if((eRet == OMX_ErrorNone) && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + if(release_done()) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); + post_event(OMX_CommandStateSet, OMX_StateLoaded, + OMX_COMPONENT_GENERATE_EVENT); + } + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::EmptyThisBuffer + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE ret1 = OMX_ErrorNone; + unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (buffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); + return OMX_ErrorBadParameter; + } + + if (!m_inp_bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled."); + return OMX_ErrorIncorrectStateOperation; + } + + if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) + { + DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex); + return OMX_ErrorBadPortIndex; + } + +#ifdef _ANDROID_ + if(iDivXDrmDecrypt) + { + OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer); + if(drmErr != OMX_ErrorNone) { + // this error can be ignored + DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr); + } + } +#endif //_ANDROID_ + if (perf_flag) + { + if (!latency) + { + dec_time.stop(); + latency = dec_time.processing_time_us(); + dec_time.start(); + } + } + + if (arbitrary_bytes) + { + nBufferIndex = buffer - m_inp_heap_ptr; + } + else + { + if (input_use_buffer == true) + { + nBufferIndex = buffer - m_inp_heap_ptr; + m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; + m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; + m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; + buffer = &m_inp_mem_ptr[nBufferIndex]; + DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d", + &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); + } + else{ + nBufferIndex = buffer - m_inp_mem_ptr; + } + } + + if (nBufferIndex > drv_ctx.ip_buf.actualcount ) + { + DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", + buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); + if (arbitrary_bytes) + { + post_event ((unsigned)hComp,(unsigned)buffer, + OMX_COMPONENT_GENERATE_ETB_ARBITRARY); + } + else + { + if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) + set_frame_rate(buffer->nTimeStamp); + post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::empty_this_buffer_proxy + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + int push_cnt = 0,i=0; + unsigned nPortIndex = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + struct vdec_input_frameinfo frameinfo; + struct vdec_bufferpayload *temp_buffer; + struct vdec_seqheader seq_header; + bool port_setting_changed = true; + bool not_coded_vop = false; + + /*Should we generate a Aync error event*/ + if (buffer == NULL || buffer->pInputPortPrivate == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); + return OMX_ErrorBadParameter; + } + + nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + + if (nPortIndex > drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", + nPortIndex); + return OMX_ErrorBadParameter; + } + + pending_input_buffers++; + + /* return zero length and not an EOS buffer */ + if (!arbitrary_bytes && (buffer->nFilledLen == 0) && + ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) + { + DEBUG_PRINT_HIGH("\n return zero legth buffer"); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorNone; + } + + + if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){ + mp4StreamType psBits; + psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); + psBits.numBytes = buffer->nFilledLen; + mp4_headerparser.parseHeader(&psBits); + not_coded_vop = mp4_headerparser.is_notcodec_vop( + (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); + if(not_coded_vop) { + DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u", + buffer->nFilledLen,frame_count); + if(buffer->nFlags & OMX_BUFFERFLAG_EOS){ + DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero"); + not_coded_vop = false; + buffer->nFilledLen = 0; + } + } + } + + if(input_flush_progress == true + + || not_coded_vop + + ) + { + DEBUG_PRINT_LOW("\n Flush in progress return buffer "); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorNone; + } + + temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; + + if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) + { + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + /*for use buffer we need to memcpy the data*/ + temp_buffer->buffer_len = buffer->nFilledLen; + + if (input_use_buffer) + { + if (buffer->nFilledLen <= temp_buffer->buffer_len) + { + if(arbitrary_bytes) + { + memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); + } + else + { + memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), + buffer->nFilledLen); + } + } + else + { + return OMX_ErrorBadParameter; + } + + } + + frameinfo.bufferaddr = temp_buffer->bufferaddr; + frameinfo.client_data = (void *) buffer; + frameinfo.datalen = temp_buffer->buffer_len; + frameinfo.flags = 0; + frameinfo.offset = buffer->nOffset; + frameinfo.pmem_fd = temp_buffer->pmem_fd; + frameinfo.pmem_offset = temp_buffer->offset; + frameinfo.timestamp = buffer->nTimeStamp; + if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) + { + DEBUG_PRINT_LOW("ETB: dmx enabled"); + if (m_demux_entries == 0) + { + extract_demux_addr_offsets(buffer); + } + + DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries); + handle_demux_data(buffer); + frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; + frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; + } + else + { + frameinfo.desc_addr = NULL; + frameinfo.desc_size = 0; + } + if(!arbitrary_bytes) + { + frameinfo.flags |= buffer->nFlags; + } + +#ifdef _ANDROID_ + if (m_debug_timestamp) + { + if(arbitrary_bytes) + { + DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); + m_timestamp_list.insert_ts(buffer->nTimeStamp); + } + else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) + { + DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); + m_timestamp_list.insert_ts(buffer->nTimeStamp); + } + } +#endif + +#ifdef INPUT_BUFFER_LOG + if (inputBufferFile1) + { + fwrite((const char *)temp_buffer->bufferaddr, + temp_buffer->buffer_len,1,inputBufferFile1); + } +#endif + + if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) + { + frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; + } + + if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) + { + DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached"); + frameinfo.flags |= VDEC_BUFFERFLAG_EOS; + h264_scratch.nFilledLen = 0; + nal_count = 0; + look_ahead_nal = false; + frame_count = 0; + if (m_frame_parser.mutils) + m_frame_parser.mutils->initialize_frame_checking_environment(); + m_frame_parser.flush(); + h264_last_au_ts = LLONG_MAX; + h264_last_au_flags = 0; + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + } + struct v4l2_buffer buf; + struct v4l2_plane plane; + memset( (void *)&buf, 0, sizeof(buf)); + memset( (void *)&plane, 0, sizeof(plane)); + int rc; + unsigned long print_count; + if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) + { buf.flags = V4L2_BUF_FLAG_EOS; + DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ; + } + OMX_ERRORTYPE eRet = OMX_ErrorNone; + buf.index = nPortIndex; + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane.bytesused = temp_buffer->buffer_len; + plane.length = drv_ctx.ip_buf.buffer_size; + plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - + (unsigned long)temp_buffer->offset; + plane.reserved[0] = temp_buffer->pmem_fd; + plane.reserved[1] = temp_buffer->offset; + plane.data_offset = 0; + buf.m.planes = &plane; + buf.length = 1; + if (frameinfo.timestamp >= LLONG_MAX) { + buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; + } + //assumption is that timestamp is in milliseconds + buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; + buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); + buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; + + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); + if(rc) + { + DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n"); + return OMX_ErrorHardware; + } + if(!streaming[OUTPUT_PORT]) + { + enum v4l2_buf_type buf_type; + int ret,r; + + buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); + ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); + if(!ret) { + DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n"); + streaming[OUTPUT_PORT] = true; + } else{ + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n"); + DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorBadParameter; + } +} + DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", + frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); + time_stamp_dts.insert_timestamp(buffer); + + return ret; +} + +/* ====================================================================== +FUNCTION + omx_vdec::FillThisBuffer + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("FTB in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (!m_out_bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled."); + return OMX_ErrorIncorrectStateOperation; + } + + if (buffer == NULL || + ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) + { + return OMX_ErrorBadParameter; + } + + if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) + { + DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex); + return OMX_ErrorBadPortIndex; + } + + DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg); + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_vdec::fill_this_buffer_proxy + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) +{ + OMX_ERRORTYPE nRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *buffer = bufferAdd; + unsigned nPortIndex = 0; + struct vdec_fillbuffer_cmd fillbuffer; + struct vdec_bufferpayload *ptr_outputbuffer = NULL; + struct vdec_output_frameinfo *ptr_respbuffer = NULL; + + nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); + + if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) + return OMX_ErrorBadParameter; + + DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", + bufferAdd, bufferAdd->pBuffer); + /*Return back the output buffer to client*/ + if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true) + { + DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + return OMX_ErrorNone; + } + pending_output_buffers++; + buffer = client_buffers.get_dr_buf_hdr(bufferAdd); + ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; + if (ptr_respbuffer) + { + ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; + } + + if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) + { + DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + pending_output_buffers--; + return OMX_ErrorBadParameter; + } + + /* memcpy (&fillbuffer.buffer,ptr_outputbuffer, + sizeof(struct vdec_bufferpayload)); + fillbuffer.client_data = bufferAdd;*/ + +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + // Acquire a write lock on this buffer. + if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle, + GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { + DEBUG_PRINT_ERROR("Failed to acquire genlock"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + pending_output_buffers--; + return OMX_ErrorInsufficientResources; + } else { + native_buffer[buffer - m_out_mem_ptr].inuse = true; + } + } +#endif + int rc = 0; + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + memset( (void *)&buf, 0, sizeof(buf)); + memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); + int extra_idx = 0; + + buf.index = nPortIndex; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].bytesused = buffer->nFilledLen; + plane[0].length = drv_ctx.op_buf.buffer_size; + plane[0].m.userptr = + (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - + (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; + plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; + plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; + plane[0].data_offset = 0; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].bytesused = 0; + plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; + plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + buf.m.planes = plane; + buf.length = drv_ctx.num_planes; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); + if (rc) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to qbuf to driver"); + } +//#ifdef _ANDROID_ICS_ + // if (m_enable_android_native_buffers) + // { + // Unlock the buffer + // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { + // DEBUG_PRINT_ERROR("Releasing genlock failed"); + // return OMX_ErrorInsufficientResources; + /// } else { + // native_buffer[buffer - m_out_mem_ptr].inuse = false; + // } + // } +//#endif + //m_cb.FillBufferDone (hComp,m_app_data,buffer); + // pending_output_buffers--; + // return OMX_ErrorBadParameter; + //} + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SetCallbacks + +DESCRIPTION + Set the callbacks. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_CALLBACKTYPE* callbacks, + OMX_IN OMX_PTR appData) +{ + + m_cb = *callbacks; + DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ + m_cb.EventHandler,m_cb.FillBufferDone); + m_app_data = appData; + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentDeInit + +DESCRIPTION + Destroys the component and release memory allocated to the heap. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) +{ +#ifdef _ANDROID_ + if(iDivXDrmDecrypt) + { + delete iDivXDrmDecrypt; + iDivXDrmDecrypt=NULL; + } +#endif //_ANDROID_ + + unsigned i = 0; + if (OMX_StateLoaded != m_state) + { + DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ + m_state); + DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); + } + else + { + DEBUG_PRINT_HIGH("\n Playback Ended - PASSED"); + } + + /*Check if the output buffers have to be cleaned up*/ + if(m_out_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing the Output Memory\n"); + for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) + { + free_output_buffer (&m_out_mem_ptr[i]); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + if (native_buffer[i].inuse) + { + if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) { + DEBUG_PRINT_ERROR("Unlocking genlock failed"); + } + native_buffer[i].inuse = false; + } + } +#endif + } +#ifdef _ANDROID_ICS_ + memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); +#endif + } + + /*Check if the input buffers have to be cleaned up*/ + if(m_inp_mem_ptr || m_inp_heap_ptr) + { + DEBUG_PRINT_LOW("Freeing the Input Memory\n"); + for (i = 0; i. + +PARAMETERS + . + +RETURN VALUE + Not Implemented error. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN void* eglImage) +{ + OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; + +#ifdef USE_EGL_IMAGE_GPU + PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; + EGLint fd = -1, offset = 0,pmemPtr = 0; +#else + int fd = -1, offset = 0; +#endif + DEBUG_PRINT_HIGH("\nuse EGL image support for decoder"); + if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { + DEBUG_PRINT_ERROR("\n "); + } +#ifdef USE_EGL_IMAGE_GPU + if(m_display_id == NULL) { + DEBUG_PRINT_ERROR("Display ID is not set by IL client \n"); + return OMX_ErrorInsufficientResources; + } + egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) + eglGetProcAddress("eglQueryImageKHR"); + egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); + egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); + egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); +#else //with OMX test app + struct temp_egl { + int pmem_fd; + int offset; + }; + struct temp_egl *temp_egl_id = NULL; + void * pmemPtr = (void *) eglImage; + temp_egl_id = (struct temp_egl *)eglImage; + if (temp_egl_id != NULL) + { + fd = temp_egl_id->pmem_fd; + offset = temp_egl_id->offset; + } +#endif + if (fd < 0) { + DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd); + return OMX_ErrorInsufficientResources; + } + pmem_info.pmem_fd = (OMX_U32) fd; + pmem_info.offset = (OMX_U32) offset; + pmem_entry.entry = (void *) &pmem_info; + pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pmem_list.entryList = &pmem_entry; + pmem_list.nEntries = 1; + ouput_egl_buffers = true; + if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, + (void *)&pmem_list, drv_ctx.op_buf.buffer_size, + (OMX_U8 *)pmemPtr)) { + DEBUG_PRINT_ERROR("use buffer call failed for egl image\n"); + return OMX_ErrorInsufficientResources; + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentRoleEnum + +DESCRIPTION + OMX Component Role Enum method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_U8* role, + OMX_IN OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) + ) + + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } + return eRet; +} + + + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateDone + +DESCRIPTION + Checks if entire buffer pool is allocated by IL Client or not. + Need this to move to IDLE state. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_vdec::allocate_done(void) +{ + bool bRet = false; + bool bRet_In = false; + bool bRet_Out = false; + + bRet_In = allocate_input_done(); + bRet_Out = allocate_output_done(); + + if(bRet_In && bRet_Out) + { + bRet = true; + } + + return bRet; +} +/* ====================================================================== +FUNCTION + omx_vdec::AllocateInputDone + +DESCRIPTION + Checks if I/P buffer pool is allocated by IL Client or not. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_vdec::allocate_input_done(void) +{ + bool bRet = false; + unsigned i=0; + + if (m_inp_mem_ptr == NULL) + { + return bRet; + } + if(m_inp_mem_ptr ) + { + for(;i= drv_ctx.op_buf.actualcount) + { + DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer); + return OMX_ErrorBadParameter; + } + else if (output_flush_progress) + { + DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); + buffer->nFilledLen = 0; + buffer->nTimeStamp = 0; + buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; + buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; + } + + DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", + buffer, buffer->pBuffer); + pending_output_buffers --; + + if (buffer->nFlags & OMX_BUFFERFLAG_EOS) + { + DEBUG_PRINT_HIGH("\n Output EOS has been reached"); + if (!output_flush_progress) + post_event((unsigned)NULL, (unsigned)NULL, + OMX_COMPONENT_GENERATE_EOS_DONE); + + if (psource_frame) + { + m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); + psource_frame = NULL; + } + if (pdest_frame) + { + pdest_frame->nFilledLen = 0; + m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL, + (unsigned)NULL); + pdest_frame = NULL; + } + } + + DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer); +#ifdef OUTPUT_BUFFER_LOG + if (outputBufferFile1 && buffer->nFilledLen) + { + int buf_index = buffer - m_out_mem_ptr; + int stride = drv_ctx.video_resolution.stride; + int scanlines = drv_ctx.video_resolution.scan_lines; + char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; + int i; + int bytes_written = 0; + for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { + bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); + temp += stride; + } + temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; + int stride_c = stride; + for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { + bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); + temp += stride_c; + } + } +#endif + + /* For use buffer we need to copy the data */ + if (!output_flush_progress) + { + time_stamp_dts.get_next_timestamp(buffer, + (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + if (m_debug_timestamp) + { + { + OMX_TICKS expected_ts = 0; + m_timestamp_list.pop_min_ts(expected_ts); + DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", + buffer->nTimeStamp, expected_ts); + + if (buffer->nTimeStamp != expected_ts) + { + DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check"); + } + } + } + } + if (m_cb.FillBufferDone) + { + if (buffer->nFilledLen > 0) + { + handle_extradata(buffer); + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + // Keep min timestamp interval to handle corrupted bit stream scenario + set_frame_rate(buffer->nTimeStamp); + else if (arbitrary_bytes) + adjust_timestamp(buffer->nTimeStamp); + if (perf_flag) + { + if (!proc_frms) + { + dec_time.stop(); + latency = dec_time.processing_time_us() - latency; + DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); + dec_time.start(); + fps_metrics.start(); + } + proc_frms++; + if (buffer->nFlags & OMX_BUFFERFLAG_EOS) + { + OMX_U64 proc_time = 0; + fps_metrics.stop(); + proc_time = fps_metrics.processing_time_us(); + DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", + proc_frms, (float)proc_time / 1e6, + (float)(1e6 * proc_frms) / proc_time); + proc_frms = 0; + } + } + +#ifdef OUTPUT_EXTRADATA_LOG + if (outputExtradataFile) + { + + OMX_OTHER_EXTRADATATYPE *p_extra = NULL; + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(buffer->pBuffer + buffer->nOffset + + buffer->nFilledLen + 3)&(~3)); + while(p_extra && + (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) + { + DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); + fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); + if (p_extra->eType == OMX_ExtraDataNone) + { + break; + } + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + } +#endif + } + if (buffer->nFlags & OMX_BUFFERFLAG_EOS){ + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } + + pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) + buffer->pPlatformPrivate)->entryList->entry; + DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + if (native_buffer[buffer - m_out_mem_ptr].inuse) { + if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { + DEBUG_PRINT_ERROR("Unlocking genlock failed"); + return OMX_ErrorInsufficientResources; + } + else { + native_buffer[buffer - m_out_mem_ptr].inuse = false; + } + } + } +#endif + OMX_BUFFERHEADERTYPE *il_buffer; + il_buffer = client_buffers.get_il_buf_hdr(buffer); + if (il_buffer) + m_cb.FillBufferDone (hComp,m_app_data,il_buffer); + else { + DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd); + } + else + { + return OMX_ErrorBadParameter; + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE* buffer) +{ + + if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) + { + DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer); + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", + buffer, buffer->pBuffer); + pending_input_buffers--; + + if (arbitrary_bytes) + { + if (pdest_frame == NULL && input_flush_progress == false) + { + DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer); + pdest_frame = buffer; + buffer->nFilledLen = 0; + buffer->nTimeStamp = LLONG_MAX; + push_input_buffer (hComp); + } + else + { + DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer); + buffer->nFilledLen = 0; + if (!m_input_free_q.insert_entry((unsigned)buffer, + (unsigned)NULL, (unsigned)NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); + } + } + } + else if(m_cb.EmptyBufferDone) + { + buffer->nFilledLen = 0; + if (input_use_buffer == true){ + buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; + } + m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); + } + return OMX_ErrorNone; +} + +int omx_vdec::async_message_process (void *context, void* message) +{ + omx_vdec* omx = NULL; + struct vdec_msginfo *vdec_msg = NULL; + OMX_BUFFERHEADERTYPE* omxhdr = NULL; + struct v4l2_buffer *v4l2_buf_ptr = NULL; + struct vdec_output_frameinfo *output_respbuf = NULL; + int rc=1; + if (context == NULL || message == NULL) + { + DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); + return -1; + } + vdec_msg = (struct vdec_msginfo *)message; + + omx = reinterpret_cast(context); + + switch (vdec_msg->msgcode) + { + + case VDEC_MSG_EVT_HW_ERROR: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_HARDWARE_ERROR); + break; + + case VDEC_MSG_RESP_START_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_START_DONE); + break; + + case VDEC_MSG_RESP_STOP_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + break; + + case VDEC_MSG_RESP_RESUME_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_RESUME_DONE); + break; + + case VDEC_MSG_RESP_PAUSE_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_PAUSE_DONE); + break; + + case VDEC_MSG_RESP_FLUSH_INPUT_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); + break; + case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); + break; + case VDEC_MSG_RESP_INPUT_FLUSHED: + case VDEC_MSG_RESP_INPUT_BUFFER_DONE: + + /* omxhdr = (OMX_BUFFERHEADERTYPE* ) + vdec_msg->msgdata.input_frame_clientdata; */ + + v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; + omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index; + if (omxhdr == NULL || + ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) + { + omxhdr = NULL; + vdec_msg->status_code = VDEC_S_EFATAL; + } + + omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, + OMX_COMPONENT_GENERATE_EBD); + break; + case VDEC_MSG_EVT_INFO_FIELD_DROPPED: + int64_t *timestamp; + timestamp = (int64_t *) malloc(sizeof(int64_t)); + if (timestamp) { + *timestamp = vdec_msg->msgdata.output_frame.time_stamp; + omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); + DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld", + vdec_msg->msgdata.output_frame.time_stamp); + } + break; + case VDEC_MSG_RESP_OUTPUT_FLUSHED: + case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: + + v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; + omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index; + DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", + omxhdr, vdec_msg->msgdata.output_frame.time_stamp, + vdec_msg->msgdata.output_frame.pic_type); + + if (omxhdr && omxhdr->pOutputPortPrivate && + ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && + (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate + - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) + { + if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) + { + omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; + omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; + omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; + omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags; + + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) + { + omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; + //rc = -1; + } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) + { + omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + } + vdec_msg->msgdata.output_frame.bufferaddr = + omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; + if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft != + vdec_msg->msgdata.output_frame.framesize.left) + || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) + || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) + || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) { + omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; + omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; + omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; + omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; + DEBUG_PRINT_HIGH("\n Crop information has changed\n"); + omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, + OMX_COMPONENT_GENERATE_PORT_RECONFIG); + } + output_respbuf = (struct vdec_output_frameinfo *)\ + omxhdr->pOutputPortPrivate; + output_respbuf->len = vdec_msg->msgdata.output_frame.len; + output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) + { + output_respbuf->pic_type = PICTURE_TYPE_I; + } + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) + { + output_respbuf->pic_type = PICTURE_TYPE_P; + } + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { + output_respbuf->pic_type = PICTURE_TYPE_B; + } + + if (omx->output_use_buffer) + memcpy ( omxhdr->pBuffer, (void *) + ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + + (unsigned long)vdec_msg->msgdata.output_frame.offset), + vdec_msg->msgdata.output_frame.len); + } + else + omxhdr->nFilledLen = 0; + omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_FBD); + } + else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) + omx->post_event ((unsigned int)NULL, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_EOS_DONE); + else + omx->post_event ((unsigned int)NULL, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_HARDWARE_ERROR); + break; + case VDEC_MSG_EVT_CONFIG_CHANGED: + DEBUG_PRINT_HIGH("\n Port settings changed"); + omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, + OMX_COMPONENT_GENERATE_PORT_RECONFIG); + break; + case VDEC_MSG_EVT_INFO_CONFIG_CHANGED: + { + DEBUG_PRINT_HIGH("\n Port settings changed info"); + // get_buffer_req and populate port defn structure + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_format fmt; + int ret; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); + omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); + omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline; + omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0]; + omx->m_port_def.nPortIndex = 1; + eRet = omx->update_portdef(&(omx->m_port_def)); + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG); + break; + } + default: + break; + } + return rc; +} + +OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ) +{ + unsigned address,p2,id; + DEBUG_PRINT_LOW("\n Empty this arbitrary"); + + if (buffer == NULL) + { + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u", + buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp); + + /* return zero length and not an EOS buffer */ + /* return buffer if input flush in progress */ + if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && + ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) + { + DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress"); + m_cb.EmptyBufferDone (hComp,m_app_data,buffer); + return OMX_ErrorNone; + } + + if (psource_frame == NULL) + { + DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp); + psource_frame = buffer; + DEBUG_PRINT_LOW("\n Try to Push One Input Buffer "); + push_input_buffer (hComp); + } + else + { + DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer); + if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL, + (unsigned)NULL)) + { + return OMX_ErrorBadParameter; + } + } + + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) +{ + unsigned address,p2,id; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (pdest_frame == NULL || psource_frame == NULL) + { + /*Check if we have a destination buffer*/ + if (pdest_frame == NULL) + { + DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue"); + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *)address; + pdest_frame->nFilledLen = 0; + pdest_frame->nTimeStamp = LLONG_MAX; + DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame); + } + } + + /*Check if we have a destination buffer*/ + if (psource_frame == NULL) + { + DEBUG_PRINT_LOW("\n Get a source buffer from the queue"); + if (m_input_pending_q.m_size) + { + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *)address; + DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, + psource_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", + psource_frame->nFlags,psource_frame->nFilledLen); + + } + } + + } + + while ((pdest_frame != NULL) && (psource_frame != NULL)) + { + switch (codec_type_parse) + { + case CODEC_TYPE_MPEG4: + case CODEC_TYPE_H263: + case CODEC_TYPE_MPEG2: + ret = push_input_sc_codec(hComp); + break; + case CODEC_TYPE_H264: + ret = push_input_h264(hComp); + break; + case CODEC_TYPE_HEVC: + ret = push_input_hevc(hComp); + break; + case CODEC_TYPE_VC1: + ret = push_input_vc1(hComp); + break; + default: + break; + } + if (ret != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); + omx_report_error (); + break; + } + } + + return ret; +} + +OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) +{ + OMX_U32 partial_frame = 1; + OMX_BOOL generate_ebd = OMX_TRUE; + unsigned address,p2,id; + + DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d", + psource_frame,psource_frame->nTimeStamp); + if (m_frame_parser.parse_sc_frame(psource_frame, + pdest_frame,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); + return OMX_ErrorBadParameter; + } + + if (partial_frame == 0) + { + DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d", + pdest_frame->nFilledLen,psource_frame,frame_count); + + + DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp); + /*First Parsed buffer will have only header Hence skip*/ + if (frame_count == 0) + { + DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame "); + + if(codec_type_parse == CODEC_TYPE_MPEG4 || + codec_type_parse == CODEC_TYPE_DIVX) { + mp4StreamType psBits; + psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; + psBits.numBytes = pdest_frame->nFilledLen; + mp4_headerparser.parseHeader(&psBits); + } + + frame_count++; + } + else + { + pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; + if(pdest_frame->nFilledLen) + { + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *) address; + pdest_frame->nFilledLen = 0; + } + } + else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) + { + DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL"); + m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL, + (unsigned)NULL); + pdest_frame = NULL; + } + } + } + else + { + DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen); + /*Check if Destination Buffer is full*/ + if (pdest_frame->nAllocLen == + pdest_frame->nFilledLen + pdest_frame->nOffset) + { + DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); + return OMX_ErrorStreamCorrupt; + } + } + + if (psource_frame->nFilledLen == 0) + { + if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) + { + if (pdest_frame) + { + pdest_frame->nFlags |= psource_frame->nFlags; + DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", + pdest_frame->nFilledLen,frame_count++); + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + } + else + { + DEBUG_PRINT_LOW("\n Last frame in else dest addr") ; + generate_ebd = OMX_FALSE; + } + } + if(generate_ebd) + { + DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame); + m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); + psource_frame = NULL; + + if (m_input_pending_q.m_size) + { + DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, + psource_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", + psource_frame->nFlags,psource_frame->nFilledLen); + } + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) +{ + OMX_U32 partial_frame = 1; + unsigned address,p2,id; + OMX_BOOL isNewFrame = OMX_FALSE; + OMX_BOOL generate_ebd = OMX_TRUE; + + if (h264_scratch.pBuffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %d " + "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); + DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); + if (h264_scratch.nFilledLen && look_ahead_nal) + { + look_ahead_nal = false; + if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame"); + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + if (nal_length == 0) + { + DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code"); + if (m_frame_parser.parse_sc_frame(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); + return OMX_ErrorBadParameter; + } + } + else + { + DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); + if (m_frame_parser.parse_h264_nallength(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); + return OMX_ErrorBadParameter; + } + } + + if (partial_frame == 0) + { + if (nal_count == 0 && h264_scratch.nFilledLen == 0) + { + DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip"); + nal_count++; + h264_scratch.nTimeStamp = psource_frame->nTimeStamp; + h264_scratch.nFlags = psource_frame->nFlags; + } + else + { + DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen); + if(h264_scratch.nFilledLen) + { + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, + NALU_TYPE_SPS); +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, + h264_scratch.nFilledLen, NALU_TYPE_SEI); + else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + // If timeinfo is present frame info from SEI is already processed + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, + h264_scratch.nFilledLen, NALU_TYPE_SEI); +#endif + m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); + nal_count++; + if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { + pdest_frame->nTimeStamp = h264_last_au_ts; + pdest_frame->nFlags = h264_last_au_flags; +#ifdef PANSCAN_HDLR + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + h264_parser->update_panscan_data(h264_last_au_ts); +#endif + } + if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || + m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { + h264_last_au_ts = h264_scratch.nTimeStamp; + h264_last_au_flags = h264_scratch.nFlags; +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); + if (!VALID_TS(h264_last_au_ts)) + h264_last_au_ts = ts_in_sei; + } +#endif + } else + h264_last_au_ts = LLONG_MAX; + } + + if (!isNewFrame) + { + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d", + h264_scratch.nFilledLen); + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) + pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + else + { + look_ahead_nal = true; + DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", + pdest_frame->nFilledLen,frame_count++); + + if (pdest_frame->nFilledLen == 0) + { + DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it"); + look_ahead_nal = false; + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + else + { + if(psource_frame->nFilledLen || h264_scratch.nFilledLen) + { + DEBUG_PRINT_LOW("\n Reset the EOS Flag"); + pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; + } + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + //frame_count++; + pdest_frame = NULL; + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame); + pdest_frame->nFilledLen = 0; + pdest_frame->nFlags = 0; + pdest_frame->nTimeStamp = LLONG_MAX; + } + } + } + } + } + else + { + DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); + /*Check if Destination Buffer is full*/ + if (h264_scratch.nAllocLen == + h264_scratch.nFilledLen + h264_scratch.nOffset) + { + DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); + return OMX_ErrorStreamCorrupt; + } + } + + if (!psource_frame->nFilledLen) + { + DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame); + + if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) + { + if (pdest_frame) + { + DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer"); + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; + pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; + + DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%d TimeStamp = %x", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++); +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); + if (!VALID_TS(pdest_frame->nTimeStamp)) + pdest_frame->nTimeStamp = ts_in_sei; + } +#endif + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + } + else + { + DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d", + pdest_frame,h264_scratch.nFilledLen); + generate_ebd = OMX_FALSE; + } + } + } + if(generate_ebd && !psource_frame->nFilledLen) + { + m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); + psource_frame = NULL; + if (m_input_pending_q.m_size) + { + DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("\nNext source Buffer flag %d src length %d", + psource_frame->nFlags,psource_frame->nFilledLen); + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc) +{ + OMX_ERRORTYPE rc = OMX_ErrorNone; + if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) + { + memcpy ((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen); + if (pDst->nTimeStamp == LLONG_MAX || pDst->nTimeStamp == 0) + { + pDst->nTimeStamp = pSrc->nTimeStamp; + DEBUG_PRINT_LOW("Assign Dst nTimeStamp=%lld", pDst->nTimeStamp); + } + pDst->nFilledLen += pSrc->nFilledLen; + pSrc->nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("Error: Destination buffer overflow\n"); + rc = OMX_ErrorBadParameter; + } + return rc; +} + +OMX_ERRORTYPE omx_vdec::push_input_hevc (OMX_HANDLETYPE hComp) +{ + OMX_U32 partial_frame = 1; + unsigned address,p2,id; + OMX_BOOL isNewFrame = OMX_FALSE; + OMX_BOOL generate_ebd = OMX_TRUE; + OMX_ERRORTYPE rc = OMX_ErrorNone; + + if (h264_scratch.pBuffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:Hevc Scratch Buffer not allocated"); + return OMX_ErrorBadParameter; + } + + + DEBUG_PRINT_LOW("h264_scratch.nFilledLen %d has look_ahead_nal %d pdest_frame nFilledLen %d nTimeStamp %lld\n", + h264_scratch.nFilledLen, look_ahead_nal, pdest_frame->nFilledLen, pdest_frame->nTimeStamp); + + if (h264_scratch.nFilledLen && look_ahead_nal) + { + look_ahead_nal = false; + + // copy the lookahead buffer in the scratch + rc = copy_buffer(pdest_frame, &h264_scratch); + if (rc != OMX_ErrorNone) + { + return rc; + } + } + if (nal_length == 0) + { + if (m_frame_parser.parse_sc_frame(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); + return OMX_ErrorBadParameter; + } + } + else + { + DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d\n",nal_length); + if (m_frame_parser.parse_h264_nallength(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); + return OMX_ErrorBadParameter; + } + } + + if (partial_frame == 0) + { + if (nal_count == 0 && h264_scratch.nFilledLen == 0) + { + DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip"); + nal_count++; + h264_scratch.nTimeStamp = psource_frame->nTimeStamp; + h264_scratch.nFlags = psource_frame->nFlags; + } + else + { + DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen); + if(h264_scratch.nFilledLen) + { + mHEVCutils.isNewFrame(&h264_scratch, 0, isNewFrame); + nal_count++; + } + + if (!isNewFrame) + { + DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %d nTimestamp %lld, pdest_frame nFilledLen %d nTimestamp %lld\n", + h264_scratch.nFilledLen, h264_scratch.nTimeStamp, pdest_frame->nFilledLen, pdest_frame->nTimeStamp); + rc = copy_buffer(pdest_frame, &h264_scratch); + if ( rc != OMX_ErrorNone) + { + return rc; + } + } + else + { + look_ahead_nal = true; + if (pdest_frame->nFilledLen == 0) + { + look_ahead_nal = false; + DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer\n"); + rc = copy_buffer(pdest_frame, &h264_scratch); + if ( rc != OMX_ErrorNone ) + { + return OMX_ErrorBadParameter; + } + } + else + { + if(psource_frame->nFilledLen || h264_scratch.nFilledLen) + { + pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; + } + + DEBUG_PRINT_LOW("FrameDetecetd # %d pdest_frame nFilledLen %d nTimeStamp %lld, look_ahead_nal in h264_scratch nFilledLen %d nTimeStamp %lld \n", + frame_count++, pdest_frame->nFilledLen, pdest_frame->nTimeStamp, h264_scratch.nFilledLen, h264_scratch.nTimeStamp); + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + pdest_frame = NULL; + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("pop the next pdest_buffer %p\n",pdest_frame); + pdest_frame->nFilledLen = 0; + pdest_frame->nFlags = 0; + pdest_frame->nTimeStamp = LLONG_MAX; + } + } + } + } + } + else + { + DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %d nTimeStamp %lld, pdest_frame nFilledLen %d nTimeStamp %lld, h264_scratch nFilledLen %d nTimeStamp %lld \n", + psource_frame->nFilledLen, psource_frame->nTimeStamp, pdest_frame->nFilledLen, pdest_frame->nTimeStamp, h264_scratch.nFilledLen, h264_scratch.nTimeStamp); + + /*Check if Destination Buffer is full*/ + if (h264_scratch.nAllocLen == + h264_scratch.nFilledLen + h264_scratch.nOffset) + { + DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); + return OMX_ErrorStreamCorrupt; + } + } + + if (!psource_frame->nFilledLen) + { + DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client\n",psource_frame); + + if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) + { + if (pdest_frame) + { + DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer\n"); + rc = copy_buffer(pdest_frame, &h264_scratch); + if ( rc != OMX_ErrorNone ) + { + return rc; + } + pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; + pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; + + DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%d TimeStamp = %lld\n", + frame_count, pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + } + else + { + DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d", + pdest_frame,h264_scratch.nFilledLen); + generate_ebd = OMX_FALSE; + } + } + } + if(generate_ebd && !psource_frame->nFilledLen) + { + m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); + psource_frame = NULL; + if (m_input_pending_q.m_size) + { + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("Next source Buffer flag %d nFilledLen %d, nTimeStamp %lld\n", + psource_frame->nFlags,psource_frame->nFilledLen, psource_frame->nTimeStamp); + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) +{ + OMX_U8 *buf, *pdest; + OMX_U32 partial_frame = 1; + OMX_U32 buf_len, dest_len; + + if(first_frame == 0) + { + first_frame = 1; + DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n"); + if(!m_vendor_config.pData) + { + DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n"); + buf = psource_frame->pBuffer; + buf_len = psource_frame->nFilledLen; + + if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == + VC1_SP_MP_START_CODE) + { + m_vc1_profile = VC1_SP_MP_RCV; + } + else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) + { + m_vc1_profile = VC1_AP; + } + else + { + DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n"); + return OMX_ErrorStreamCorrupt; + } + } + else + { + pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + + pdest_frame->nOffset; + dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + + pdest_frame->nOffset); + + if(dest_len < m_vendor_config.nDataSize) + { + DEBUG_PRINT_ERROR("\nDestination buffer full\n"); + return OMX_ErrorBadParameter; + } + else + { + memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); + pdest_frame->nFilledLen += m_vendor_config.nDataSize; + } + } + } + + switch(m_vc1_profile) + { + case VC1_AP: + DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code"); + if (push_input_sc_codec(hComp) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); + return OMX_ErrorBadParameter; + } + break; + + case VC1_SP_MP_RCV: + default: + DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n"); + return OMX_ErrorBadParameter; + } + return OMX_ErrorNone; +} + +bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, + OMX_U32 alignment) +{ + struct pmem_allocation allocation; + allocation.size = buffer_size; + allocation.align = clip2(alignment); + if (allocation.align < 4096) + { + allocation.align = 4096; + } + if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) + { + DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", + allocation.align, allocation.size); + return false; + } + return true; +} +#ifdef USE_ION +int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, + OMX_U32 alignment, struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data, int flag) +{ + int fd = -EINVAL; + int rc = -EINVAL; + int ion_dev_flag; + struct vdec_ion ion_buf_info; + if (!alloc_data || buffer_size <= 0 || !fd_data) { + DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n"); + return -EINVAL; + } + ion_dev_flag = O_RDONLY; + fd = open (MEM_DEVICE, ion_dev_flag); + if (fd < 0) { + DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd); + return fd; + } + alloc_data->flags = 0; + if(!secure_mode && (flag & ION_FLAG_CACHED)) + { + alloc_data->flags |= ION_FLAG_CACHED; + } + alloc_data->len = buffer_size; + alloc_data->align = clip2(alignment); + if (alloc_data->align < 4096) + { + alloc_data->align = 4096; + } + if ((secure_mode) && (flag & ION_SECURE)) + alloc_data->flags |= ION_SECURE; + +#ifdef _HEVC_USE_ADSP_HEAP_ + alloc_data->heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); +#else + alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); +#endif + if (secure_mode) { + alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); + } + rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); + if (rc || !alloc_data->handle) { + DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); + alloc_data->handle = NULL; + close(fd); + fd = -ENOMEM; + return fd; + } + fd_data->handle = alloc_data->handle; + rc = ioctl(fd,ION_IOC_MAP,fd_data); + if (rc) { + DEBUG_PRINT_ERROR("\n ION MAP failed "); + ion_buf_info.ion_alloc_data = *alloc_data; + ion_buf_info.ion_device_fd = fd; + ion_buf_info.fd_ion_data = *fd_data; + free_ion_memory(&ion_buf_info); + fd_data->fd =-1; + close(fd); + fd = -ENOMEM; + } + + return fd; +} + +void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) { + + if(!buf_ion_info) { + DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata"); + return; + } + if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, + &buf_ion_info->ion_alloc_data.handle)) { + DEBUG_PRINT_ERROR("\n ION: free failed" ); + } + close(buf_ion_info->ion_device_fd); + buf_ion_info->ion_device_fd = -1; + buf_ion_info->ion_alloc_data.handle = NULL; + buf_ion_info->fd_ion_data.fd = -1; +} +#endif +void omx_vdec::free_output_buffer_header() +{ + DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released"); + output_use_buffer = false; + ouput_egl_buffers = false; + + if (m_out_mem_ptr) + { + free (m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + + if(m_platform_list) + { + free(m_platform_list); + m_platform_list = NULL; + } + + if (drv_ctx.ptr_respbuffer) + { + free (drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } + if (drv_ctx.ptr_outputbuffer) + { + free (drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif +} + +void omx_vdec::free_input_buffer_header() +{ + input_use_buffer = false; + if (arbitrary_bytes) + { + if (m_frame_parser.mutils) + { + DEBUG_PRINT_LOW("\n Free utils parser"); + delete (m_frame_parser.mutils); + m_frame_parser.mutils = NULL; + } + + if (m_inp_heap_ptr) + { + DEBUG_PRINT_LOW("\n Free input Heap Pointer"); + free (m_inp_heap_ptr); + m_inp_heap_ptr = NULL; + } + + if (m_phdr_pmem_ptr) + { + DEBUG_PRINT_LOW("\n Free input pmem header Pointer"); + free (m_phdr_pmem_ptr); + m_phdr_pmem_ptr = NULL; + } + } + if (m_inp_mem_ptr) + { + DEBUG_PRINT_LOW("\n Free input pmem Pointer area"); + free (m_inp_mem_ptr); + m_inp_mem_ptr = NULL; + } + if (drv_ctx.ptr_inputbuffer) + { + DEBUG_PRINT_LOW("\n Free Driver Context pointer"); + free (drv_ctx.ptr_inputbuffer); + drv_ctx.ptr_inputbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.ip_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free ion context"); + free(drv_ctx.ip_buf_ion_info); + drv_ctx.ip_buf_ion_info = NULL; + } +#endif +} + +int omx_vdec::stream_off(OMX_U32 port) +{ + enum v4l2_buf_type btype; + int rc = 0; + enum v4l2_ports v4l2_port = OUTPUT_PORT; + + if (port == OMX_CORE_INPUT_PORT_INDEX) { + btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + v4l2_port = OUTPUT_PORT; + } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { + btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + v4l2_port = CAPTURE_PORT; + } else if (port == OMX_ALL) { + int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); + int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); + + if (!rc_input) + return rc_input; + else + return rc_output; + } + + if (!streaming[v4l2_port]) { + // already streamed off, warn and move on + DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," + " which is already streamed off", v4l2_port); + return 0; + } + + DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); + + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); + if (rc) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port); + } else { + streaming[v4l2_port] = false; + } + + return rc; +} + +OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_requestbuffers bufreq; + unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; + struct v4l2_format fmt; + int ret = 0; + + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 1; + if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.pixelformat = output_capability; + }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.pixelformat = capture_capability; + }else {eRet = OMX_ErrorBadParameter;} + if(eRet==OMX_ErrorNone){ + ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); + } + if(ret) + { + DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); + /*TODO: How to handle this case */ + eRet = OMX_ErrorInsufficientResources; + return eRet; + } + else + { + buffer_prop->actualcount = bufreq.count; + buffer_prop->mincount = bufreq.count; + DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count); + } + DEBUG_PRINT_HIGH("GetBufReq: ActCnt(%d) Size(%d), BufType(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type); + + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); + + update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); + if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; + DEBUG_PRINT_HIGH("Buffer Size (plane[0].sizeimage) = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); + + if(ret) + { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + int extra_idx = 0; + buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + buf_size = buffer_prop->buffer_size; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + { + DEBUG_PRINT_HIGH("Frame info extra data enabled!"); + client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; + } + if (client_extradata & OMX_INTERLACE_EXTRADATA) + { + client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; + } + if (client_extradata & OMX_PORTDEF_EXTRADATA) + { + client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; + DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n", + client_extra_data_size); + } + if (client_extra_data_size) + { + client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator + buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit + } + drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size; + drv_ctx.extradata_info.count = buffer_prop->actualcount; + drv_ctx.extradata_info.buffer_size = extra_data_size; + buf_size += client_extra_data_size; + buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); + DEBUG_PRINT_HIGH("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d) BufType(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size, buf_size, buffer_prop->buffer_type); + if (in_reconfig) // BufReq will be set to driver when port is disabled + buffer_prop->buffer_size = buf_size; + else if (buf_size != buffer_prop->buffer_size) + { + buffer_prop->buffer_size = buf_size; + eRet = set_buffer_req(buffer_prop); + } + } + DEBUG_PRINT_HIGH("GetBufReq OUT: ActCnt(%d) Size(%d), BufType(%d)\n", + buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type); + return eRet; +} + +OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned buf_size = 0; + struct v4l2_format fmt; + struct v4l2_requestbuffers bufreq; + int ret; + DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); + if (buf_size != buffer_prop->buffer_size) + { + DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", + buffer_prop->buffer_size, buf_size); + eRet = OMX_ErrorBadParameter; + } + else + { + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + + if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ + fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.pixelformat = output_capability; + } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.pixelformat = capture_capability; + } else {eRet = OMX_ErrorBadParameter;} + + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) + { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); + eRet = OMX_ErrorInsufficientResources; + } + + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = buffer_prop->actualcount; + if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + } else {eRet = OMX_ErrorBadParameter;} + + if (eRet==OMX_ErrorNone) { + ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); + } + + if (ret) + { + DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); + /*TODO: How to handle this case */ + eRet = OMX_ErrorInsufficientResources; + } else if (bufreq.count < buffer_prop->actualcount) { + DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" + " on v4l2 port %d to %d (prefers %d)", bufreq.type, + buffer_prop->actualcount, bufreq.count); + eRet = OMX_ErrorInsufficientResources; + } else { + if (!client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); + eRet = OMX_ErrorInsufficientResources; + } + } + } + if (!eRet && buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) + { + // need to update extradata buffers also + drv_ctx.extradata_info.size = buffer_prop->actualcount * drv_ctx.extradata_info.buffer_size; + drv_ctx.extradata_info.count = buffer_prop->actualcount; + } + return eRet; +} + +OMX_ERRORTYPE omx_vdec::update_picture_resolution() +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + return eRet; +} + +OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (!portDefn) + { + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("omx_vdec::update_portdef\n"); + portDefn->nVersion.nVersion = OMX_SPEC_VERSION; + portDefn->nSize = sizeof(portDefn); + portDefn->eDomain = OMX_PortDomainVideo; + if (drv_ctx.frame_rate.fps_denominator > 0) + portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / + drv_ctx.frame_rate.fps_denominator; + else { + DEBUG_PRINT_ERROR("Error: Divide by zero \n"); + return OMX_ErrorBadParameter; + } + if (0 == portDefn->nPortIndex) + { + portDefn->eDir = OMX_DirInput; + portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; + portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; + portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; + portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; + portDefn->format.video.eCompressionFormat = eCompressionFormat; + portDefn->bEnabled = m_inp_bEnabled; + portDefn->bPopulated = m_inp_bPopulated; + } + else if (1 == portDefn->nPortIndex) + { + unsigned int buf_size = 0; + if (!client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed"); + return OMX_ErrorHardware; + } + if (!client_buffers.get_buffer_req(buf_size)) { + DEBUG_PRINT_ERROR("\n update buffer requirements"); + return OMX_ErrorHardware; + } + portDefn->nBufferSize = buf_size; + portDefn->eDir = OMX_DirOutput; + portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; + portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; + portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + portDefn->bEnabled = m_out_bEnabled; + portDefn->bPopulated = m_out_bPopulated; + if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { + DEBUG_PRINT_ERROR("\n Error in getting color format"); + return OMX_ErrorHardware; + } + } + else + { + portDefn->eDir = OMX_DirMax; + DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; + portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; + portDefn->format.video.nStride = drv_ctx.video_resolution.stride; + portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; + DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld" + " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight, + portDefn->format.video.nStride, + portDefn->format.video.nSliceHeight); + return eRet; + +} + +OMX_ERRORTYPE omx_vdec::allocate_output_headers() +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr = NULL; + unsigned i= 0; + + if(!m_out_mem_ptr) { + DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation"); + int nBufHdrSize = 0; + int nPlatformEntrySize = 0; + int nPlatformListSize = 0; + int nPMEMInfoSize = 0; + OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; + + DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n", + drv_ctx.op_buf.actualcount); + nBufHdrSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_BUFFERHEADERTYPE); + + nPMEMInfoSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); + nPlatformListSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); + nPlatformEntrySize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); + + DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, + sizeof(OMX_BUFFERHEADERTYPE), + nPMEMInfoSize, + nPlatformListSize); + DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize, + m_out_bm_count); + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + // Alloc mem for platform specific info + char *pPtr=NULL; + pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + + nPMEMInfoSize,1); + drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ + calloc (sizeof(struct vdec_bufferpayload), + drv_ctx.op_buf.actualcount); + drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ + calloc (sizeof (struct vdec_output_frameinfo), + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ + calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); +#endif + + if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer + && drv_ctx.ptr_respbuffer) + { + bufHdr = m_out_mem_ptr; + m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); + m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) + (((char *) m_platform_list) + nPlatformListSize); + m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + (((char *) m_platform_entry) + nPlatformEntrySize); + pPlatformList = m_platform_list; + pPlatformEntry = m_platform_entry; + pPMEMInfo = m_pmem_info; + + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); + + // Settting the entire storage nicely + DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, + m_out_mem_ptr,pPlatformEntry); + DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); + for(i=0; i < drv_ctx.op_buf.actualcount ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = 0; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = NULL; + bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pPlatformEntry->entry = pPMEMInfo; + // Initialize the Platform List + pPlatformList->nEntries = 1; + pPlatformList->entryList = pPlatformEntry; + // Keep pBuffer NULL till vdec is opened + bufHdr->pBuffer = NULL; + pPMEMInfo->offset = 0; + pPMEMInfo->pmem_fd = 0; + bufHdr->pPlatformPrivate = pPlatformList; + drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; +#endif + /*Create a mapping between buffers*/ + bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; + drv_ctx.ptr_respbuffer[i].client_data = (void *) \ + &drv_ctx.ptr_outputbuffer[i]; + // Move the buffer and buffer header pointers + bufHdr++; + pPMEMInfo++; + pPlatformEntry++; + pPlatformList++; + } + } + else + { + DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ + m_out_mem_ptr, pPtr); + if(m_out_mem_ptr) + { + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(pPtr) + { + free(pPtr); + pPtr = NULL; + } + if(drv_ctx.ptr_outputbuffer) + { + free(drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } + if(drv_ctx.ptr_respbuffer) + { + free(drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif + eRet = OMX_ErrorInsufficientResources; + } + } else { + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + +void omx_vdec::complete_pending_buffer_done_cbs() +{ + unsigned p1; + unsigned p2; + unsigned ident; + omx_cmd_queue tmp_q, pending_bd_q; + pthread_mutex_lock(&m_lock); + // pop all pending GENERATE FDB from ftb queue + while (m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_FBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to ftb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_ftb_q.insert_entry(p1,p2,ident); + } + // pop all pending GENERATE EDB from etb queue + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_EBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to etb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_etb_q.insert_entry(p1,p2,ident); + } + pthread_mutex_unlock(&m_lock); + // process all pending buffer dones + while(pending_bd_q.m_size) + { + pending_bd_q.pop_entry(&p1,&p2,&ident); + switch(ident) + { + case OMX_COMPONENT_GENERATE_EBD: + if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); + omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FBD: + if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); + omx_report_error (); + } + break; + } + } +} + +void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) +{ + OMX_U32 new_frame_interval = 0; + if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts + && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000)) + { + new_frame_interval = (act_timestamp > prev_ts)? + act_timestamp - prev_ts : + prev_ts - act_timestamp; + if (new_frame_interval < frm_int || frm_int == 0) + { + frm_int = new_frame_interval; + if(frm_int) + { + drv_ctx.frame_rate.fps_numerator = 1e6; + drv_ctx.frame_rate.fps_denominator = frm_int; + DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", + frm_int, drv_ctx.frame_rate.fps_numerator / + (float)drv_ctx.frame_rate.fps_denominator); + } + } + } + prev_ts = act_timestamp; +} + +void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) +{ + if (rst_prev_ts && VALID_TS(act_timestamp)) + { + prev_ts = act_timestamp; + rst_prev_ts = false; + } + else if (VALID_TS(prev_ts)) + { + bool codec_cond = (drv_ctx.timestamp_adjust)? + (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? + (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): + (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); + if(frm_int > 0 && codec_cond) + { + DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); + act_timestamp = prev_ts + frm_int; + DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); + prev_ts = act_timestamp; + } + else + set_frame_rate(act_timestamp); + } + else if (frm_int > 0) // In this case the frame rate was set along + { // with the port definition, start ts with 0 + act_timestamp = prev_ts = 0; // and correct if a valid ts is received. + rst_prev_ts = true; + } +} + +void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) +{ + OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; + OMX_U32 num_conceal_MB = 0; + OMX_U32 frame_rate = 0; + int consumed_len = 0; + OMX_U32 num_MB_in_frame; + OMX_U32 recovery_sei_flags = 1; + int buf_index = p_buf_hdr - m_out_mem_ptr; + struct msm_vidc_panscan_window_payload *panscan_payload = NULL; + OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) + + p_buf_hdr->nOffset; + if (!drv_ctx.extradata_info.uaddr) { + return; + } + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); + char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; + if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) + p_extra = NULL; + OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; + if (data) { + while((consumed_len < drv_ctx.extradata_info.buffer_size) + && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) { + if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) { + DEBUG_PRINT_LOW("Invalid extra data size"); + break; + } + switch((unsigned long)data->eType) { + case EXTRADATA_INTERLACE_VIDEO: + struct msm_vidc_interlace_payload *payload; + payload = (struct msm_vidc_interlace_payload *)data->data; + if (payload->format != INTERLACE_FRAME_PROGRESSIVE) { + int enable = 1; + OMX_U32 mbaff = 0; + mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; + if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; + else + drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; + if(m_enable_android_native_buffers) + setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, + PP_PARAM_INTERLACED, (void*)&enable); + } + if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) { + append_interlace_extradata(p_extra, payload->format); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + break; + case EXTRADATA_FRAME_RATE: + struct msm_vidc_framerate_payload *frame_rate_payload; + frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data; + frame_rate = frame_rate_payload->frame_rate; + break; + case EXTRADATA_TIMESTAMP: + struct msm_vidc_ts_payload *time_stamp_payload; + time_stamp_payload = (struct msm_vidc_ts_payload *)data->data; + p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo; + p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); + break; + case EXTRADATA_NUM_CONCEALED_MB: + struct msm_vidc_concealmb_payload *conceal_mb_payload; + conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data; + num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * + (drv_ctx.video_resolution.frame_height + 15)) >> 8; + num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); + break; + case EXTRADATA_ASPECT_RATIO: + struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; + aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data; + ((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; + ((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; + break; + case EXTRADATA_RECOVERY_POINT_SEI: + struct msm_vidc_recoverysei_payload *recovery_sei_payload; + recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data; + recovery_sei_flags = recovery_sei_payload->flags; + if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; + DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n"); + } + break; + case EXTRADATA_PANSCAN_WINDOW: + panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data; + break; + default: + goto unrecognized_extradata; + } + consumed_len += data->nSize; + data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); + } + if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + append_frame_info_extradata(p_extra, + num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, + panscan_payload,&((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);} + } +unrecognized_extradata: + if(!secure_mode && client_extradata) + append_terminator_extradata(p_extra); + return; +} + +OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, + bool is_internal, bool enable) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + struct v4l2_control control; + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); + return OMX_ErrorIncorrectStateOperation; + } + DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n", + client_extradata, requested_extradata, enable, is_internal); + + if (!is_internal) { + if (enable) + client_extradata |= requested_extradata; + else + client_extradata = client_extradata & ~requested_extradata; + } + + if (enable) { + if (requested_extradata & OMX_INTERLACE_EXTRADATA) { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set interlaced extradata." + " Quality of interlaced clips might be impacted.\n"); + } + } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) + { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set framerate extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); + } + } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) + { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n"); + } + } + } + ret = get_buffer_req(&drv_ctx.op_buf); + return ret; +} + +OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; + OMX_U8 *data_ptr = extra->data, data = 0; + while (byte_count < extra->nDataSize) + { + data = *data_ptr; + while (data) + { + num_MB += (data&0x01); + data >>= 1; + } + data_ptr++; + byte_count++; + } + num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * + (drv_ctx.video_resolution.frame_height + 15)) >> 8; + return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); +} + +void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + if (!m_debug_extradata) + return; + + DEBUG_PRINT_HIGH( + "============== Extra Data ==============\n" + " Size: %lu \n" + " Version: %lu \n" + " PortIndex: %lu \n" + " Type: %x \n" + " DataSize: %lu \n", + extra->nSize, extra->nVersion.nVersion, + extra->nPortIndex, extra->eType, extra->nDataSize); + + if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) + { + OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; + DEBUG_PRINT_HIGH( + "------ Interlace Format ------\n" + " Size: %lu \n" + " Version: %lu \n" + " PortIndex: %lu \n" + " Is Interlace Format: %d \n" + " Interlace Formats: %lu \n" + "=========== End of Interlace ===========\n", + intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, + intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); + } + else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) + { + OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; + + DEBUG_PRINT_HIGH( + "-------- Frame Format --------\n" + " Picture Type: %d \n" + " Interlace Type: %d \n" + " Pan Scan Total Frame Num: %lu \n" + " Concealed Macro Blocks: %lu \n" + " frame rate: %lu \n" + " Aspect Ratio X: %lu \n" + " Aspect Ratio Y: %lu \n", + fminfo->ePicType, + fminfo->interlaceType, + fminfo->panScan.numWindows, + fminfo->nConcealedMacroblocks, + fminfo->nFrameRate, + fminfo->aspectRatio.aspectRatioX, + fminfo->aspectRatio.aspectRatioY); + + for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) + { + DEBUG_PRINT_HIGH( + "------------------------------\n" + " Pan Scan Frame Num: %lu \n" + " Rectangle x: %ld \n" + " Rectangle y: %ld \n" + " Rectangle dx: %ld \n" + " Rectangle dy: %ld \n", + i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, + fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); + } + + DEBUG_PRINT_HIGH("========= End of Frame Format =========="); + } + else if (extra->eType == OMX_ExtraDataNone) + { + DEBUG_PRINT_HIGH("========== End of Terminator ==========="); + } + else + { + DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); + } +} + +void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 interlaced_format_type) +{ + OMX_STREAMINTERLACEFORMAT *interlace_format; + OMX_U32 mbaff = 0; + if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { + return; + } + extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; + extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); + interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; + interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); + interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; + interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; + if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) + { + interlace_format->bInterlaceFormat = OMX_FALSE; + interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; + } + else + { + interlace_format->bInterlaceFormat = OMX_TRUE; + interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; + drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; + } + print_debug_extradata(extra); +} + +void omx_vdec::fill_aspect_ratio_info( + struct vdec_aspectratioinfo *aspect_ratio_info, + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) +{ + m_extradata = frame_info; + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; + DEBUG_PRINT_LOW("aspectRatioX %d aspectRatioX %d", m_extradata->aspectRatio.aspectRatioX, + m_extradata->aspectRatio.aspectRatioY); +} + +void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate, + struct msm_vidc_panscan_window_payload *panscan_payload, + struct vdec_aspectratioinfo *aspect_ratio_info) +{ + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; + struct msm_vidc_panscan_window *panscan_window; + if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { + return; + } + extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; + extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); + frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; + switch (picture_type) + { + case PICTURE_TYPE_I: + frame_info->ePicType = OMX_VIDEO_PictureTypeI; + break; + case PICTURE_TYPE_P: + frame_info->ePicType = OMX_VIDEO_PictureTypeP; + break; + case PICTURE_TYPE_B: + frame_info->ePicType = OMX_VIDEO_PictureTypeB; + break; + default: + frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; + } + if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) + frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; + else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) + frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; + else + frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; + memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); + frame_info->nConcealedMacroblocks = num_conceal_mb; + frame_info->nFrameRate = frame_rate; + frame_info->panScan.numWindows = 0; + if(panscan_payload) { + frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; + panscan_window = &panscan_payload->wnd[0]; + for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) + { + frame_info->panScan.window[i].x = panscan_window->panscan_window_width; + frame_info->panScan.window[i].y = panscan_window->panscan_window_height; + frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; + frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; + panscan_window++; + } + } + fill_aspect_ratio_info(aspect_ratio_info, frame_info); + print_debug_extradata(extra); +} + +void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; + extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; + extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; + *portDefn = m_port_def; + DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u" + "sliceheight = %u \n",portDefn->format.video.nFrameHeight, + portDefn->format.video.nFrameWidth, + portDefn->format.video.nStride, + portDefn->format.video.nSliceHeight); +} + +void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + if (!client_extradata) { + return; + } + extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->eType = OMX_ExtraDataNone; + extra->nDataSize = 0; + extra->data[0] = 0; + + print_debug_extradata(extra); +} + +OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (index >= drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found"); + return OMX_ErrorInsufficientResources; + } + if (m_desc_buffer_ptr == NULL) + { + m_desc_buffer_ptr = (desc_buffer_hdr*) \ + calloc( (sizeof(desc_buffer_hdr)), + drv_ctx.ip_buf.actualcount); + if (m_desc_buffer_ptr == NULL) + { + DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + } + + m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); + if (m_desc_buffer_ptr[index].buf_addr == NULL) + { + DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed "); + return OMX_ErrorInsufficientResources; + } + + return eRet; +} + +void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) +{ + DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries); + if (m_demux_entries < 8192) + { + m_demux_offsets[m_demux_entries++] = address_offset; + } + return; +} + +void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) +{ + OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; + OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; + OMX_U32 index = 0; + + m_demux_entries = 0; + + while (index < bytes_to_parse) + { + if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && + (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || + ((buf[index] == 0x00) && (buf[index+1] == 0x00) && + (buf[index+2] == 0x01)) ) + { + //Found start code, insert address offset + insert_demux_addr_offset(index); + if (buf[index+2] == 0x01) // 3 byte start code + index += 3; + else //4 byte start code + index += 4; + } + else + index++; + } + DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries); + return; +} + +OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) +{ + //fix this, handle 3 byte start code, vc1 terminator entry + OMX_U8 *p_demux_data = NULL; + OMX_U32 desc_data = 0; + OMX_U32 start_addr = 0; + OMX_U32 nal_size = 0; + OMX_U32 suffix_byte = 0; + OMX_U32 demux_index = 0; + OMX_U32 buffer_index = 0; + + if (m_desc_buffer_ptr == NULL) + { + DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); + return OMX_ErrorBadParameter; + } + + buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + if (buffer_index > drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index); + return OMX_ErrorBadParameter; + } + + p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; + + if ( ((OMX_U8*)p_demux_data == NULL) || + ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) + { + DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); + return OMX_ErrorBadParameter; + } + else + { + for (; demux_index < m_demux_entries; demux_index++) + { + desc_data = 0; + start_addr = m_demux_offsets[demux_index]; + if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) + { + suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; + } + else + { + suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; + } + if (demux_index < (m_demux_entries - 1)) + { + nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; + } + else + { + nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; + } + DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)", + start_addr, + suffix_byte, + nal_size, + demux_index); + desc_data = (start_addr >> 3) << 1; + desc_data |= (start_addr & 7) << 21; + desc_data |= suffix_byte << 24; + + memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); + memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); + memset(p_demux_data + 8, 0, sizeof(OMX_U32)); + memset(p_demux_data + 12, 0, sizeof(OMX_U32)); + + p_demux_data += 16; + } + if (codec_type_parse == CODEC_TYPE_VC1) + { + DEBUG_PRINT_LOW("VC1 terminator entry"); + desc_data = 0; + desc_data = 0x82 << 24; + memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); + memset(p_demux_data + 4, 0, sizeof(OMX_U32)); + memset(p_demux_data + 8, 0, sizeof(OMX_U32)); + memset(p_demux_data + 12, 0, sizeof(OMX_U32)); + p_demux_data += 16; + m_demux_entries++; + } + //Add zero word to indicate end of descriptors + memset(p_demux_data, 0, sizeof(OMX_U32)); + + m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); + DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size); + } + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + DEBUG_PRINT_LOW("Demux table complete!"); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::createDivxDrmContext() +{ + OMX_ERRORTYPE err = OMX_ErrorNone; + iDivXDrmDecrypt = DivXDrmDecrypt::Create(); + if (iDivXDrmDecrypt) { + OMX_ERRORTYPE err = iDivXDrmDecrypt->Init(); + if(err!=OMX_ErrorNone) { + DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err); + delete iDivXDrmDecrypt; + iDivXDrmDecrypt = NULL; + } + } + else { + DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM"); + err = OMX_ErrorUndefined; + } + return err; +} + +omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() +{ + enabled = false; + omx = NULL; + init_members(); + ColorFormat = OMX_COLOR_FormatMax; +} + +void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) +{ + omx = reinterpret_cast(client); +} + +void omx_vdec::allocate_color_convert_buf::init_members() { + allocated_count = 0; + buffer_size_req = 0; + buffer_alignment_req = 0; + memset(m_platform_list_client,0,sizeof(m_platform_list_client)); + memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); + memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); + memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); +#ifdef USE_ION + memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); +#endif + for (int i = 0; i < MAX_COUNT;i++) + pmem_fd[i] = -1; +} + +omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() { + c2d.destroy(); +} + +bool omx_vdec::allocate_color_convert_buf::update_buffer_req() +{ + bool status = true; + unsigned int src_size = 0, destination_size = 0; + OMX_COLOR_FORMATTYPE drv_color_format; + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid client in color convert"); + return false; + } + if (!enabled){ + DEBUG_PRINT_ERROR("\n No color conversion required"); + return status; + } + pthread_mutex_lock(&omx->c_lock); + if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && + ColorFormat != OMX_COLOR_FormatYUV420Planar) { + DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion"); + status = false; + goto fail_update_buf_req; + } + c2d.close(); + status = c2d.open(omx->drv_ctx.video_resolution.frame_height, + omx->drv_ctx.video_resolution.frame_width, + NV12_128m,YCbCr420P); + if (status) { + status = c2d.get_buffer_size(C2D_INPUT,src_size); + if (status) + status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); + } + if (status) { + if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || + !destination_size) { + DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d" + "driver size %d destination size %d", + src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); + status = false; + c2d.close(); + buffer_size_req = 0; + } else { + buffer_size_req = destination_size; + if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) + buffer_size_req = omx->drv_ctx.op_buf.buffer_size; + if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) + buffer_alignment_req = omx->drv_ctx.op_buf.alignment; + } + } +fail_update_buf_req: + pthread_mutex_unlock(&omx->c_lock); + return status; +} + +bool omx_vdec::allocate_color_convert_buf::set_color_format( + OMX_COLOR_FORMATTYPE dest_color_format) +{ + bool status = true; + OMX_COLOR_FORMATTYPE drv_color_format; + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid client in color convert"); + return false; + } + pthread_mutex_lock(&omx->c_lock); + if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) + drv_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + else { + DEBUG_PRINT_ERROR("\n Incorrect color format"); + status = false; + } + if (status && (drv_color_format != dest_color_format)) { + DEBUG_PRINT_LOW("Enabling C2D\n"); + if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { + DEBUG_PRINT_ERROR("\n Unsupported color format for c2d"); + status = false; + } else { + ColorFormat = OMX_COLOR_FormatYUV420Planar; + if (enabled) + c2d.destroy(); + enabled = false; + if (!c2d.init()) { + DEBUG_PRINT_ERROR("\n open failed for c2d"); + status = false; + } else + enabled = true; + } + } else { + if (enabled) + c2d.destroy(); + enabled = false; + } + pthread_mutex_unlock(&omx->c_lock); + return status; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return omx->m_out_mem_ptr; + return m_out_mem_ptr_client; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr + (OMX_BUFFERHEADERTYPE *bufadd) +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return bufadd; + + unsigned index = 0; + index = bufadd - omx->m_out_mem_ptr; + if (index < omx->drv_ctx.op_buf.actualcount) { + m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); + m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; + bool status; + if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { + pthread_mutex_lock(&omx->c_lock); + status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, + omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer,pmem_fd[index], + pmem_baseaddress[index], pmem_baseaddress[index]); + pthread_mutex_unlock(&omx->c_lock); + m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; + if (!status){ + DEBUG_PRINT_ERROR("\n Failed color conversion %d", status); + m_out_mem_ptr_client[index].nFilledLen = 0; + return &m_out_mem_ptr_client[index]; + } + } else + m_out_mem_ptr_client[index].nFilledLen = 0; + return &m_out_mem_ptr_client[index]; + } + DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr"); + return NULL; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr + (OMX_BUFFERHEADERTYPE *bufadd) +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return bufadd; + unsigned index = 0; + index = bufadd - m_out_mem_ptr_client; + if (index < omx->drv_ctx.op_buf.actualcount) { + return &omx->m_out_mem_ptr[index]; + } + DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr"); + return NULL; +} +bool omx_vdec::allocate_color_convert_buf::get_buffer_req + (unsigned int &buffer_size) +{ + bool status = true; + pthread_mutex_lock(&omx->c_lock); + if (!enabled) + buffer_size = omx->drv_ctx.op_buf.buffer_size; + else { + if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { + DEBUG_PRINT_ERROR("\n Get buffer size failed"); + status = false; + goto fail_get_buffer_size; + } + } + if (buffer_size < omx->drv_ctx.op_buf.buffer_size) + buffer_size = omx->drv_ctx.op_buf.buffer_size; + if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) + buffer_alignment_req = omx->drv_ctx.op_buf.alignment; +fail_get_buffer_size: + pthread_mutex_unlock(&omx->c_lock); + return status; +} +OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( + OMX_BUFFERHEADERTYPE *bufhdr) { + unsigned int index = 0; + + if (!enabled) + return omx->free_output_buffer(bufhdr); + if (enabled && omx->is_component_secure()) + return OMX_ErrorNone; + if (!allocated_count || !bufhdr) { + DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr); + return OMX_ErrorBadParameter; + } + index = bufhdr - m_out_mem_ptr_client; + if (index >= omx->drv_ctx.op_buf.actualcount){ + DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer"); + return OMX_ErrorBadParameter; + } + if (pmem_fd[index] > 0) { + munmap(pmem_baseaddress[index], buffer_size_req); + close(pmem_fd[index]); + } + pmem_fd[index] = -1; +#ifdef USE_ION + omx->free_ion_memory(&op_buf_ion_info[index]); +#endif + m_heap_ptr[index].video_heap_ptr = NULL; + if (allocated_count > 0) + allocated_count--; + else + allocated_count = 0; + if (!allocated_count) { + pthread_mutex_lock(&omx->c_lock); + c2d.close(); + init_members(); + pthread_mutex_unlock(&omx->c_lock); + } + return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); +} + +OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (!enabled){ + eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); + return eRet; + } + if (enabled && omx->is_component_secure()) { + DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d", + omx->is_component_secure()); + return OMX_ErrorUnsupportedSetting; + } + if (!bufferHdr || bytes > buffer_size_req) { + DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr); + DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu", + buffer_size_req,bytes); + return OMX_ErrorBadParameter; + } + if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert"); + return OMX_ErrorInsufficientResources; + } + OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; + eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, + port,appData,omx->drv_ctx.op_buf.buffer_size); + if (eRet != OMX_ErrorNone || !temp_bufferHdr){ + DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert"); + return eRet; + } + if ((temp_bufferHdr - omx->m_out_mem_ptr) >= + omx->drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("\n Invalid header index %d", + (temp_bufferHdr - omx->m_out_mem_ptr)); + return OMX_ErrorUndefined; + } + unsigned int i = allocated_count; +#ifdef USE_ION + op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( + buffer_size_req,buffer_alignment_req, + &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, + 0); + pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; + if (op_buf_ion_info[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert"); + return OMX_ErrorInsufficientResources; + } + pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, + PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); + + if (pmem_baseaddress[i] == MAP_FAILED) { + DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req); + close(pmem_fd[i]); + omx->free_ion_memory(&op_buf_ion_info[i]); + return OMX_ErrorInsufficientResources; + } + m_heap_ptr[i].video_heap_ptr = new VideoHeap ( + op_buf_ion_info[i].ion_device_fd,buffer_size_req, + pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); +#endif + m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); + m_pmem_info_client[i].offset = 0; + m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; + m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + m_platform_list_client[i].nEntries = 1; + m_platform_list_client[i].entryList = &m_platform_entry_client[i]; + m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; + m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; + m_out_mem_ptr_client[i].nFilledLen = 0; + m_out_mem_ptr_client[i].nFlags = 0; + m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); + m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; + m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; + m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; + m_out_mem_ptr_client[i].pAppPrivate = appData; + *bufferHdr = &m_out_mem_ptr_client[i]; + DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr); + allocated_count++; + return eRet; +} + +bool omx_vdec::is_component_secure() +{ + return secure_mode; +} + +bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) +{ + bool status = true; + if (!enabled) { + if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) + dest_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + else + status = false; + } else { + if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { + status = false; + } else + dest_color_format = OMX_COLOR_FormatYUV420Planar; + } + return status; +} diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp new file mode 100644 index 00000000..44810df4 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp @@ -0,0 +1,9668 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +/*============================================================================ + O p e n M A X w r a p p e r s + O p e n M A X C o r e + +*//** @file omx_vdec.cpp + This module contains the implementation of the OpenMAX core & component. + +*//*========================================================================*/ + +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include "omx_vdec.h" +#include +#include +#include +#include + +#ifndef _ANDROID_ +#include +#include +#endif //_ANDROID_ + +#ifdef _ANDROID_ +#include +#undef USE_EGL_IMAGE_GPU +#endif + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +#include +#endif + +#if defined (_ANDROID_ICS_) +#include +#include +#endif + +#ifdef _ANDROID_ +#include "DivXDrmDecrypt.h" +#endif //_ANDROID_ + +#ifdef USE_EGL_IMAGE_GPU +#include +#include +#define EGL_BUFFER_HANDLE_QCOM 0x4F00 +#define EGL_BUFFER_OFFSET_QCOM 0x4F01 +#endif +#ifdef INPUT_BUFFER_LOG +#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" +#define INPUT_BUFFER_FILE_NAME_LEN 30 +FILE *inputBufferFile1; +char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; +#endif +#ifdef OUTPUT_BUFFER_LOG +FILE *outputBufferFile1; +char outputfilename [] = "/data/output.yuv"; + +#endif +#ifdef OUTPUT_EXTRADATA_LOG +FILE *outputExtradataFile; +char ouputextradatafilename [] = "/data/extradata"; +#endif + +#define DEFAULT_FPS 30 +#define MAX_INPUT_ERROR DEFAULT_FPS +#define MAX_SUPPORTED_FPS 120 + +#define VC1_SP_MP_START_CODE 0xC5000000 +#define VC1_SP_MP_START_CODE_MASK 0xFF000000 +#define VC1_AP_SEQ_START_CODE 0x0F010000 +#define VC1_STRUCT_C_PROFILE_MASK 0xF0 +#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 +#define VC1_SIMPLE_PROFILE 0 +#define VC1_MAIN_PROFILE 1 +#define VC1_ADVANCE_PROFILE 3 +#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 +#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 +#define VC1_STRUCT_C_LEN 4 +#define VC1_STRUCT_C_POS 8 +#define VC1_STRUCT_A_POS 12 +#define VC1_STRUCT_B_POS 24 +#define VC1_SEQ_LAYER_SIZE 36 +#define POLL_TIMEOUT 0x7fffffff + +#define MEM_DEVICE "/dev/ion" +#define MEM_HEAP_ID ION_CP_MM_HEAP_ID + +#ifdef _ANDROID_ + extern "C"{ + #include + } +#endif//_ANDROID_ + +#define SZ_4K 0x1000 +#define SZ_1M 0x100000 + +#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } +#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } +#define EXTRADATA_IDX(__num_planes) (__num_planes - 1) + +#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA) +void* async_message_thread (void *input) +{ + OMX_BUFFERHEADERTYPE *buffer; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + struct pollfd pfd; + struct v4l2_buffer v4l2_buf; + memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); + struct v4l2_event dqevent; + omx_vdec *omx = reinterpret_cast(input); + pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; + pfd.fd = omx->drv_ctx.video_driver_fd; + int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; + DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n"); + prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); + while (1) + { + rc = poll(&pfd, 1, POLL_TIMEOUT); + if (!rc) { + DEBUG_PRINT_ERROR("Poll timedout\n"); + break; + } else if (rc < 0) { + DEBUG_PRINT_ERROR("Error while polling: %d\n", rc); + break; + } + if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { + struct vdec_msginfo vdec_msg; + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + v4l2_buf.memory = V4L2_MEMORY_USERPTR; + v4l2_buf.length = omx->drv_ctx.num_planes; + v4l2_buf.m.planes = plane; + while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { + vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; + vdec_msg.msgdata.output_frame.len=plane[0].bytesused; + vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; + vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + + (uint64_t)v4l2_buf.timestamp.tv_usec; + if (vdec_msg.msgdata.output_frame.len) { + vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2]; + vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3]; + vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4]; + vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5]; + } + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } + } + if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { + struct vdec_msginfo vdec_msg; + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + v4l2_buf.memory = V4L2_MEMORY_USERPTR; + v4l2_buf.length = 1; + v4l2_buf.m.planes = plane; + while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { + vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } + } + if (pfd.revents & POLLPRI){ + rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); + if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { + struct vdec_msginfo vdec_msg; + vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { + struct vdec_msginfo vdec_msg; + vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { + DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n"); + break; + } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { + struct vdec_msginfo vdec_msg; + vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR; + vdec_msg.status_code=VDEC_S_SUCCESS; + DEBUG_PRINT_HIGH("\n SYS Error Recieved \n"); + if (omx->async_message_process(input,&vdec_msg) < 0) { + DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); + break; + } + } else { + DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n"); + continue; + } + } + } + DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n"); + return NULL; +} + +void* message_thread(void *input) +{ + omx_vdec* omx = reinterpret_cast(input); + unsigned char id; + int n; + + DEBUG_PRINT_HIGH("omx_vdec: message thread start\n"); + prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); + while (1) + { + + n = read(omx->m_pipe_in, &id, 1); + + if(0 == n) + { + break; + } + + if (1 == n) + { + omx->process_event_cb(omx, id); + } + if ((n < 0) && (errno != EINTR)) + { + DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); + break; + } + } + DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n"); + return 0; +} + +void post_message(omx_vdec *omx, unsigned char id) +{ + int ret_value; + DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out); + ret_value = write(omx->m_pipe_out, &id, 1); + DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value); +} + +// omx_cmd_queue destructor +omx_vdec::omx_cmd_queue::~omx_cmd_queue() +{ + // Nothing to do +} + +// omx cmd queue constructor +omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) +{ + memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); +} + +// omx cmd queue insert +bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) +{ + bool ret = true; + if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_q[m_write].id = id; + m_q[m_write].param1 = p1; + m_q[m_write].param2 = p2; + m_write++; + m_size ++; + if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_write = 0; + } + } + else + { + ret = false; + DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__); + } + return ret; +} + +// omx cmd queue pop +bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) +{ + bool ret = true; + if (m_size > 0) + { + *id = m_q[m_read].id; + *p1 = m_q[m_read].param1; + *p2 = m_q[m_read].param2; + // Move the read pointer ahead + ++m_read; + --m_size; + if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_read = 0; + } + } + else + { + ret = false; + } + return ret; +} + +// Retrieve the first mesg type in the queue +unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() +{ + return m_q[m_read].id; +} + +#ifdef _ANDROID_ +omx_vdec::ts_arr_list::ts_arr_list() +{ + //initialize timestamps array + memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); +} +omx_vdec::ts_arr_list::~ts_arr_list() +{ + //free m_ts_arr_list? +} + +bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) +{ + bool ret = true; + bool duplicate_ts = false; + int idx = 0; + + //insert at the first available empty location + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + if (!m_ts_arr_list[idx].valid) + { + //found invalid or empty entry, save timestamp + m_ts_arr_list[idx].valid = true; + m_ts_arr_list[idx].timestamp = ts; + DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", + ts, idx); + break; + } + } + + if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) + { + DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); + ret = false; + } + return ret; +} + +bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) +{ + bool ret = true; + int min_idx = -1; + OMX_TICKS min_ts = 0; + int idx = 0; + + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + + if (m_ts_arr_list[idx].valid) + { + //found valid entry, save index + if (min_idx < 0) + { + //first valid entry + min_ts = m_ts_arr_list[idx].timestamp; + min_idx = idx; + } + else if (m_ts_arr_list[idx].timestamp < min_ts) + { + min_ts = m_ts_arr_list[idx].timestamp; + min_idx = idx; + } + } + + } + + if (min_idx < 0) + { + //no valid entries found + DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); + ts = 0; + ret = false; + } + else + { + ts = m_ts_arr_list[min_idx].timestamp; + m_ts_arr_list[min_idx].valid = false; + DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", + ts, min_idx); + } + + return ret; + +} + + +bool omx_vdec::ts_arr_list::reset_ts_list() +{ + bool ret = true; + int idx = 0; + + DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); + for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) + { + m_ts_arr_list[idx].valid = false; + } + return ret; +} +#endif + +// factory function executed by the core to create instances +void *get_omx_component_factory_fn(void) +{ + return (new omx_vdec); +} + +#ifdef _ANDROID_ +#ifdef USE_ION +VideoHeap::VideoHeap(int devicefd, size_t size, void* base, + struct ion_handle *handle, int ionMapfd) +{ +// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); +} +#else +VideoHeap::VideoHeap(int fd, size_t size, void* base) +{ + // dup file descriptor, map once, use pmem + init(dup(fd), base, size, 0 , MEM_DEVICE); +} +#endif +#endif // _ANDROID_ +/* ====================================================================== +FUNCTION + omx_vdec::omx_vdec + +DESCRIPTION + Constructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_vdec::omx_vdec(): m_error_propogated(false), + m_state(OMX_StateInvalid), + m_app_data(NULL), + m_inp_mem_ptr(NULL), + m_out_mem_ptr(NULL), + m_inp_err_count(0), + input_flush_progress (false), + output_flush_progress (false), + input_use_buffer (false), + output_use_buffer (false), + ouput_egl_buffers(false), + m_use_output_pmem(OMX_FALSE), + m_out_mem_region_smi(OMX_FALSE), + m_out_pvt_entry_pmem(OMX_FALSE), + pending_input_buffers(0), + pending_output_buffers(0), + m_out_bm_count(0), + m_inp_bm_count(0), + m_inp_bPopulated(OMX_FALSE), + m_out_bPopulated(OMX_FALSE), + m_flags(0), +#ifdef _ANDROID_ + m_heap_ptr(NULL), +#endif + m_inp_bEnabled(OMX_TRUE), + m_out_bEnabled(OMX_TRUE), + m_in_alloc_cnt(0), + m_platform_list(NULL), + m_platform_entry(NULL), + m_pmem_info(NULL), + arbitrary_bytes (true), + psource_frame (NULL), + pdest_frame (NULL), + m_inp_heap_ptr (NULL), + m_phdr_pmem_ptr(NULL), + m_heap_inp_bm_count (0), + codec_type_parse ((codec_type)0), + first_frame_meta (true), + frame_count (0), + nal_count (0), + nal_length(0), + look_ahead_nal (false), + first_frame(0), + first_buffer(NULL), + first_frame_size (0), + m_device_file_ptr(NULL), + m_vc1_profile((vc1_profile_type)0), + h264_last_au_ts(LLONG_MAX), + h264_last_au_flags(0), + prev_ts(LLONG_MAX), + rst_prev_ts(true), + frm_int(0), + m_disp_hor_size(0), + m_disp_vert_size(0), + in_reconfig(false), + m_display_id(NULL), + h264_parser(NULL), + client_extradata(0), +#ifdef _ANDROID_ + m_enable_android_native_buffers(OMX_FALSE), + m_use_android_native_buffers(OMX_FALSE), + iDivXDrmDecrypt(NULL), +#endif + m_desc_buffer_ptr(NULL), + secure_mode(false), + client_set_fps(false) +{ + /* Assumption is that , to begin with , we have all the frames with decoder */ + DEBUG_PRINT_HIGH("In OMX vdec Constructor"); +#ifdef _ANDROID_ + char property_value[PROPERTY_VALUE_MAX] = {0}; + property_get("vidc.dec.debug.perf", property_value, "0"); + perf_flag = atoi(property_value); + if (perf_flag) + { + DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); + dec_time.start(); + proc_frms = latency = 0; + } + prev_n_filled_len = 0; + property_value[0] = '\0'; + property_get("vidc.dec.debug.ts", property_value, "0"); + m_debug_timestamp = atoi(property_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); + if (m_debug_timestamp) + { + time_stamp_dts.set_timestamp_reorder_mode(true); + time_stamp_dts.enable_debug_print(true); + } + + property_value[0] = '\0'; + property_get("vidc.dec.debug.concealedmb", property_value, "0"); + m_debug_concealedmb = atoi(property_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); + +#endif + memset(&m_cmp,0,sizeof(m_cmp)); + memset(&m_cb,0,sizeof(m_cb)); + memset (&drv_ctx,0,sizeof(drv_ctx)); + memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); + memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + msg_thread_id = 0; + async_thread_id = 0; + msg_thread_created = false; + async_thread_created = false; +#ifdef _ANDROID_ICS_ + memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); +#endif + memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); + drv_ctx.timestamp_adjust = false; + drv_ctx.video_driver_fd = -1; + m_vendor_config.pData = NULL; + pthread_mutex_init(&m_lock, NULL); + pthread_mutex_init(&c_lock, NULL); + sem_init(&m_cmd_lock,0,0); + streaming[CAPTURE_PORT] = + streaming[OUTPUT_PORT] = false; +#ifdef _ANDROID_ + char extradata_value[PROPERTY_VALUE_MAX] = {0}; + property_get("vidc.dec.debug.extradata", extradata_value, "0"); + m_debug_extradata = atoi(extradata_value); + DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); +#endif + m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; + client_buffers.set_vdec_client(this); +} + +static const int event_type[] = { + V4L2_EVENT_MSM_VIDC_FLUSH_DONE, + V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, + V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, + V4L2_EVENT_MSM_VIDC_CLOSE_DONE, + V4L2_EVENT_MSM_VIDC_SYS_ERROR +}; + +static OMX_ERRORTYPE subscribe_to_events(int fd) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_event_subscription sub; + int array_sz = sizeof(event_type)/sizeof(int); + int i,rc; + if (fd < 0) { + printf("Invalid input: %d\n", fd); + return OMX_ErrorBadParameter; + } + + for (i = 0; i < array_sz; ++i) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + if (rc) { + printf("Failed to subscribe event: 0x%x\n", sub.type); + break; + } + } + if (i < array_sz) { + for (--i; i >=0 ; i--) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); + if (rc) + printf("Failed to unsubscribe event: 0x%x\n", sub.type); + } + eRet = OMX_ErrorNotImplemented; + } + return eRet; +} + + +static OMX_ERRORTYPE unsubscribe_to_events(int fd) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_event_subscription sub; + int array_sz = sizeof(event_type)/sizeof(int); + int i,rc; + if (fd < 0) { + printf("Invalid input: %d\n", fd); + return OMX_ErrorBadParameter; + } + + for (i = 0; i < array_sz; ++i) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); + if (rc) { + printf("Failed to unsubscribe event: 0x%x\n", sub.type); + break; + } + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::~omx_vdec + +DESCRIPTION + Destructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_vdec::~omx_vdec() +{ + m_pmem_info = NULL; + struct v4l2_decoder_cmd dec; + DEBUG_PRINT_HIGH("In OMX vdec Destructor"); + if(m_pipe_in) close(m_pipe_in); + if(m_pipe_out) close(m_pipe_out); + m_pipe_in = -1; + m_pipe_out = -1; + DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); + if (msg_thread_created) + pthread_join(msg_thread_id,NULL); + DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); + dec.cmd = V4L2_DEC_CMD_STOP; + if (drv_ctx.video_driver_fd >=0 ) { + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) + DEBUG_PRINT_ERROR("\n STOP Command failed\n"); + } + if (async_thread_created) + pthread_join(async_thread_id,NULL); + unsubscribe_to_events(drv_ctx.video_driver_fd); + close(drv_ctx.video_driver_fd); + pthread_mutex_destroy(&m_lock); + pthread_mutex_destroy(&c_lock); + sem_destroy(&m_cmd_lock); + if (perf_flag) + { + DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); + dec_time.end(); + } + DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); +} + +int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) { + struct v4l2_requestbuffers bufreq; + int rc = 0; + if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 0; + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); + } + return rc; +} + +/* ====================================================================== +FUNCTION + omx_vdec::OMXCntrlProcessMsgCb + +DESCRIPTION + IL Client callbacks are generated through this routine. The decoder + provides the thread context for this routine. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +void omx_vdec::process_event_cb(void *ctxt, unsigned char id) +{ + signed p1; // Parameter - 1 + signed p2; // Parameter - 2 + unsigned ident; + unsigned qsize=0; // qsize + omx_vdec *pThis = (omx_vdec *) ctxt; + + if(!pThis) + { + DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n", + __func__); + return; + } + + // Protect the shared queue data structure + do + { + /*Read the message id's from the queue*/ + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if(qsize) + { + pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); + } + + if (qsize == 0 && pThis->m_state != OMX_StatePause) + { + qsize = pThis->m_ftb_q.m_size; + if (qsize) + { + pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); + } + } + + if (qsize == 0 && pThis->m_state != OMX_StatePause) + { + qsize = pThis->m_etb_q.m_size; + if (qsize) + { + pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); + } + } + pthread_mutex_unlock(&pThis->m_lock); + + /*process message if we have one*/ + if(qsize > 0) + { + id = ident; + switch (id) + { + case OMX_COMPONENT_GENERATE_EVENT: + if (pThis->m_cb.EventHandler) + { + switch (p1) + { + case OMX_CommandStateSet: + pThis->m_state = (OMX_STATETYPE) p2; + DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d", + pThis->m_state); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL); + break; + + case OMX_EventError: + if(p2 == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); + pThis->m_state = (OMX_STATETYPE) p2; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError, OMX_ErrorInvalidState, p2, NULL); + } + else if (p2 == OMX_ErrorHardware) + { + pThis->omx_report_error(); + } + else + { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError, p2, (OMX_U32)NULL, NULL ); + } + break; + + case OMX_CommandPortDisable: + DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2); + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) + { + BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); + break; + } + if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) + { + OMX_ERRORTYPE eRet = OMX_ErrorNone; + pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); + if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) + DEBUG_PRINT_HIGH("Failed to release output buffers\n"); + OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); + pThis->in_reconfig = false; + if(eRet != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); + pThis->omx_report_error(); + break; + } + } + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + case OMX_CommandPortEnable: + DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + default: + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__); + } + break; + case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: + if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); + pThis->omx_report_error (); + } + break; + case OMX_COMPONENT_GENERATE_ETB: + if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FTB: + if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_COMMAND: + pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ + (OMX_U32)p2,(OMX_PTR)NULL); + break; + + case OMX_COMPONENT_GENERATE_EBD: + + if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); + pThis->omx_report_error (); + } + else + { + if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) + { + pThis->m_inp_err_count++; + pThis->time_stamp_dts.remove_time_stamp( + ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, + (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + } + else + { + pThis->m_inp_err_count = 0; + } + if ( pThis->empty_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); + pThis->omx_report_error (); + } + if(pThis->m_inp_err_count >= MAX_INPUT_ERROR) + { + DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); + pThis->omx_report_error (); + } + } + break; + case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: + { + int64_t *timestamp = (int64_t *)p1; + if (p1) + { + pThis->time_stamp_dts.remove_time_stamp(*timestamp, + (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + ?true:false); + free(timestamp); + } + } + break; + case OMX_COMPONENT_GENERATE_FBD: + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); + pThis->omx_report_error (); + } + else if ( pThis->fill_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: + DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete"); + if (!pThis->input_flush_progress) + { + DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); + } + else + { + pThis->execute_input_flush(); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); + pThis->omx_report_error (); + } + else + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_INPUT_FLUSH_PENDING)) + { + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); + DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client"); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + OMX_CORE_INPUT_PORT_INDEX,NULL ); + } + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_IDLE_PENDING)) + { + if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { + DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n"); + pThis->omx_report_error (); + } else { + pThis->streaming[OUTPUT_PORT] = false; + } + if (!pThis->output_flush_progress) + { + DEBUG_PRINT_LOW("\n Input flush done hence issue stop"); + pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + } + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: + DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete"); + if (!pThis->output_flush_progress) + { + DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); + } + else + { + pThis->execute_output_flush(); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); + pThis->omx_report_error (); + } + else + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) + { + DEBUG_PRINT_LOW("\n Notify Output Flush done"); + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + OMX_CORE_OUTPUT_PORT_INDEX,NULL ); + } + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) + { + DEBUG_PRINT_LOW("\n Internal flush complete"); + BITMASK_CLEAR (&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); + if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) + { + pThis->post_event(OMX_CommandPortDisable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + BITMASK_CLEAR (&pThis->m_flags, + OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); + + } + } + + if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) + { + if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { + DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n"); + pThis->omx_report_error (); + break; + } + pThis->streaming[CAPTURE_PORT] = false; + if (!pThis->input_flush_progress) + { + DEBUG_PRINT_LOW("\n Output flush done hence issue stop"); + pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + } + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_START_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE"); + + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); + pThis->omx_report_error (); + } + else + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("\n Move to executing"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting, NULL); + } + else if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_PAUSE_PENDING)) + { + if (/*ioctl (pThis->drv_ctx.video_driver_fd, + VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); + pThis->omx_report_error (); + } + } + } + } + else + { + DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); + } + break; + + case OMX_COMPONENT_GENERATE_PAUSE_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); + pThis->omx_report_error (); + } + else + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); + //Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); + pThis->m_state = OMX_StatePause; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StatePause, NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_RESUME_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); + pThis->omx_report_error (); + } + else + { + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("\n Moving the decoder to execute state"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting,NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_STOP_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); + if (pThis->m_cb.EventHandler) + { + if (p2 != VDEC_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); + pThis->omx_report_error (); + } + else + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); + pThis->m_state = OMX_StateIdle; + DEBUG_PRINT_LOW("\n Move to Idle State"); + pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateIdle,NULL); + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + break; + + case OMX_COMPONENT_GENERATE_PORT_RECONFIG: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); + + if (p2 == OMX_IndexParamPortDefinition) { + pThis->in_reconfig = true; + } + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventPortSettingsChanged, p1, p2, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + + if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) + { + OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; + OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; + if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) + format = OMX_InterlaceInterleaveFrameTopFieldFirst; + else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) + format = OMX_InterlaceInterleaveFrameBottomFieldFirst; + else //unsupported interlace format; raise a error + event = OMX_EventError; + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + event, format, 0, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + break; + + case OMX_COMPONENT_GENERATE_EOS_DONE: + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, + OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + pThis->prev_ts = LLONG_MAX; + pThis->rst_prev_ts = true; + break; + + case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); + pThis->omx_report_error (); + break; + + case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING: + DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n"); + pThis->omx_report_unsupported_setting(); + break; + + case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: + { + DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); + if (pThis->m_cb.EventHandler) { + pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, + (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); + } else { + DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); + } + } + default: + break; + } + } + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if (pThis->m_state != OMX_StatePause) + qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); + pthread_mutex_unlock(&pThis->m_lock); + } + while(qsize>0); + +} + +int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines) +{ + int format_changed = 0; + if ((height != drv_ctx.video_resolution.frame_height) || + (width != drv_ctx.video_resolution.frame_width)) { + DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n", + width, drv_ctx.video_resolution.frame_width, + height,drv_ctx.video_resolution.frame_height); + format_changed = 1; + } + drv_ctx.video_resolution.frame_height = height; + drv_ctx.video_resolution.frame_width = width; + drv_ctx.video_resolution.scan_lines = scan_lines; + drv_ctx.video_resolution.stride = stride; + rectangle.nLeft = 0; + rectangle.nTop = 0; + rectangle.nWidth = drv_ctx.video_resolution.frame_width; + rectangle.nHeight = drv_ctx.video_resolution.frame_height; + return format_changed; +} + +OMX_ERRORTYPE omx_vdec::is_video_session_supported() +{ +#ifdef H264_PROFILE_LEVEL_CHECK + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", + OMX_MAX_STRINGNAME_SIZE) && + m_profile_lvl.eProfile == OMX_VIDEO_AVCProfileHigh) { + if (m_profile_lvl.eLevel > OMX_VIDEO_AVCLevel3) { + DEBUG_PRINT_ERROR("Unsupported level for H264 High profile"); + return OMX_ErrorUnsupportedSetting; + } + m_decoder_capability.max_width = 864; + m_decoder_capability.max_height = 480; + DEBUG_PRINT_LOW(" set max_width x max_height to 864x480 for H264 high profile"); + } +#endif + + if ((drv_ctx.video_resolution.frame_width * + drv_ctx.video_resolution.frame_height > + m_decoder_capability.max_width * + m_decoder_capability.max_height) || + (drv_ctx.video_resolution.frame_width* + drv_ctx.video_resolution.frame_height < + m_decoder_capability.min_width * + m_decoder_capability.min_height)) + { + DEBUG_PRINT_ERROR( + "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)", + drv_ctx.video_resolution.frame_width, + drv_ctx.video_resolution.frame_height, + m_decoder_capability.min_width, + m_decoder_capability.min_height, + m_decoder_capability.max_width, + m_decoder_capability.max_height); + return OMX_ErrorUnsupportedSetting; + } + DEBUG_PRINT_HIGH("\n video session supported\n"); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentInit + +DESCRIPTION + Initialize the component. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_fmtdesc fdesc; + struct v4l2_format fmt; + struct v4l2_requestbuffers bufreq; + struct v4l2_control control; + struct v4l2_frmsizeenum frmsize; + unsigned int alignment = 0,buffer_size = 0; + int fds[2]; + int r,ret=0; + bool codec_ambiguous = false; + OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec"; + +#ifdef _ANDROID_ + char platform_name[64]; + property_get("ro.board.platform", platform_name, "0"); + if (!strncmp(platform_name, "msm8610", 7)) { + device_name = (OMX_STRING)"/dev/video/q6_dec"; + } +#endif + + if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){ + struct v4l2_control control; + secure_mode = true; + arbitrary_bytes = false; + role = (OMX_STRING)"OMX.qcom.video.decoder.avc"; + } + + drv_ctx.video_driver_fd = open(device_name, O_RDWR); + + DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d", + drv_ctx.video_driver_fd, errno); + + if(drv_ctx.video_driver_fd == 0){ + DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n"); + drv_ctx.video_driver_fd = open(device_name, O_RDWR); + close(0); + } + + if(drv_ctx.video_driver_fd < 0) + { + DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno); + return OMX_ErrorInsufficientResources; + } + drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; + drv_ctx.frame_rate.fps_denominator = 1; + + ret = subscribe_to_events(drv_ctx.video_driver_fd); + if (!ret) { + async_thread_created = true; + ret = pthread_create(&async_thread_id,0,async_message_thread,this); + } + if(ret) { + DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n"); + async_thread_created = false; + return OMX_ErrorInsufficientResources; + } + +#ifdef INPUT_BUFFER_LOG + strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); +#endif +#ifdef OUTPUT_BUFFER_LOG + outputBufferFile1 = fopen (outputfilename, "ab"); +#endif +#ifdef OUTPUT_EXTRADATA_LOG + outputExtradataFile = fopen (ouputextradatafilename, "ab"); +#endif + + // Copy the role information which provides the decoder kind + strlcpy(drv_ctx.kind,role,128); + + if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE); + drv_ctx.timestamp_adjust = true; + drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; + eCompressionFormat = OMX_VIDEO_CodingMPEG4; + output_capability=V4L2_PIX_FMT_MPEG4; + /*Initialize Start Code for MPEG4*/ + codec_type_parse = CODEC_TYPE_MPEG4; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "m4v"); +#endif + } + else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ + OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; + output_capability = V4L2_PIX_FMT_MPEG2; + eCompressionFormat = OMX_VIDEO_CodingMPEG2; + /*Initialize Start Code for MPEG2*/ + codec_type_parse = CODEC_TYPE_MPEG2; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "mpg"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("\n H263 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_H263; + eCompressionFormat = OMX_VIDEO_CodingH263; + output_capability = V4L2_PIX_FMT_H263; + codec_type_parse = CODEC_TYPE_H263; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "263"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; + output_capability = V4L2_PIX_FMT_DIVX_311; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + m_frame_parser.init_start_codes (codec_type_parse); + + eRet = createDivxDrmContext(); + if (eRet != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + return eRet; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; + output_capability = V4L2_PIX_FMT_DIVX; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + codec_ambiguous = true; + m_frame_parser.init_start_codes (codec_type_parse); + + eRet = createDivxDrmContext(); + if (eRet != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + return eRet; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected"); + drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; + output_capability = V4L2_PIX_FMT_DIVX; + eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + codec_type_parse = CODEC_TYPE_DIVX; + codec_ambiguous = true; + m_frame_parser.init_start_codes (codec_type_parse); + + eRet = createDivxDrmContext(); + if (eRet != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); + return eRet; + } + + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_H264; + output_capability=V4L2_PIX_FMT_H264; + eCompressionFormat = OMX_VIDEO_CodingAVC; + codec_type_parse = CODEC_TYPE_H264; + m_frame_parser.init_start_codes (codec_type_parse); + m_frame_parser.init_nal_length(nal_length); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "264"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; + eCompressionFormat = OMX_VIDEO_CodingWMV; + codec_type_parse = CODEC_TYPE_VC1; + output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "vc1"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; + eCompressionFormat = OMX_VIDEO_CodingWMV; + codec_type_parse = CODEC_TYPE_VC1; + output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; + m_frame_parser.init_start_codes (codec_type_parse); +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "vc1"); +#endif + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); + output_capability=V4L2_PIX_FMT_VP8; + eCompressionFormat = OMX_VIDEO_CodingVPX; + codec_type_parse = CODEC_TYPE_VP8; + arbitrary_bytes = false; +#ifdef INPUT_BUFFER_LOG + strcat(inputfilename, "ivf"); +#endif + + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } +#ifdef INPUT_BUFFER_LOG + inputBufferFile1 = fopen (inputfilename, "ab"); + if (output_capability == V4L2_PIX_FMT_VP8) { + struct ivf_file_header + { + OMX_U8 signature[4]; //='DKIF'; + OMX_U8 version ; //= 0; + OMX_U8 headersize ; //= 32; + OMX_U32 FourCC; + OMX_U8 width; + OMX_U8 height; + OMX_U32 rate; + OMX_U32 scale; + OMX_U32 length; + OMX_U8 unused[4]; + } file_header; + memset((void *)&file_header,0,sizeof(file_header)); + file_header.signature[0] = 'D'; + file_header.signature[1] = 'K'; + file_header.signature[2] = 'I'; + file_header.signature[3] = 'F'; + file_header.version = 0; + file_header.headersize = 32; + file_header.FourCC = 0x30385056; + if (inputBufferFile1) + { + fwrite((const char *)&file_header, + sizeof(file_header),1,inputBufferFile1); + } + } +#endif + if (eRet == OMX_ErrorNone) + { + + drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; + OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + if (!client_buffers.set_color_format(dest_color_format)) { + DEBUG_PRINT_ERROR("\n Setting color format failed"); + eRet = OMX_ErrorInsufficientResources; + } + + capture_capability= V4L2_PIX_FMT_NV12; + + struct v4l2_capability cap; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap); + if (ret) { + DEBUG_PRINT_ERROR("Failed to query capabilities\n"); + /*TODO: How to handle this case */ + } else { + DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s," + " version = %d, capabilities = %x\n", cap.driver, cap.card, + cap.bus_info, cap.version, cap.capabilities); + } + ret=0; + fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fdesc.index=0; + while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { + DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, + fdesc.pixelformat, fdesc.flags); + fdesc.index++; + } + fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fdesc.index=0; + while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { + + DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, + fdesc.pixelformat, fdesc.flags); + fdesc.index++; + } + update_resolution(320, 240, 320, 240); + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = output_capability; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to set format on output port\n"); + return OMX_ErrorInsufficientResources; + } + DEBUG_PRINT_HIGH("\n Set Format was successful \n "); + if (codec_ambiguous) { + if (output_capability == V4L2_PIX_FMT_DIVX) { + struct v4l2_control divx_ctrl; + + if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { + divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; + } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { + divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; + } else { + divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; + } + + divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); + if (ret) { + DEBUG_PRINT_ERROR("Failed to set divx version\n"); + } + } else { + DEBUG_PRINT_ERROR("Codec should not be ambiguous"); + } + } + + //Get the hardware capabilities + memset((void *)&frmsize,0,sizeof(frmsize)); + frmsize.index = 0; + frmsize.pixel_format = output_capability; + ret = ioctl(drv_ctx.video_driver_fd, + VIDIOC_ENUM_FRAMESIZES, &frmsize); + if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { + DEBUG_PRINT_ERROR("Failed to get framesizes\n"); + return OMX_ErrorHardware; + } + + if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { + m_decoder_capability.min_width = frmsize.stepwise.min_width; + m_decoder_capability.max_width = frmsize.stepwise.max_width; + m_decoder_capability.min_height = frmsize.stepwise.min_height; + m_decoder_capability.max_height = frmsize.stepwise.max_height; + } + + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = capture_capability; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to set format on capture port\n"); + } + DEBUG_PRINT_HIGH("\n Set Format was successful \n "); + if(secure_mode){ + control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; + control.value = 1; + DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret); + ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); + if (ret) { + DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret); + return OMX_ErrorInsufficientResources; + } + } + + /*Get the Buffer requirements for input and output ports*/ + drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; + drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + if (secure_mode) { + drv_ctx.op_buf.alignment=SZ_1M; + drv_ctx.ip_buf.alignment=SZ_1M; + } else { + drv_ctx.op_buf.alignment=SZ_4K; + drv_ctx.ip_buf.alignment=SZ_4K; + } + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; + drv_ctx.extradata = 0; + drv_ctx.picture_order = VDEC_ORDER_DISPLAY; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; + control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + drv_ctx.idr_only_decoding = 0; + + m_state = OMX_StateLoaded; +#ifdef DEFAULT_EXTRADATA + if (eRet == OMX_ErrorNone && !secure_mode) + enable_extradata(DEFAULT_EXTRADATA, true, true); +#endif + eRet=get_buffer_req(&drv_ctx.ip_buf); + DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size); + get_buffer_req(&drv_ctx.op_buf); + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + if (m_frame_parser.mutils == NULL) + { + m_frame_parser.mutils = new H264_Utils(); + + if (m_frame_parser.mutils == NULL) + { + DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); + eRet = OMX_ErrorInsufficientResources; + } + else + { + h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; + h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); + h264_scratch.nFilledLen = 0; + h264_scratch.nOffset = 0; + + if (h264_scratch.pBuffer == NULL) + { + DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); + return OMX_ErrorInsufficientResources; + } + m_frame_parser.mutils->initialize_frame_checking_environment(); + m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); + } + } + + h264_parser = new h264_stream_parser(); + if (!h264_parser) + { + DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); + eRet = OMX_ErrorInsufficientResources; + } + } + + if(pipe(fds)) + { + DEBUG_PRINT_ERROR("pipe creation failed\n"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + int temp1[2]; + if(fds[0] == 0 || fds[1] == 0) + { + if (pipe (temp1)) + { + DEBUG_PRINT_ERROR("pipe creation failed\n"); + return OMX_ErrorInsufficientResources; + } + //close (fds[0]); + //close (fds[1]); + fds[0] = temp1 [0]; + fds[1] = temp1 [1]; + } + m_pipe_in = fds[0]; + m_pipe_out = fds[1]; + msg_thread_created = true; + r = pthread_create(&msg_thread_id,0,message_thread,this); + + if(r < 0) + { + DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); + msg_thread_created = false; + eRet = OMX_ErrorInsufficientResources; + } + } + } + + if (eRet != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Component Init Failed"); + } + else + { + DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success"); + } + //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetComponentVersion + +DESCRIPTION + Returns the component version. + +PARAMETERS + TBD. + +RETURN VALUE + OMX_ErrorNone. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_component_version + ( + OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STRING componentName, + OMX_OUT OMX_VERSIONTYPE* componentVersion, + OMX_OUT OMX_VERSIONTYPE* specVersion, + OMX_OUT OMX_UUIDTYPE* componentUUID + ) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n"); + return OMX_ErrorInvalidState; + } + /* TBD -- Return the proper version */ + if (specVersion) + { + specVersion->nVersion = OMX_SPEC_VERSION; + } + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_vdec::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX + && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) + { + DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush " + "to invalid port: %lu", param1); + return OMX_ErrorBadPortIndex; + } + post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); + sem_wait(&m_cmd_lock); + DEBUG_PRINT_LOW("\n send_command: Command Processed\n"); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_STATETYPE eState = (OMX_STATETYPE) param1; + int bFlag = 1,sem_posted = 0,ret=0; + + DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd); + DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d", + m_state, eState); + + if(cmd == OMX_CommandStateSet) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued"); + DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState); + /***************************/ + /* Current State is Loaded */ + /***************************/ + if(m_state == OMX_StateLoaded) + { + if(eState == OMX_StateIdle) + { + //if all buffers are allocated or all ports disabled + if(allocate_done() || + (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) + { + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n"); + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Loaded to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Loaded to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n"); + } + /* Requesting transition from Loaded to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ + eState); + eRet = OMX_ErrorBadParameter; + } + } + + /***************************/ + /* Current State is IDLE */ + /***************************/ + else if(m_state == OMX_StateIdle) + { + if(eState == OMX_StateLoaded) + { + if(release_done()) + { + /* + Since error is None , we will post an event at the end + of this function definition + */ + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n"); + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Idle to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); + //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); + bFlag = 1; + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); + m_state=OMX_StateExecuting; + DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n"); + } + /* Requesting transition from Idle to Idle */ + else if(eState == OMX_StateIdle) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Idle to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Idle to Pause */ + else if(eState == OMX_StatePause) + { + /*To pause the Video core we need to start the driver*/ + if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, + NULL) < */0) + { + DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n"); + bFlag = 0; + } + } + /* Requesting transition from Idle to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + + /******************************/ + /* Current State is Executing */ + /******************************/ + else if(m_state == OMX_StateExecuting) + { + DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting"); + /* Requesting transition from Executing to Idle */ + if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition + */ + DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n"); + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + execute_omx_flush(OMX_ALL); + } + bFlag = 0; + } + /* Requesting transition from Executing to Paused */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_LOW("\n PAUSE Command Issued"); + m_state = OMX_StatePause; + bFlag = 1; + } + /* Requesting transition from Executing to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Executing to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is Pause */ + /***************************/ + else if(m_state == OMX_StatePause) + { + /* Requesting transition from Pause to Executing */ + if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_LOW("\n Pause --> Executing \n"); + m_state = OMX_StateExecuting; + bFlag = 1; + } + /* Requesting transition from Pause to Idle */ + else if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("\n Pause --> Idle \n"); + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + execute_omx_flush(OMX_ALL); + } + bFlag = 0; + } + /* Requesting transition from Pause to loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Pause to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is WaitForResources */ + /***************************/ + else if(m_state == OMX_StateWaitForResources) + { + /* Requesting transition from WaitForResources to Loaded */ + if(eState == OMX_StateLoaded) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n"); + } + /* Requesting transition from WaitForResources to WaitForResources */ + else if (eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorSameState, + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from WaitForResources to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + /* Requesting transition from WaitForResources to Loaded - + is NOT tested by Khronos TS */ + + } + else + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); + eRet = OMX_ErrorBadParameter; + } + } + /********************************/ + /* Current State is Invalid */ + /*******************************/ + else if(m_state == OMX_StateInvalid) + { + /* State Transition from Inavlid to any state */ + if(eState == (OMX_StateLoaded || OMX_StateWaitForResources + || OMX_StateIdle || OMX_StateExecuting + || OMX_StatePause || OMX_StateInvalid)) + { + DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); + post_event(OMX_EventError,OMX_ErrorInvalidState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + } + else if (cmd == OMX_CommandFlush) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued" + "with param1: %lu", param1); + if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); + } + if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) + { + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + } + if (!sem_posted){ + sem_posted = 1; + DEBUG_PRINT_LOW("\n Set the Semaphore"); + sem_post (&m_cmd_lock); + execute_omx_flush(param1); + } + bFlag = 0; + } + else if ( cmd == OMX_CommandPortEnable) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued" + "with param1: %lu", param1); + if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_inp_bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || allocate_input_done()) + { + post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) + { + DEBUG_PRINT_LOW("\n Enable output Port command recieved"); + m_out_bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || (allocate_output_done())) + { + post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + + } + else + { + DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + } + else if (cmd == OMX_CommandPortDisable) + { + DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued" + "with param1: %lu", param1); + if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_inp_bEnabled = OMX_FALSE; + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_input_done()) + { + post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + if(!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + } + execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); + } + + // Skip the event notification + bFlag = 0; + } + } + if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) + { + m_out_bEnabled = OMX_FALSE; + DEBUG_PRINT_LOW("\n Disable output Port command recieved"); + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_output_done()) + { + post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + if (!sem_posted) + { + sem_posted = 1; + sem_post (&m_cmd_lock); + } + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); + execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); + } + // Skip the event notification + bFlag = 0; + + } + } + } + else + { + DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); + eRet = OMX_ErrorNotImplemented; + } + if(eRet == OMX_ErrorNone && bFlag) + { + post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); + } + if(!sem_posted) + { + sem_post(&m_cmd_lock); + } + + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ExecuteOmxFlush + +DESCRIPTION + Executes the OMX flush. + +PARAMETERS + flushtype - input flush(1)/output flush(0)/ both. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_vdec::execute_omx_flush(OMX_U32 flushType) +{ + bool bRet = false; + struct v4l2_plane plane; + struct v4l2_buffer v4l2_buf; + struct v4l2_decoder_cmd dec; + DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType); + memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); + dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; + + DEBUG_PRINT_ERROR("in %s: reconfig? %d", __func__, in_reconfig); + + if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) + { + output_flush_progress = true; + dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; + } + else + { + /* XXX: The driver/hardware does not support flushing of individual ports + * in all states. So we pretty much need to flush both ports internally, + * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it + * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, + * we automatically omit sending the FLUSH done for the "opposite" port. */ + input_flush_progress = true; + output_flush_progress = true; + dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; + } + + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) + { + DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType); + bRet = false; + } + + return bRet; +} +/*========================================================================= +FUNCTION : execute_output_flush + +DESCRIPTION + Executes the OMX flush at OUTPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_vdec::execute_output_flush() +{ + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate FBD for all Buffers in the FTBq*/ + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_LOW("\n Initiate Output Flush"); + while (m_ftb_q.m_size) + { + DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d", + m_ftb_q.m_size,pending_output_buffers); + m_ftb_q.pop_entry(&p1,&p2,&ident); + DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2); + if(ident == m_fill_output_msg ) + { + m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + else if (ident == OMX_COMPONENT_GENERATE_FBD) + { + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + pthread_mutex_unlock(&m_lock); + output_flush_progress = false; + + if (arbitrary_bytes) + { + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } + DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); + return bRet; +} +/*========================================================================= +FUNCTION : execute_input_flush + +DESCRIPTION + Executes the OMX flush at INPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_vdec::execute_input_flush() +{ + unsigned i =0; + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate EBD for all Buffers in the ETBq*/ + DEBUG_PRINT_LOW("\n Initiate Input Flush \n"); + + pthread_mutex_lock(&m_lock); + DEBUG_PRINT_LOW("\n Check if the Queue is empty \n"); + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + + if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) + { + DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_ETB) + { + pending_input_buffers++; + DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", + (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if (ident == OMX_COMPONENT_GENERATE_EBD) + { + DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", + (OMX_BUFFERHEADERTYPE *)p1); + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + time_stamp_dts.flush_timestamp(); + /*Check if Heap Buffers are to be flushed*/ + if (arbitrary_bytes && !(codec_config_flag)) + { + DEBUG_PRINT_LOW("\n Reset all the variables before flusing"); + h264_scratch.nFilledLen = 0; + nal_count = 0; + look_ahead_nal = false; + frame_count = 0; + h264_last_au_ts = LLONG_MAX; + h264_last_au_flags = 0; + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + DEBUG_PRINT_LOW("\n Initialize parser"); + if (m_frame_parser.mutils) + { + m_frame_parser.mutils->initialize_frame_checking_environment(); + } + + while (m_input_pending_q.m_size) + { + m_input_pending_q.pop_entry(&p1,&p2,&ident); + m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); + } + + if (psource_frame) + { + m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); + psource_frame = NULL; + } + + if (pdest_frame) + { + pdest_frame->nFilledLen = 0; + m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL, + (unsigned int)NULL); + pdest_frame = NULL; + } + m_frame_parser.flush(); + } + else if (codec_config_flag) + { + DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " + "is not sent to the driver yet"); + } + pthread_mutex_unlock(&m_lock); + input_flush_progress = false; + if (!arbitrary_bytes) + { + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } +#ifdef _ANDROID_ + if (m_debug_timestamp) + { + m_timestamp_list.reset_ts_list(); + } +#endif + DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); + return bRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::SendCommandEvent + +DESCRIPTION + Send the event to decoder pipe. This is needed to generate the callbacks + in decoder thread context. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_vdec::post_event(unsigned int p1, + unsigned int p2, + unsigned int id) +{ + bool bRet = false; + + + pthread_mutex_lock(&m_lock); + + if (id == m_fill_output_msg || + id == OMX_COMPONENT_GENERATE_FBD) + { + m_ftb_q.insert_entry(p1,p2,id); + } + else if (id == OMX_COMPONENT_GENERATE_ETB || + id == OMX_COMPONENT_GENERATE_EBD || + id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) + { + m_etb_q.insert_entry(p1,p2,id); + } + else + { + m_cmd_q.insert_entry(p1,p2,id); + } + + bRet = true; + DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); + post_message(this, id); + + pthread_mutex_unlock(&m_lock); + + return bRet; +} + +OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 0) { + if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + eRet = OMX_ErrorNoMore; + } + else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; + profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetParameter + +DESCRIPTION + OMX Get Parameter method implementation + +PARAMETERS + . + +RETURN VALUE + Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_INOUT OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + DEBUG_PRINT_LOW("get_parameter: \n"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_LOW("Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + switch((unsigned long)paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn = + (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); + eRet = update_portdef(portDefn); + if (eRet == OMX_ErrorNone) + m_port_def = *portDefn; + break; + } + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); + + portParamType->nVersion.nVersion = OMX_SPEC_VERSION; + portParamType->nSize = sizeof(portParamType); + portParamType->nPorts = 2; + portParamType->nStartPortNumber = 0; + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); + + portFmt->nVersion.nVersion = OMX_SPEC_VERSION; + portFmt->nSize = sizeof(portFmt); + + if (0 == portFmt->nPortIndex) + { + if (0 == portFmt->nIndex) + { + portFmt->eColorFormat = OMX_COLOR_FormatUnused; + portFmt->eCompressionFormat = eCompressionFormat; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ + " NoMore compression formats\n"); + eRet = OMX_ErrorNoMore; + } + } + else if (1 == portFmt->nPortIndex) + { + portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; + + if(0 == portFmt->nIndex) + portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + else if (1 == portFmt->nIndex) + portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ + " NoMore Color formats\n"); + eRet = OMX_ErrorNoMore; + } + ALOGE("returning %d\n", portFmt->eColorFormat); + } + else + { + DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", + (int)portFmt->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamAudioInit: + { + OMX_PORT_PARAM_TYPE *audioPortParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); + audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; + audioPortParamType->nSize = sizeof(audioPortParamType); + audioPortParamType->nPorts = 0; + audioPortParamType->nStartPortNumber = 0; + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamImageInit: + { + OMX_PORT_PARAM_TYPE *imagePortParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); + imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; + imagePortParamType->nSize = sizeof(imagePortParamType); + imagePortParamType->nPorts = 0; + imagePortParamType->nStartPortNumber = 0; + break; + + } + /*Component should support this port definition*/ + case OMX_IndexParamOtherInit: + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", + paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + break; + } + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + comp_role->nVersion.nVersion = OMX_SPEC_VERSION; + comp_role->nSize = sizeof(*comp_role); + + DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", + paramIndex); + strlcpy((char*)comp_role->cRole,(const char*)m_cRole, + OMX_MAX_STRINGNAME_SIZE); + break; + } + /* Added for parameter test */ + case OMX_IndexParamPriorityMgmt: + { + + OMX_PRIORITYMGMTTYPE *priorityMgmType = + (OMX_PRIORITYMGMTTYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); + priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; + priorityMgmType->nSize = sizeof(priorityMgmType); + + break; + } + /* Added for parameter test */ + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = + (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); + + bufferSupplierType->nSize = sizeof(bufferSupplierType); + bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; + if(0 == bufferSupplierType->nPortIndex) + bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; + else if (1 == bufferSupplierType->nPortIndex) + bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; + else + eRet = OMX_ErrorBadPortIndex; + + + break; + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoH263: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg4: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg2: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n", + paramIndex); + break; + } + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex); + OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = + (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; + eRet = get_supported_profile_level_for_1080p(profileLevelType); + break; + } +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: + { + DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n"); + GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; + if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { + + if(secure_mode) { + nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | + GRALLOC_USAGE_PRIVATE_UNCACHED); + } else { + nativeBuffersUsage->nUsage = + (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | + GRALLOC_USAGE_PRIVATE_UNCACHED); + } + } else { + DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n"); + eRet = OMX_ErrorBadParameter; + } + } + break; +#endif + + default: + { + DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + } + + } + + DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n", + drv_ctx.video_resolution.frame_width, + drv_ctx.video_resolution.frame_height, + drv_ctx.video_resolution.stride, + drv_ctx.video_resolution.scan_lines); + + return eRet; +} + +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) +OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) +{ + DEBUG_PRINT_LOW("Inside use_android_native_buffer"); + OMX_ERRORTYPE eRet = OMX_ErrorNone; + UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; + + if((params == NULL) || + (params->nativeBuffer == NULL) || + (params->nativeBuffer->handle == NULL) || + !m_enable_android_native_buffers) + return OMX_ErrorBadParameter; + m_use_android_native_buffers = OMX_TRUE; + sp nBuf = params->nativeBuffer; + private_handle_t *handle = (private_handle_t *)nBuf->handle; + if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port + OMX_U8 *buffer = NULL; + if(!secure_mode) { + buffer = (OMX_U8*)mmap(0, handle->size, + PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); + if(buffer == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); + return OMX_ErrorInsufficientResources; + } + } + eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); + } else { + eRet = OMX_ErrorBadParameter; + } + return eRet; +} +#endif +/* ====================================================================== +FUNCTION + omx_vdec::Setparameter + +DESCRIPTION + OMX Set Parameter method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_IN OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + int ret=0; + struct v4l2_format fmt; + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + if((m_state != OMX_StateLoaded) && + BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && + (m_out_bEnabled == OMX_TRUE) && + BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && + (m_inp_bEnabled == OMX_TRUE)) { + DEBUG_PRINT_ERROR("Set Param in Invalid State \n"); + return OMX_ErrorIncorrectStateOperation; + } + switch((unsigned long)paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has + //been called. + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", + (int)portDefn->format.video.nFrameHeight, + (int)portDefn->format.video.nFrameWidth); + if(OMX_DirOutput == portDefn->eDir) + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n"); + m_display_id = portDefn->format.video.pNativeWindow; + unsigned int buffer_size; + if (!client_buffers.get_buffer_req(buffer_size)) { + DEBUG_PRINT_ERROR("\n Error in getting buffer requirements"); + eRet = OMX_ErrorBadParameter; + } else { + if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && + portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) + { + drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; + drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; + drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount; + drv_ctx.extradata_info.size = drv_ctx.extradata_info.count * + drv_ctx.extradata_info.buffer_size; + eRet = set_buffer_req(&drv_ctx.op_buf); + if (eRet == OMX_ErrorNone) + m_port_def = *portDefn; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n", + drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, + portDefn->nBufferCountActual, portDefn->nBufferSize); + eRet = OMX_ErrorBadParameter; + } + } + } + else if(OMX_DirInput == portDefn->eDir) + { + if((portDefn->format.video.xFramerate >> 16) > 0 && + (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) + { + // Frame rate only should be set if this is a "known value" or to + // activate ts prediction logic (arbitrary mode only) sending input + // timestamps with max value (LLONG_MAX). + DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu", + portDefn->format.video.xFramerate >> 16); + Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, + drv_ctx.frame_rate.fps_denominator); + if(!drv_ctx.frame_rate.fps_numerator) + { + DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); + drv_ctx.frame_rate.fps_numerator = 30; + } + if(drv_ctx.frame_rate.fps_denominator) + drv_ctx.frame_rate.fps_numerator = (int) + drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; + drv_ctx.frame_rate.fps_denominator = 1; + frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / + drv_ctx.frame_rate.fps_numerator; + DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)", + frm_int, drv_ctx.frame_rate.fps_numerator / + (float)drv_ctx.frame_rate.fps_denominator); + } + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n"); + if(drv_ctx.video_resolution.frame_height != + portDefn->format.video.nFrameHeight || + drv_ctx.video_resolution.frame_width != + portDefn->format.video.nFrameWidth) + { + DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n", + portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight); + if (portDefn->format.video.nFrameHeight != 0x0 && + portDefn->format.video.nFrameWidth != 0x0) + { + update_resolution(portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight, + portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight); + eRet = is_video_session_supported(); + if (eRet) + break; + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = output_capability; + DEBUG_PRINT_LOW("\n fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d \n",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) + { + DEBUG_PRINT_ERROR("\n Set Resolution failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + else + eRet = get_buffer_req(&drv_ctx.op_buf); + } + } + else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount + || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) + { + vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; + drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; + drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & + (~(buffer_prop->alignment - 1)); + eRet = set_buffer_req(buffer_prop); + } + else + { + DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n", + drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, + portDefn->nBufferCountActual, portDefn->nBufferSize); + eRet = OMX_ErrorBadParameter; + } + } + else if (portDefn->eDir == OMX_DirMax) + { + DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + } + break; + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + int ret=0; + struct v4l2_format fmt; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", + portFmt->eColorFormat); + + if(1 == portFmt->nPortIndex) + { + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + fmt.fmt.pix_mp.pixelformat = capture_capability; + enum vdec_output_fromat op_format; + if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) || + (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar)) + op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; + else if(portFmt->eColorFormat == + (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) + op_format = VDEC_YUV_FORMAT_TILE_4x2; + else + eRet = OMX_ErrorBadParameter; + + if(eRet == OMX_ErrorNone) + { + drv_ctx.output_format = op_format; + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if(ret) + { + DEBUG_PRINT_ERROR("\n Set output format failed"); + eRet = OMX_ErrorUnsupportedSetting; + /*TODO: How to handle this case */ + } + else + { + eRet = get_buffer_req(&drv_ctx.op_buf); + } + } + if (eRet == OMX_ErrorNone){ + if (!client_buffers.set_color_format(portFmt->eColorFormat)) { + DEBUG_PRINT_ERROR("\n Set color format failed"); + eRet = OMX_ErrorBadParameter; + } + } + } + } + break; + + case OMX_QcomIndexPortDefn: + { + OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = + (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n", + portFmt->nFramePackingFormat); + + /* Input port */ + if (portFmt->nPortIndex == 0) + { + if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) + { + if(secure_mode) { + arbitrary_bytes = false; + DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); + eRet = OMX_ErrorUnsupportedSetting; + } else { + arbitrary_bytes = true; + } + } + else if (portFmt->nFramePackingFormat == + OMX_QCOM_FramePacking_OnlyOneCompleteFrame) + { + arbitrary_bytes = false; + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n", + portFmt->nFramePackingFormat); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n"); + if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && + portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && + portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) + { + m_out_mem_region_smi = OMX_TRUE; + if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n"); + m_use_output_pmem = OMX_TRUE; + } + } + } + } + break; + + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", + comp_role->cRole); + + if((m_state == OMX_StateLoaded)&& + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("Set Parameter called in valid state"); + } + else + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || + (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) + { + strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind); + eRet = OMX_ErrorInvalidComponentName; + } + break; + } + + case OMX_IndexParamPriorityMgmt: + { + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n", + priorityMgmtype->nGroupID); + + DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n", + priorityMgmtype->nGroupPriority); + + m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; + m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; + + break; + } + + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", + bufferSupplierType->eBufferSupplier); + if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) + m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; + + else + + eRet = OMX_ErrorBadPortIndex; + + break; + + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoH263: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg4: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", + paramIndex); + break; + } + case OMX_IndexParamVideoMpeg2: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n", + paramIndex); + break; + } + case OMX_QcomIndexParamVideoDecoderPictureOrder: + { + QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = + (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; + struct v4l2_control control; + int pic_order,rc=0; + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n", + pictureOrder->eOutputPictureOrder); + if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { + pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; + } + else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){ + pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; + time_stamp_dts.set_timestamp_reorder_mode(false); + } + else + eRet = OMX_ErrorBadParameter; + if (eRet == OMX_ErrorNone) + { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; + control.value = pic_order; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + if(rc) + { + DEBUG_PRINT_ERROR("\n Set picture order failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + } + break; + } + case OMX_QcomIndexParamConcealMBMapExtraData: + if(!secure_mode) + eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + case OMX_QcomIndexParamFrameInfoExtraData: + { + if(!secure_mode) + eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + } + case OMX_QcomIndexParamInterlaceExtraData: + if(!secure_mode) + eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + case OMX_QcomIndexParamH264TimeInfo: + if(!secure_mode) + eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, + ((QOMX_ENABLETYPE *)paramData)->bEnable); + else { + DEBUG_PRINT_ERROR("\n secure mode setting not supported"); + eRet = OMX_ErrorUnsupportedSetting; + } + break; + case OMX_QcomIndexParamVideoDivx: + { + QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; + } + break; + case OMX_QcomIndexPlatformPvt: + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n"); + OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; + if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) + { + DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); + eRet = OMX_ErrorUnsupportedSetting; + } + else + { + m_out_pvt_entry_pmem = OMX_TRUE; + if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n"); + m_use_output_pmem = OMX_TRUE; + } + } + + } + break; + case OMX_QcomIndexParamVideoSyncFrameDecodingMode: + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); + DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); + struct v4l2_control control; + int rc; + drv_ctx.idr_only_decoding = 1; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; + control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + if(rc) + { + DEBUG_PRINT_ERROR("\n Set picture order failed"); + eRet = OMX_ErrorUnsupportedSetting; + } else { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; + control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); + if(rc) + { + DEBUG_PRINT_ERROR("\n Sync frame setting failed"); + eRet = OMX_ErrorUnsupportedSetting; + } + /*Setting sync frame decoding on driver might change buffer + * requirements so update them here*/ + if (get_buffer_req(&drv_ctx.ip_buf)) { + DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer requirements"); + eRet = OMX_ErrorUnsupportedSetting; + } + } + } + break; + + case OMX_QcomIndexParamIndexExtraDataType: + { + if(!secure_mode) { + QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; + if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && + (extradataIndexType->bEnabled == OMX_TRUE) && + (extradataIndexType->nPortIndex == 1)) + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n"); + eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); + + } + } + } + break; + case OMX_QcomIndexParamEnableSmoothStreaming: + { +#ifndef SMOOTH_STREAMING_DISABLED + struct v4l2_control control; + struct v4l2_format fmt; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; + control.value = 1; + int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); + if(rc < 0) { + DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); + eRet = OMX_ErrorHardware; + } +#else + eRet = OMX_ErrorUnsupportedSetting; +#endif + } + break; +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + /* Need to allow following two set_parameters even in Idle + * state. This is ANDROID architecture which is not in sync + * with openmax standard. */ + case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: + { + EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; + if(enableNativeBuffers) { + m_enable_android_native_buffers = enableNativeBuffers->enable; + } + } + break; + case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: + { + eRet = use_android_native_buffer(hComp, paramData); + } + break; +#endif + case OMX_QcomIndexParamEnableTimeStampReorder: + { + QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; + if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { + if (reorder->bEnable == OMX_TRUE) { + frm_int =0; + time_stamp_dts.set_timestamp_reorder_mode(true); + } + else + time_stamp_dts.set_timestamp_reorder_mode(false); + } else { + time_stamp_dts.set_timestamp_reorder_mode(false); + if (reorder->bEnable == OMX_TRUE) + { + eRet = OMX_ErrorUnsupportedSetting; + } + } + } + break; + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = + (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; + if (pParam) { + m_profile_lvl.eProfile = pParam->eProfile; + m_profile_lvl.eLevel = pParam->eLevel; + } + break; + + } + default: + { + DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); + eRet = OMX_ErrorUnsupportedIndex; + } + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetConfig + +DESCRIPTION + OMX Get Config Method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_INOUT OMX_PTR configData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + if (m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + switch ((unsigned long)configIndex) + { + case OMX_QcomIndexConfigInterlaced: + { + OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = + (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; + if (configFmt->nPortIndex == 1) + { + if (configFmt->nIndex == 0) + { + configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; + } + else if (configFmt->nIndex == 1) + { + configFmt->eInterlaceType = + OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; + } + else if (configFmt->nIndex == 2) + { + configFmt->eInterlaceType = + OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; + } + else + { + DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" + " NoMore Interlaced formats\n"); + eRet = OMX_ErrorNoMore; + } + + } + else + { + DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", + (int)configFmt->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + case OMX_QcomIndexQueryNumberOfVideoDecInstance: + { + QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = + (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; + decoderinstances->nNumOfInstances = 16; + /*TODO: How to handle this case */ + break; + } + case OMX_QcomIndexConfigVideoFramePackingArrangement: + { + if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) + { + OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = + (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; + h264_parser->get_frame_pack_data(configFmt); + } + else + { + DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); + } + break; + } + case OMX_IndexConfigCommonOutputCrop: + { + OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; + memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); + break; + } + default: + { + DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); + eRet = OMX_ErrorBadParameter; + } + + } + + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SetConfig + +DESCRIPTION + OMX Set Config method implementation + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_IN OMX_PTR configData) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_VIDEO_CONFIG_NALSIZE *pNal; + + DEBUG_PRINT_LOW("\n Set Config Called"); + + if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) + { + OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; + DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called"); + if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) + { + DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC"); + OMX_U32 extra_size; + // Parsing done here for the AVC atom is definitely not generic + // Currently this piece of code is working, but certainly + // not tested with all .mp4 files. + // Incase of failure, we might need to revisit this + // for a generic piece of code. + + // Retrieve size of NAL length field + // byte #4 contains the size of NAL lenght field + nal_length = (config->pData[4] & 0x03) + 1; + + extra_size = 0; + if (nal_length > 2) + { + /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ + extra_size = (nal_length - 2) * 2; + } + + // SPS starts from byte #6 + OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); + OMX_U8 *pDestBuf; + m_vendor_config.nPortIndex = config->nPortIndex; + + // minus 6 --> SPS starts from byte #6 + // minus 1 --> picture param set byte to be ignored from avcatom + m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; + m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); + OMX_U32 len; + OMX_U8 index = 0; + // case where SPS+PPS is sent as part of set_config + pDestBuf = m_vendor_config.pData; + + DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n", + m_vendor_config.nPortIndex, + m_vendor_config.nDataSize, + m_vendor_config.pData); + while (index < 2) + { + uint8 *psize; + len = *pSrcBuf; + len = len << 8; + len |= *(pSrcBuf + 1); + psize = (uint8 *) & len; + memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); + for (unsigned int i = 0; i < nal_length; i++) + { + pDestBuf[i] = psize[nal_length - 1 - i]; + } + //memcpy(pDestBuf,pSrcBuf,(len+2)); + pDestBuf += len + nal_length; + pSrcBuf += len + 2; + index++; + pSrcBuf++; // skip picture param set + len = 0; + } + } + else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || + !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) + { + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); + memcpy(m_vendor_config.pData, config->pData,config->nDataSize); + } + else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) + { + if(m_vendor_config.pData) + { + free(m_vendor_config.pData); + m_vendor_config.pData = NULL; + m_vendor_config.nDataSize = 0; + } + + if (((*((OMX_U32 *) config->pData)) & + VC1_SP_MP_START_CODE_MASK) == + VC1_SP_MP_START_CODE) + { + DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = + (OMX_U8 *) malloc(config->nDataSize); + memcpy(m_vendor_config.pData, config->pData, + config->nDataSize); + m_vc1_profile = VC1_SP_MP_RCV; + } + else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) + { + DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = + (OMX_U8 *) malloc((config->nDataSize)); + memcpy(m_vendor_config.pData, config->pData, + config->nDataSize); + m_vc1_profile = VC1_AP; + } + else if ((config->nDataSize == VC1_STRUCT_C_LEN)) + { + DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); + m_vendor_config.nPortIndex = config->nPortIndex; + m_vendor_config.nDataSize = config->nDataSize; + m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); + memcpy(m_vendor_config.pData,config->pData,config->nDataSize); + m_vc1_profile = VC1_SP_MP_RCV; + } + else + { + DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); + } + } + return ret; + } + else if (configIndex == OMX_IndexConfigVideoNalSize) + { + struct v4l2_control temp; + temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT; + + pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); + switch (pNal->nNaluBytes) { + case 0: + temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES; + break; + case 2: + temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH; + break; + case 4: + temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH; + break; + default: + return OMX_ErrorUnsupportedSetting; + } + + if (!arbitrary_bytes) { + /* In arbitrary bytes mode, the assembler strips out nal size and replaces + * with start code, so only need to notify driver in frame by frame mode */ + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) + { + DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT"); + return OMX_ErrorHardware; + } + } + + nal_length = pNal->nNaluBytes; + m_frame_parser.init_nal_length(nal_length); + + DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length); + return ret; + } + else if (configIndex == OMX_IndexVendorVideoFrameRate) + { + OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData; + DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps); + + if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) + { + if (config->bEnabled) + { + if ((config->nFps >> 16) > 0) + { + DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d", + config->nFps >> 16); + Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator, + drv_ctx.frame_rate.fps_denominator); + + if (!drv_ctx.frame_rate.fps_numerator) + { + DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); + drv_ctx.frame_rate.fps_numerator = 30; + } + + if (drv_ctx.frame_rate.fps_denominator) + { + drv_ctx.frame_rate.fps_numerator = (int) + drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; + } + + drv_ctx.frame_rate.fps_denominator = 1; + frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / + drv_ctx.frame_rate.fps_numerator; + + struct v4l2_outputparm oparm; + /*XXX: we're providing timing info as seconds per frame rather than frames + * per second.*/ + oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; + oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; + + struct v4l2_streamparm sparm; + sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + sparm.parm.output = oparm; + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) + { + DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ + performance might be affected"); + ret = OMX_ErrorHardware; + } + client_set_fps = true; + } + else + { + DEBUG_PRINT_ERROR("Frame rate not supported."); + ret = OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate"); + client_set_fps = false; + } + } + else + { + DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d", + (int)config->nPortIndex); + ret = OMX_ErrorBadPortIndex; + } + + return ret; + } + + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetExtensionIndex + +DESCRIPTION + OMX GetExtensionIndex method implementaion. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_STRING paramName, + OMX_OUT OMX_INDEXTYPE* indexType) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); + return OMX_ErrorInvalidState; + } + else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; + } + else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) + { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; + } +#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) + else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; + } + else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; + } + else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { + DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName); + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; + } + else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; + } +#endif + else { + DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName); + return OMX_ErrorNotImplemented; + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::GetState + +DESCRIPTION + Returns the state information back to the caller. + +PARAMETERS + . + +RETURN VALUE + Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STATETYPE* state) +{ + *state = m_state; + DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentTunnelRequest + +DESCRIPTION + OMX Component Tunnel Request method implementation. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_HANDLETYPE peerComponent, + OMX_IN OMX_U32 peerPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) +{ + DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::UseOutputBuffer + +DESCRIPTION + Helper function for Use buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_extradata() +{ +#ifdef USE_ION + if (drv_ctx.extradata_info.buffer_size) { + if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { + munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); + close(drv_ctx.extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&drv_ctx.extradata_info.ion); + } + drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); + drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( + drv_ctx.extradata_info.size, 4096, + &drv_ctx.extradata_info.ion.ion_alloc_data, + &drv_ctx.extradata_info.ion.fd_ion_data, 0); + if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { + DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n"); + return OMX_ErrorInsufficientResources; + } + drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, + drv_ctx.extradata_info.size, + PROT_READ|PROT_WRITE, MAP_SHARED, + drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); + if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); + close(drv_ctx.extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&drv_ctx.extradata_info.ion); + return OMX_ErrorInsufficientResources; + } + } +#endif + return OMX_ErrorNone; +} + +void omx_vdec::free_extradata() { +#ifdef USE_ION + if (drv_ctx.extradata_info.uaddr) { + munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); + close(drv_ctx.extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&drv_ctx.extradata_info.ion); + } + memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); +#endif +} + +OMX_ERRORTYPE omx_vdec::use_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + struct vdec_setbuffer_cmd setbuffers; + OMX_PTR privateAppData = NULL; + private_handle_t *handle = NULL; + OMX_U8 *buff = buffer; + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + int extra_idx = 0; + + if (!m_out_mem_ptr) { + DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); + eRet = allocate_output_headers(); + if (eRet == OMX_ErrorNone) + eRet = allocate_extradata(); + } + + if (eRet == OMX_ErrorNone) { + for(i=0; i< drv_ctx.op_buf.actualcount; i++) { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + break; + } + } + } + + if(i >= drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount); + eRet = OMX_ErrorInsufficientResources; + } + + if (eRet == OMX_ErrorNone) { +#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) + if(m_enable_android_native_buffers) { + if (m_use_android_native_buffers) { + UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; + sp nBuf = params->nativeBuffer; + handle = (private_handle_t *)nBuf->handle; + privateAppData = params->pAppPrivate; + } else { + handle = (private_handle_t *)buff; + privateAppData = appData; + } + + if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { + DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," + " expected %u, got %lu", + drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); + return OMX_ErrorBadParameter; + } + + if (!m_use_android_native_buffers) { + if (!secure_mode) { + buff = (OMX_U8*)mmap(0, handle->size, + PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); + if (buff == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); + return OMX_ErrorInsufficientResources; + } + } + } +#if defined(_ANDROID_ICS_) + native_buffer[i].nativehandle = handle; + native_buffer[i].privatehandle = handle; +#endif + if(!handle) { + DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); + return OMX_ErrorBadParameter; + } + drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; + drv_ctx.ptr_outputbuffer[i].offset = 0; + drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; + drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; + drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size; + } else +#endif + + if (!ouput_egl_buffers && !m_use_output_pmem) { +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( + drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, + &drv_ctx.op_buf_ion_info[i].ion_alloc_data, + &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); + if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd); + return OMX_ErrorInsufficientResources; + } + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; +#else + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + open (MEM_DEVICE,O_RDWR); + + if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { + DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); + return OMX_ErrorInsufficientResources; + } + + /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ + if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) + { + drv_ctx.ptr_outputbuffer[i].pmem_fd = \ + open (MEM_DEVICE,O_RDWR); + if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { + DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, + drv_ctx.op_buf.buffer_size, + drv_ctx.op_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(drv_ctx.ptr_outputbuffer[i].pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if(!secure_mode) { + drv_ctx.ptr_outputbuffer[i].bufferaddr = + (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, + PROT_READ|PROT_WRITE, MAP_SHARED, + drv_ctx.ptr_outputbuffer[i].pmem_fd,0); + if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { + close(drv_ctx.ptr_outputbuffer[i].pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[i]); +#endif + DEBUG_PRINT_ERROR("Unable to mmap output buffer\n"); + return OMX_ErrorInsufficientResources; + } + } + drv_ctx.ptr_outputbuffer[i].offset = 0; + privateAppData = appData; + } + else { + + DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); + if (!appData || !bytes ) { + if(!secure_mode && !buffer) { + DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case"); + return OMX_ErrorBadParameter; + } + } + + OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; + pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; + if (!pmem_list->entryList || !pmem_list->entryList->entry || + !pmem_list->nEntries || + pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { + DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer"); + return OMX_ErrorBadParameter; + } + pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + pmem_list->entryList->entry; + DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx", + pmem_info->pmem_fd); + drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; + drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; + drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; + drv_ctx.ptr_outputbuffer[i].mmaped_size = + drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; + privateAppData = appData; + } + m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; + m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; + + *bufferHdr = (m_out_mem_ptr + i ); + if(secure_mode) + drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; + //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], + sizeof (vdec_bufferpayload)); + + DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, + drv_ctx.ptr_outputbuffer[i].bufferaddr, + drv_ctx.ptr_outputbuffer[i].pmem_fd ); + + buf.index = i; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].length = drv_ctx.op_buf.buffer_size; + plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - + (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; + plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; + plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; + plane[0].data_offset = 0; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; + plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + buf.m.planes = plane; + buf.length = drv_ctx.num_planes; + + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { + DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); + /*TODO: How to handle this case */ + return OMX_ErrorInsufficientResources; + } + + if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { + enum v4l2_buf_type buf_type; + buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { + return OMX_ErrorInsufficientResources; + } else { + streaming[CAPTURE_PORT] = true; + DEBUG_PRINT_LOW("\n STREAMON Successful \n "); + } + } + + (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; + if (m_enable_android_native_buffers) { + DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); + (*bufferHdr)->pBuffer = (OMX_U8 *)handle; + } else { + (*bufferHdr)->pBuffer = buff; + } + (*bufferHdr)->pAppPrivate = privateAppData; + BITMASK_SET(&m_out_bm_count,i); + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::use_input_heap_buffers + +DESCRIPTION + OMX Use Buffer Heap allocation method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer); + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!m_inp_heap_ptr) + m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), + drv_ctx.ip_buf.actualcount); + if(!m_phdr_pmem_ptr) + m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) + calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), + drv_ctx.ip_buf.actualcount); + if(!m_inp_heap_ptr || !m_phdr_pmem_ptr) + { + DEBUG_PRINT_ERROR("Insufficent memory"); + eRet = OMX_ErrorInsufficientResources; + } + else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) + { + input_use_buffer = true; + memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); + m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; + m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; + m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; + m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; + m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; + *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; + eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); + DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); + if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], + (unsigned)NULL, (unsigned)NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); + return OMX_ErrorInsufficientResources; + } + m_in_alloc_cnt++; + } + else + { + DEBUG_PRINT_ERROR("All i/p buffers have been set!"); + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_vdec::UseBuffer + +DESCRIPTION + OMX Use Buffer method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE error = OMX_ErrorNone; + struct vdec_setbuffer_cmd setbuffers; + + if (bufferHdr == NULL || bytes == 0) + { + if(!secure_mode && buffer == NULL) { + DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer); + return OMX_ErrorBadParameter; + } + } + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(port == OMX_CORE_INPUT_PORT_INDEX) + error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested + else + { + DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); + error = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error); + if(error == OMX_ErrorNone) + { + if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && + BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && + BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + return error; +} + +OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, + OMX_BUFFERHEADERTYPE *pmem_bufferHdr) +{ + if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) + { + if(m_inp_heap_ptr[bufferindex].pBuffer) + free(m_inp_heap_ptr[bufferindex].pBuffer); + m_inp_heap_ptr[bufferindex].pBuffer = NULL; + } + if (pmem_bufferHdr) + free_input_buffer(pmem_bufferHdr); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + if (bufferHdr == NULL || m_inp_mem_ptr == NULL) + { + return OMX_ErrorBadParameter; + } + + index = bufferHdr - m_inp_mem_ptr; + DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); + + if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) + { + DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); + if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) + { + struct vdec_setbuffer_cmd setbuffers; + setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], + sizeof (vdec_bufferpayload)); + if(!secure_mode) { + DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d", + drv_ctx.ptr_inputbuffer[index].pmem_fd); + DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p", + drv_ctx.ptr_inputbuffer[index].mmaped_size, + drv_ctx.ptr_inputbuffer[index].bufferaddr); + munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, + drv_ctx.ptr_inputbuffer[index].mmaped_size); + } + close (drv_ctx.ptr_inputbuffer[index].pmem_fd); + drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; + if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) + { + free(m_desc_buffer_ptr[index].buf_addr); + m_desc_buffer_ptr[index].buf_addr = NULL; + m_desc_buffer_ptr[index].desc_data_size = 0; + } +#ifdef USE_ION + free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); +#endif + } + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + + if (bufferHdr == NULL || m_out_mem_ptr == NULL) + { + return OMX_ErrorBadParameter; + } + + index = bufferHdr - m_out_mem_ptr; + DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index); + + if (index < drv_ctx.op_buf.actualcount + && drv_ctx.ptr_outputbuffer) + { + DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index, + drv_ctx.ptr_outputbuffer[index].bufferaddr); + + struct vdec_setbuffer_cmd setbuffers; + setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], + sizeof (vdec_bufferpayload)); +#ifdef _ANDROID_ + if(m_enable_android_native_buffers) { + if (!secure_mode) { + if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { + munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, + drv_ctx.ptr_outputbuffer[index].mmaped_size); + } + } + drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; + } else { +#endif + if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) + { + if (!secure_mode) { + DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", + drv_ctx.ptr_outputbuffer[0].pmem_fd); + DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p", + drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, + drv_ctx.ptr_outputbuffer[0].bufferaddr); + munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, + drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); + } + close (drv_ctx.ptr_outputbuffer[0].pmem_fd); + drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[0]); +#endif + } +#ifdef _ANDROID_ + } +#endif + if (release_output_done()) { + free_extradata(); + } + } + + return OMX_ErrorNone; + +} + +OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes) +{ + OMX_BUFFERHEADERTYPE *input = NULL; + unsigned char *buf_addr = NULL; + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned i = 0; + + /* Sanity Check*/ + if (bufferHdr == NULL) + { + return OMX_ErrorBadParameter; + } + + if (m_inp_heap_ptr == NULL) + { + m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), + drv_ctx.ip_buf.actualcount); + m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), + drv_ctx.ip_buf.actualcount); + + if (m_inp_heap_ptr == NULL) + { + DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + } + + /*Find a Free index*/ + for(i=0; i< drv_ctx.ip_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); + break; + } + } + + if (i < drv_ctx.ip_buf.actualcount) + { + buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); + + if (buf_addr == NULL) + { + return OMX_ErrorInsufficientResources; + } + + *bufferHdr = (m_inp_heap_ptr + i); + input = *bufferHdr; + BITMASK_SET(&m_heap_inp_bm_count,i); + + input->pBuffer = (OMX_U8 *)buf_addr; + input->nSize = sizeof(OMX_BUFFERHEADERTYPE); + input->nVersion.nVersion = OMX_SPEC_VERSION; + input->nAllocLen = drv_ctx.ip_buf.buffer_size; + input->pAppPrivate = appData; + input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; + DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr ); + eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); + DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); + /*Add the Buffers to freeq*/ + if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i], + (unsigned)NULL, (unsigned)NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); + return OMX_ErrorInsufficientResources; + } + } + else + { + return OMX_ErrorBadParameter; + } + + return eRet; + +} + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateInputBuffer + +DESCRIPTION + Helper function for allocate buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_input_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct vdec_setbuffer_cmd setbuffers; + OMX_BUFFERHEADERTYPE *input = NULL; + unsigned i = 0; + unsigned char *buf_addr = NULL; + int pmem_fd = -1; + + if(bytes != drv_ctx.ip_buf.buffer_size) + { + DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d", + bytes, drv_ctx.ip_buf.buffer_size); + return OMX_ErrorBadParameter; + } + + if(!m_inp_mem_ptr) + { + DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)", + drv_ctx.ip_buf.actualcount, + drv_ctx.ip_buf.buffer_size); + + m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); + + if (m_inp_mem_ptr == NULL) + { + return OMX_ErrorInsufficientResources; + } + + drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ + calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); + + if (drv_ctx.ptr_inputbuffer == NULL) + { + return OMX_ErrorInsufficientResources; + } +#ifdef USE_ION + drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ + calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); + + if (drv_ctx.ip_buf_ion_info == NULL) + { + return OMX_ErrorInsufficientResources; + } +#endif + + for (i=0; i < drv_ctx.ip_buf.actualcount; i++) + { + drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; +#ifdef USE_ION + drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; +#endif + } + } + + for(i=0; i< drv_ctx.ip_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_inp_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); + break; + } + } + + if(i < drv_ctx.ip_buf.actualcount) + { + struct v4l2_buffer buf; + struct v4l2_plane plane; + int rc; + DEBUG_PRINT_LOW("\n Allocate input Buffer"); +#ifdef USE_ION + drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( + drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, + &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, + &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); + if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; +#else + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); + return OMX_ErrorInsufficientResources; + } + + if (pmem_fd == 0) + { + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, + drv_ctx.ip_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if (!secure_mode) { + buf_addr = (unsigned char *)mmap(NULL, + drv_ctx.ip_buf.buffer_size, + PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); + + if (buf_addr == MAP_FAILED) + { + close(pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); +#endif + DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); + return OMX_ErrorInsufficientResources; + } + } + *bufferHdr = (m_inp_mem_ptr + i); + if (secure_mode) + drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; + else + drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; + drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; + drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; + drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; + drv_ctx.ptr_inputbuffer [i].offset = 0; + + + buf.index = i; + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane.bytesused = 0; + plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; + plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; + plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; + plane.reserved[1] = 0; + plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; + buf.m.planes = &plane; + buf.length = 1; + + DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i, + drv_ctx.ptr_inputbuffer[i].bufferaddr); + + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); + + if (rc) { + DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); + /*TODO: How to handle this case */ + return OMX_ErrorInsufficientResources; + } + + input = *bufferHdr; + BITMASK_SET(&m_inp_bm_count,i); + DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr); + if (secure_mode) + input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; + else + input->pBuffer = (OMX_U8 *)buf_addr; + input->nSize = sizeof(OMX_BUFFERHEADERTYPE); + input->nVersion.nVersion = OMX_SPEC_VERSION; + input->nAllocLen = drv_ctx.ip_buf.buffer_size; + input->pAppPrivate = appData; + input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; + input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; + + if (drv_ctx.disable_dmx) + { + eRet = allocate_desc_buffer(i); + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateOutputBuffer + +DESCRIPTION + Helper fn for AllocateBuffer in the output pin + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything went well. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + struct vdec_setbuffer_cmd setbuffers; + int extra_idx = 0; +#ifdef USE_ION + int ion_device_fd =-1; + struct ion_allocation_data ion_alloc_data; + struct ion_fd_data fd_ion_data; +#endif + if(!m_out_mem_ptr) + { + DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)", + drv_ctx.op_buf.actualcount, + drv_ctx.op_buf.buffer_size); + int nBufHdrSize = 0; + int nPlatformEntrySize = 0; + int nPlatformListSize = 0; + int nPMEMInfoSize = 0; + int pmem_fd = -1; + unsigned char *pmem_baseaddress = NULL; + + OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; + + DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n", + drv_ctx.op_buf.actualcount); + nBufHdrSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_BUFFERHEADERTYPE); + + nPMEMInfoSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); + nPlatformListSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); + nPlatformEntrySize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); + + DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, + sizeof(OMX_BUFFERHEADERTYPE), + nPMEMInfoSize, + nPlatformListSize); + DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize, + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + ion_device_fd = alloc_map_ion_memory( + drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount, + drv_ctx.op_buf.alignment, + &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0); + if (ion_device_fd < 0) { + return OMX_ErrorInsufficientResources; + } + pmem_fd = fd_ion_data.fd; +#else + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", + drv_ctx.op_buf.buffer_size); + return OMX_ErrorInsufficientResources; + } + + if(pmem_fd == 0) + { + pmem_fd = open (MEM_DEVICE,O_RDWR); + + if (pmem_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", + drv_ctx.op_buf.buffer_size); + return OMX_ErrorInsufficientResources; + } + } + + if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size * + drv_ctx.op_buf.actualcount, + drv_ctx.op_buf.alignment)) + { + DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); + close(pmem_fd); + return OMX_ErrorInsufficientResources; + } +#endif + if (!secure_mode) { + pmem_baseaddress = (unsigned char *)mmap(NULL, + (drv_ctx.op_buf.buffer_size * + drv_ctx.op_buf.actualcount), + PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); + if (pmem_baseaddress == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\n MMAP failed for Size %d", + drv_ctx.op_buf.buffer_size); + close(pmem_fd); +#ifdef USE_ION + free_ion_memory(&drv_ctx.op_buf_ion_info[i]); +#endif + return OMX_ErrorInsufficientResources; + } + } + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + // Alloc mem for platform specific info + char *pPtr=NULL; + pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + + nPMEMInfoSize,1); + drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ + calloc (sizeof(struct vdec_bufferpayload), + drv_ctx.op_buf.actualcount); + drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ + calloc (sizeof (struct vdec_output_frameinfo), + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ + calloc (sizeof(struct vdec_ion), + drv_ctx.op_buf.actualcount); +#endif + + if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer + && drv_ctx.ptr_respbuffer) + { + drv_ctx.ptr_outputbuffer[0].mmaped_size = + (drv_ctx.op_buf.buffer_size * + drv_ctx.op_buf.actualcount); + bufHdr = m_out_mem_ptr; + m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); + m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) + (((char *) m_platform_list) + nPlatformListSize); + m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + (((char *) m_platform_entry) + nPlatformEntrySize); + pPlatformList = m_platform_list; + pPlatformEntry = m_platform_entry; + pPMEMInfo = m_pmem_info; + + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); + + // Settting the entire storage nicely + DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry); + DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); + for(i=0; i < drv_ctx.op_buf.actualcount ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = bytes; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = appData; + bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + // Platform specific PMEM Information + // Initialize the Platform Entry + //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i); + pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pPlatformEntry->entry = pPMEMInfo; + // Initialize the Platform List + pPlatformList->nEntries = 1; + pPlatformList->entryList = pPlatformEntry; + // Keep pBuffer NULL till vdec is opened + bufHdr->pBuffer = NULL; + bufHdr->nOffset = 0; + + pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; + pPMEMInfo->pmem_fd = 0; + bufHdr->pPlatformPrivate = pPlatformList; + + drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd; + m_pmem_info[i].pmem_fd = pmem_fd; +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd; + drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data; + drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data; +#endif + + /*Create a mapping between buffers*/ + bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; + drv_ctx.ptr_respbuffer[i].client_data = (void *)\ + &drv_ctx.ptr_outputbuffer[i]; + drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; + drv_ctx.ptr_outputbuffer[i].bufferaddr = + pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); + + DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p", + pmem_fd, drv_ctx.ptr_outputbuffer[i].offset, + drv_ctx.ptr_outputbuffer[i].bufferaddr); + // Move the buffer and buffer header pointers + bufHdr++; + pPMEMInfo++; + pPlatformEntry++; + pPlatformList++; + } + } + else + { + DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ + m_out_mem_ptr, pPtr); + if(m_out_mem_ptr) + { + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(pPtr) + { + free(pPtr); + pPtr = NULL; + } + if(drv_ctx.ptr_outputbuffer) + { + free(drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } + if(drv_ctx.ptr_respbuffer) + { + free(drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif + eRet = OMX_ErrorInsufficientResources; + } + if (eRet == OMX_ErrorNone) + eRet = allocate_extradata(); + } + + for(i=0; i< drv_ctx.op_buf.actualcount; i++) + { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); + break; + } + } + + if (eRet == OMX_ErrorNone) + { + if(i < drv_ctx.op_buf.actualcount) + { + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + int rc; + m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; + + drv_ctx.ptr_outputbuffer[i].buffer_len = + drv_ctx.op_buf.buffer_size; + + *bufferHdr = (m_out_mem_ptr + i ); + if (secure_mode) { + drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; + } + drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; + + buf.index = i; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].length = drv_ctx.op_buf.buffer_size; + plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - + (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; +#ifdef USE_ION + plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; +#endif + plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; + plane[0].data_offset = 0; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; + plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + buf.m.planes = plane; + buf.length = drv_ctx.num_planes; + DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr); + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); + if (rc) { + /*TODO: How to handle this case */ + return OMX_ErrorInsufficientResources; + } + + if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { + enum v4l2_buf_type buf_type; + buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); + if (rc) { + return OMX_ErrorInsufficientResources; + } else { + streaming[CAPTURE_PORT] = true; + DEBUG_PRINT_LOW("\n STREAMON Successful \n "); + } + } + + (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; + (*bufferHdr)->pAppPrivate = appData; + BITMASK_SET(&m_out_bm_count,i); + } + else + { + DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n"); + eRet = OMX_ErrorInsufficientResources; + } + } + + return eRet; +} + + +// AllocateBuffer -- API Call +/* ====================================================================== +FUNCTION + omx_vdec::AllocateBuffer + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + unsigned i = 0; + OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type + + DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if(port == OMX_CORE_INPUT_PORT_INDEX) + { + if (arbitrary_bytes) + { + eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); + } + else + { + eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); + } + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + { + eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, + appData,bytes); + } + else + { + DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); + if(eRet == OMX_ErrorNone) + { + if(allocate_done()){ + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + } + DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); + return eRet; +} + +// Free Buffer - API call +/* ====================================================================== +FUNCTION + omx_vdec::FreeBuffer + +DESCRIPTION + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int nPortIndex; + DEBUG_PRINT_LOW("In for decoder free_buffer \n"); + + if(m_state == OMX_StateIdle && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); + } + else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| + (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) + { + DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port); + } + else if ((port == OMX_CORE_INPUT_PORT_INDEX && + BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || + (port == OMX_CORE_OUTPUT_PORT_INDEX && + BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) + { + DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port); + } + else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) + { + DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + + return OMX_ErrorIncorrectStateOperation; + } + else if (m_state != OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + } + + if(port == OMX_CORE_INPUT_PORT_INDEX) + { + /*Check if arbitrary bytes*/ + if(!arbitrary_bytes && !input_use_buffer) + nPortIndex = buffer - m_inp_mem_ptr; + else + nPortIndex = buffer - m_inp_heap_ptr; + + DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex); + if(nPortIndex < drv_ctx.ip_buf.actualcount) + { + // Clear the bit associated with it. + BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); + BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); + if (input_use_buffer == true) + { + + DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex); + if(m_phdr_pmem_ptr) + free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); + } + else + { + if (arbitrary_bytes) + { + if(m_phdr_pmem_ptr) + free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); + else + free_input_buffer(nPortIndex,NULL); + } + else + free_input_buffer(buffer); + } + m_inp_bPopulated = OMX_FALSE; + /*Free the Buffer Header*/ + if (release_input_done()) + { + DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released"); + free_input_buffer_header(); + } + } + else + { + DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) + && release_input_done()) + { + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); + post_event(OMX_CommandPortDisable, + OMX_CORE_INPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else if(port == OMX_CORE_OUTPUT_PORT_INDEX) + { + // check if the buffer is valid + nPortIndex = buffer - client_buffers.get_il_buf_hdr(); + if(nPortIndex < drv_ctx.op_buf.actualcount) + { + DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex); + // Clear the bit associated with it. + BITMASK_CLEAR(&m_out_bm_count,nPortIndex); + m_out_bPopulated = OMX_FALSE; + client_buffers.free_output_buffer (buffer); + + if (release_output_done()) + { + free_output_buffer_header(); + } + } + else + { + DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) + && release_output_done()) + { + DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); + + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); + memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); + } +#endif + + post_event(OMX_CommandPortDisable, + OMX_CORE_OUTPUT_PORT_INDEX, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else + { + eRet = OMX_ErrorBadPortIndex; + } + if((eRet == OMX_ErrorNone) && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + if(release_done()) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); + post_event(OMX_CommandStateSet, OMX_StateLoaded, + OMX_COMPONENT_GENERATE_EVENT); + } + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_vdec::EmptyThisBuffer + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE ret1 = OMX_ErrorNone; + unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; + + if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) + { + codec_config_flag = true; + DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); + } + else + { + codec_config_flag = false; + } + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (buffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); + return OMX_ErrorBadParameter; + } + + if (!m_inp_bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled."); + return OMX_ErrorIncorrectStateOperation; + } + + if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) + { + DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex); + return OMX_ErrorBadPortIndex; + } + +#ifdef _ANDROID_ + if(iDivXDrmDecrypt) + { + OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer); + if(drmErr != OMX_ErrorNone) { + // this error can be ignored + DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr); + } + } +#endif //_ANDROID_ + if (perf_flag) + { + if (!latency) + { + dec_time.stop(); + latency = dec_time.processing_time_us(); + dec_time.start(); + } + } + + if (arbitrary_bytes) + { + nBufferIndex = buffer - m_inp_heap_ptr; + } + else + { + if (input_use_buffer == true) + { + nBufferIndex = buffer - m_inp_heap_ptr; + m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; + m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; + m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; + buffer = &m_inp_mem_ptr[nBufferIndex]; + DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu", + &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); + } + else{ + nBufferIndex = buffer - m_inp_mem_ptr; + } + } + + if (nBufferIndex > drv_ctx.ip_buf.actualcount ) + { + DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", + buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); + if (arbitrary_bytes) + { + post_event ((unsigned)hComp,(unsigned)buffer, + OMX_COMPONENT_GENERATE_ETB_ARBITRARY); + } + else + { + if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) + set_frame_rate(buffer->nTimeStamp); + post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::empty_this_buffer_proxy + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + int push_cnt = 0,i=0; + unsigned nPortIndex = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + struct vdec_input_frameinfo frameinfo; + struct vdec_bufferpayload *temp_buffer; + struct vdec_seqheader seq_header; + bool port_setting_changed = true; + bool not_coded_vop = false; + + /*Should we generate a Aync error event*/ + if (buffer == NULL || buffer->pInputPortPrivate == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); + return OMX_ErrorBadParameter; + } + + nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + + if (nPortIndex > drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", + nPortIndex); + return OMX_ErrorBadParameter; + } + + pending_input_buffers++; + + /* return zero length and not an EOS buffer */ + if (!arbitrary_bytes && (buffer->nFilledLen == 0) && + ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) + { + DEBUG_PRINT_HIGH("\n return zero legth buffer"); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorNone; + } + + + if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){ + mp4StreamType psBits; + psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); + psBits.numBytes = buffer->nFilledLen; + mp4_headerparser.parseHeader(&psBits); + not_coded_vop = mp4_headerparser.is_notcodec_vop( + (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); + if(not_coded_vop) { + DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u", + buffer->nFilledLen,frame_count); + if(buffer->nFlags & OMX_BUFFERFLAG_EOS){ + DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero"); + not_coded_vop = false; + buffer->nFilledLen = 0; + } + } + } + + if(input_flush_progress == true + + || not_coded_vop + + ) + { + DEBUG_PRINT_LOW("\n Flush in progress return buffer "); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorNone; + } + + temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; + + if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) + { + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + /*for use buffer we need to memcpy the data*/ + temp_buffer->buffer_len = buffer->nFilledLen; + + if (input_use_buffer) + { + if (buffer->nFilledLen <= temp_buffer->buffer_len) + { + if(arbitrary_bytes) + { + memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); + } + else + { + memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), + buffer->nFilledLen); + } + } + else + { + return OMX_ErrorBadParameter; + } + + } + + frameinfo.bufferaddr = temp_buffer->bufferaddr; + frameinfo.client_data = (void *) buffer; + frameinfo.datalen = temp_buffer->buffer_len; + frameinfo.flags = 0; + frameinfo.offset = buffer->nOffset; + frameinfo.pmem_fd = temp_buffer->pmem_fd; + frameinfo.pmem_offset = temp_buffer->offset; + frameinfo.timestamp = buffer->nTimeStamp; + if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) + { + DEBUG_PRINT_LOW("ETB: dmx enabled"); + if (m_demux_entries == 0) + { + extract_demux_addr_offsets(buffer); + } + + DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries); + handle_demux_data(buffer); + frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; + frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; + } + else + { + frameinfo.desc_addr = NULL; + frameinfo.desc_size = 0; + } + if(!arbitrary_bytes) + { + frameinfo.flags |= buffer->nFlags; + } + +#ifdef _ANDROID_ + if (m_debug_timestamp) + { + if(arbitrary_bytes) + { + DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); + m_timestamp_list.insert_ts(buffer->nTimeStamp); + } + else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) + { + DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); + m_timestamp_list.insert_ts(buffer->nTimeStamp); + } + } +#endif + +#ifdef INPUT_BUFFER_LOG + if (output_capability == V4L2_PIX_FMT_VP8) { + struct vp8_ivf_frame_header{ + OMX_U32 framesize; + OMX_U32 timestamp_lo; + OMX_U32 timestamp_hi; + } vp8_frame_header; + vp8_frame_header.framesize = temp_buffer->buffer_len; + /* Currently FW doesn't use timestamp values */ + vp8_frame_header.timestamp_lo = 0; + vp8_frame_header.timestamp_hi = 0; + if (inputBufferFile1) + { + fwrite((const char *)&vp8_frame_header, + sizeof(vp8_frame_header),1,inputBufferFile1); + fwrite((const char *)temp_buffer->bufferaddr, + temp_buffer->buffer_len,1,inputBufferFile1); + } + } else { + if (inputBufferFile1) + { + fwrite((const char *)temp_buffer->bufferaddr, + temp_buffer->buffer_len,1,inputBufferFile1); + } + } +#endif + + if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) + { + frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; + } + + if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) + { + DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached"); + frameinfo.flags |= VDEC_BUFFERFLAG_EOS; + h264_scratch.nFilledLen = 0; + nal_count = 0; + look_ahead_nal = false; + frame_count = 0; + if (m_frame_parser.mutils) + m_frame_parser.mutils->initialize_frame_checking_environment(); + m_frame_parser.flush(); + h264_last_au_ts = LLONG_MAX; + h264_last_au_flags = 0; + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + } + struct v4l2_buffer buf; + struct v4l2_plane plane; + memset( (void *)&buf, 0, sizeof(buf)); + memset( (void *)&plane, 0, sizeof(plane)); + int rc; + unsigned long print_count; + if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) + { buf.flags = V4L2_BUF_FLAG_EOS; + DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ; + } + OMX_ERRORTYPE eRet = OMX_ErrorNone; + buf.index = nPortIndex; + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane.bytesused = temp_buffer->buffer_len; + plane.length = drv_ctx.ip_buf.buffer_size; + plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - + (unsigned long)temp_buffer->offset; + plane.reserved[0] = temp_buffer->pmem_fd; + plane.reserved[1] = temp_buffer->offset; + plane.data_offset = 0; + buf.m.planes = &plane; + buf.length = 1; + if (frameinfo.timestamp >= LLONG_MAX) { + buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; + } + //assumption is that timestamp is in milliseconds + buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; + buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); + buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; + buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0; + + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); + if(rc) + { + DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n"); + return OMX_ErrorHardware; + } + if(!streaming[OUTPUT_PORT]) + { + enum v4l2_buf_type buf_type; + int ret,r; + + buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); + ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); + if(!ret) { + DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n"); + streaming[OUTPUT_PORT] = true; + } else{ + DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n"); + DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); + post_event ((unsigned int)buffer,VDEC_S_SUCCESS, + OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorBadParameter; + } +} + DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", + frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); + time_stamp_dts.insert_timestamp(buffer); + + return ret; +} + +/* ====================================================================== +FUNCTION + omx_vdec::FillThisBuffer + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("FTB in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (!m_out_bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled."); + return OMX_ErrorIncorrectStateOperation; + } + + if (buffer == NULL || + ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) + { + return OMX_ErrorBadParameter; + } + + if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) + { + DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex); + return OMX_ErrorBadPortIndex; + } + + DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg); + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_vdec::fill_this_buffer_proxy + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) +{ + OMX_ERRORTYPE nRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *buffer = bufferAdd; + unsigned nPortIndex = 0; + struct vdec_fillbuffer_cmd fillbuffer; + struct vdec_bufferpayload *ptr_outputbuffer = NULL; + struct vdec_output_frameinfo *ptr_respbuffer = NULL; + + nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); + + if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) + return OMX_ErrorBadParameter; + + DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", + bufferAdd, bufferAdd->pBuffer); + /*Return back the output buffer to client*/ + if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true) + { + DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + return OMX_ErrorNone; + } + pending_output_buffers++; + buffer = client_buffers.get_dr_buf_hdr(bufferAdd); + ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; + if (ptr_respbuffer) + { + ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; + } + + if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) + { + DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + pending_output_buffers--; + return OMX_ErrorBadParameter; + } + + /* memcpy (&fillbuffer.buffer,ptr_outputbuffer, + sizeof(struct vdec_bufferpayload)); + fillbuffer.client_data = bufferAdd;*/ + +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + // Acquire a write lock on this buffer. + if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle, + GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { + DEBUG_PRINT_ERROR("Failed to acquire genlock"); + buffer->nFilledLen = 0; + m_cb.FillBufferDone (hComp,m_app_data,buffer); + pending_output_buffers--; + return OMX_ErrorInsufficientResources; + } else { + native_buffer[buffer - m_out_mem_ptr].inuse = true; + } + } +#endif + int rc = 0; + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + memset( (void *)&buf, 0, sizeof(buf)); + memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); + int extra_idx = 0; + + buf.index = nPortIndex; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].bytesused = buffer->nFilledLen; + plane[0].length = drv_ctx.op_buf.buffer_size; + plane[0].m.userptr = + (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - + (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; + plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; + plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; + plane[0].data_offset = 0; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].bytesused = 0; + plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; + plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + buf.m.planes = plane; + buf.length = drv_ctx.num_planes; + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); + if (rc) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to qbuf to driver"); + } +//#ifdef _ANDROID_ICS_ + // if (m_enable_android_native_buffers) + // { + // Unlock the buffer + // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { + // DEBUG_PRINT_ERROR("Releasing genlock failed"); + // return OMX_ErrorInsufficientResources; + /// } else { + // native_buffer[buffer - m_out_mem_ptr].inuse = false; + // } + // } +//#endif + //m_cb.FillBufferDone (hComp,m_app_data,buffer); + // pending_output_buffers--; + // return OMX_ErrorBadParameter; + //} + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::SetCallbacks + +DESCRIPTION + Set the callbacks. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_CALLBACKTYPE* callbacks, + OMX_IN OMX_PTR appData) +{ + + m_cb = *callbacks; + DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ + m_cb.EventHandler,m_cb.FillBufferDone); + m_app_data = appData; + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentDeInit + +DESCRIPTION + Destroys the component and release memory allocated to the heap. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) +{ +#ifdef _ANDROID_ + if(iDivXDrmDecrypt) + { + delete iDivXDrmDecrypt; + iDivXDrmDecrypt=NULL; + } +#endif //_ANDROID_ + + unsigned i = 0; + if (OMX_StateLoaded != m_state) + { + DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ + m_state); + DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); + } + else + { + DEBUG_PRINT_HIGH("\n Playback Ended - PASSED"); + } + + /*Check if the output buffers have to be cleaned up*/ + if(m_out_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing the Output Memory\n"); + for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) + { + free_output_buffer (&m_out_mem_ptr[i]); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + if (native_buffer[i].inuse) + { + if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) { + DEBUG_PRINT_ERROR("Unlocking genlock failed"); + } + native_buffer[i].inuse = false; + } + } +#endif + } +#ifdef _ANDROID_ICS_ + memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); +#endif + } + + /*Check if the input buffers have to be cleaned up*/ + if(m_inp_mem_ptr || m_inp_heap_ptr) + { + DEBUG_PRINT_LOW("Freeing the Input Memory\n"); + for (i = 0; i. + +PARAMETERS + . + +RETURN VALUE + Not Implemented error. + +========================================================================== */ +OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN void* eglImage) +{ + OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; + +#ifdef USE_EGL_IMAGE_GPU + PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; + EGLint fd = -1, offset = 0,pmemPtr = 0; +#else + int fd = -1, offset = 0; +#endif + DEBUG_PRINT_HIGH("\nuse EGL image support for decoder"); + if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { + DEBUG_PRINT_ERROR("\n "); + } +#ifdef USE_EGL_IMAGE_GPU + if(m_display_id == NULL) { + DEBUG_PRINT_ERROR("Display ID is not set by IL client \n"); + return OMX_ErrorInsufficientResources; + } + egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) + eglGetProcAddress("eglQueryImageKHR"); + egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); + egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); + egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); +#else //with OMX test app + struct temp_egl { + int pmem_fd; + int offset; + }; + struct temp_egl *temp_egl_id = NULL; + void * pmemPtr = (void *) eglImage; + temp_egl_id = (struct temp_egl *)eglImage; + if (temp_egl_id != NULL) + { + fd = temp_egl_id->pmem_fd; + offset = temp_egl_id->offset; + } +#endif + if (fd < 0) { + DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd); + return OMX_ErrorInsufficientResources; + } + pmem_info.pmem_fd = (OMX_U32) fd; + pmem_info.offset = (OMX_U32) offset; + pmem_entry.entry = (void *) &pmem_info; + pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pmem_list.entryList = &pmem_entry; + pmem_list.nEntries = 1; + ouput_egl_buffers = true; + if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, + (void *)&pmem_list, drv_ctx.op_buf.buffer_size, + (OMX_U8 *)pmemPtr)) { + DEBUG_PRINT_ERROR("use buffer call failed for egl image\n"); + return OMX_ErrorInsufficientResources; + } + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_vdec::ComponentRoleEnum + +DESCRIPTION + OMX Component Role Enum method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_U8* role, + OMX_IN OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + + else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) + ) + + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || + (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) + ) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_LOW("\n No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } + return eRet; +} + + + + +/* ====================================================================== +FUNCTION + omx_vdec::AllocateDone + +DESCRIPTION + Checks if entire buffer pool is allocated by IL Client or not. + Need this to move to IDLE state. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_vdec::allocate_done(void) +{ + bool bRet = false; + bool bRet_In = false; + bool bRet_Out = false; + + bRet_In = allocate_input_done(); + bRet_Out = allocate_output_done(); + + if(bRet_In && bRet_Out) + { + bRet = true; + } + + return bRet; +} +/* ====================================================================== +FUNCTION + omx_vdec::AllocateInputDone + +DESCRIPTION + Checks if I/P buffer pool is allocated by IL Client or not. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_vdec::allocate_input_done(void) +{ + bool bRet = false; + unsigned i=0; + + if (m_inp_mem_ptr == NULL) + { + return bRet; + } + if(m_inp_mem_ptr ) + { + for(;i= drv_ctx.op_buf.actualcount) + { + DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer); + return OMX_ErrorBadParameter; + } + else if (output_flush_progress) + { + DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); + buffer->nFilledLen = 0; + buffer->nTimeStamp = 0; + buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; + buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; + } + + if (m_debug_extradata) + { + if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) + { + DEBUG_PRINT_HIGH("\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + } + + if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) + { + DEBUG_PRINT_HIGH("\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + } + } + + + DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", + buffer, buffer->pBuffer); + pending_output_buffers --; + + if (buffer->nFlags & OMX_BUFFERFLAG_EOS) + { + DEBUG_PRINT_HIGH("\n Output EOS has been reached"); + if (!output_flush_progress) + post_event((unsigned)NULL, (unsigned)NULL, + OMX_COMPONENT_GENERATE_EOS_DONE); + + if (psource_frame) + { + m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); + psource_frame = NULL; + } + if (pdest_frame) + { + pdest_frame->nFilledLen = 0; + m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL, + (unsigned)NULL); + pdest_frame = NULL; + } + } + + DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer); +#ifdef OUTPUT_BUFFER_LOG + if (outputBufferFile1 && buffer->nFilledLen) + { + int buf_index = buffer - m_out_mem_ptr; + int stride = drv_ctx.video_resolution.stride; + int scanlines = drv_ctx.video_resolution.scan_lines; + char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; + unsigned i; + int bytes_written = 0; + for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { + bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); + temp += stride; + } + temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; + int stride_c = stride; + for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { + bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); + temp += stride_c; + } + } +#endif + + /* For use buffer we need to copy the data */ + if (!output_flush_progress) + { + /* This is the error check for non-recoverable errros */ + bool is_duplicate_ts_valid = true; + bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive); + + if (output_capability == V4L2_PIX_FMT_MPEG4 || + output_capability == V4L2_PIX_FMT_MPEG2 || + output_capability == V4L2_PIX_FMT_DIVX || + output_capability == V4L2_PIX_FMT_DIVX_311) + is_duplicate_ts_valid = false; + + if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) { + bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; + if (mbaff) { + is_interlaced = false; + } + } + + if (buffer->nFilledLen > 0) { + time_stamp_dts.get_next_timestamp(buffer, + is_interlaced && is_duplicate_ts_valid); + if (m_debug_timestamp) + { + { + OMX_TICKS expected_ts = 0; + m_timestamp_list.pop_min_ts(expected_ts); + if (is_interlaced && is_duplicate_ts_valid) { + m_timestamp_list.pop_min_ts(expected_ts); + } + DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", + buffer->nTimeStamp, expected_ts); + + if (buffer->nTimeStamp != expected_ts) { + DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check"); + } + } + } + } else { + m_inp_err_count++; + time_stamp_dts.remove_time_stamp( + buffer->nTimeStamp, + is_interlaced && is_duplicate_ts_valid); + } + + + } + if (m_cb.FillBufferDone) + { + if (buffer->nFilledLen > 0) + { + handle_extradata(buffer); + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + set_frame_rate(buffer->nTimeStamp); + else if (arbitrary_bytes) + adjust_timestamp(buffer->nTimeStamp); + if (perf_flag) + { + if (!proc_frms) + { + dec_time.stop(); + latency = dec_time.processing_time_us() - latency; + DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); + dec_time.start(); + fps_metrics.start(); + } + proc_frms++; + if (buffer->nFlags & OMX_BUFFERFLAG_EOS) + { + OMX_U64 proc_time = 0; + fps_metrics.stop(); + proc_time = fps_metrics.processing_time_us(); + DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", + proc_frms, (float)proc_time / 1e6, + (float)(1e6 * proc_frms) / proc_time); + proc_frms = 0; + } + } + +#ifdef OUTPUT_EXTRADATA_LOG + if (outputExtradataFile) + { + + OMX_OTHER_EXTRADATATYPE *p_extra = NULL; + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(buffer->pBuffer + buffer->nOffset + + buffer->nFilledLen + 3)&(~3)); + while(p_extra && + (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) + { + DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); + fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); + if (p_extra->eType == OMX_ExtraDataNone) + { + break; + } + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + } +#endif + } + if (buffer->nFlags & OMX_BUFFERFLAG_EOS){ + prev_ts = LLONG_MAX; + rst_prev_ts = true; + } + + pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) + buffer->pPlatformPrivate)->entryList->entry; + DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd); +#ifdef _ANDROID_ICS_ + if (m_enable_android_native_buffers) + { + if (native_buffer[buffer - m_out_mem_ptr].inuse) { + if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { + DEBUG_PRINT_ERROR("Unlocking genlock failed"); + return OMX_ErrorInsufficientResources; + } + else { + native_buffer[buffer - m_out_mem_ptr].inuse = false; + } + } + } +#endif + OMX_BUFFERHEADERTYPE *il_buffer; + il_buffer = client_buffers.get_il_buf_hdr(buffer); + if (il_buffer) + m_cb.FillBufferDone (hComp,m_app_data,il_buffer); + else { + DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd); + } + else + { + return OMX_ErrorBadParameter; + } + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE* buffer) +{ + + if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) + { + DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer); + return OMX_ErrorBadParameter; + } + + DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", + buffer, buffer->pBuffer); + pending_input_buffers--; + + if (arbitrary_bytes) + { + if (pdest_frame == NULL && input_flush_progress == false) + { + DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer); + pdest_frame = buffer; + buffer->nFilledLen = 0; + buffer->nTimeStamp = LLONG_MAX; + push_input_buffer (hComp); + } + else + { + DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer); + buffer->nFilledLen = 0; + if (!m_input_free_q.insert_entry((unsigned)buffer, + (unsigned)NULL, (unsigned)NULL)) + { + DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); + } + } + } + else if(m_cb.EmptyBufferDone) + { + buffer->nFilledLen = 0; + if (input_use_buffer == true){ + buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; + } + m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); + } + return OMX_ErrorNone; +} + +int omx_vdec::async_message_process (void *context, void* message) +{ + omx_vdec* omx = NULL; + struct vdec_msginfo *vdec_msg = NULL; + OMX_BUFFERHEADERTYPE* omxhdr = NULL; + struct v4l2_buffer *v4l2_buf_ptr = NULL; + struct vdec_output_frameinfo *output_respbuf = NULL; + int rc=1; + if (context == NULL || message == NULL) + { + DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); + return -1; + } + vdec_msg = (struct vdec_msginfo *)message; + + omx = reinterpret_cast(context); + + switch (vdec_msg->msgcode) + { + + case VDEC_MSG_EVT_HW_ERROR: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_HARDWARE_ERROR); + break; + + case VDEC_MSG_RESP_START_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_START_DONE); + break; + + case VDEC_MSG_RESP_STOP_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + break; + + case VDEC_MSG_RESP_RESUME_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_RESUME_DONE); + break; + + case VDEC_MSG_RESP_PAUSE_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_PAUSE_DONE); + break; + + case VDEC_MSG_RESP_FLUSH_INPUT_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); + break; + case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: + omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); + break; + case VDEC_MSG_RESP_INPUT_FLUSHED: + case VDEC_MSG_RESP_INPUT_BUFFER_DONE: + + /* omxhdr = (OMX_BUFFERHEADERTYPE* ) + vdec_msg->msgdata.input_frame_clientdata; */ + + v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; + omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index; + if (omxhdr == NULL || + ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) + { + omxhdr = NULL; + vdec_msg->status_code = VDEC_S_EFATAL; + } + + omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, + OMX_COMPONENT_GENERATE_EBD); + break; + case VDEC_MSG_EVT_INFO_FIELD_DROPPED: + int64_t *timestamp; + timestamp = (int64_t *) malloc(sizeof(int64_t)); + if (timestamp) { + *timestamp = vdec_msg->msgdata.output_frame.time_stamp; + omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); + DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld", + vdec_msg->msgdata.output_frame.time_stamp); + } + break; + case VDEC_MSG_RESP_OUTPUT_FLUSHED: + case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: + + v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; + omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index; + DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", + omxhdr, vdec_msg->msgdata.output_frame.time_stamp, + vdec_msg->msgdata.output_frame.pic_type); + + if (omxhdr && omxhdr->pOutputPortPrivate && + ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && + (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate + - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) + { + if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) + { + omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; + omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; + omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; + omxhdr->nFlags = 0; + + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) + { + omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; + //rc = -1; + } + if (omxhdr->nFilledLen) + { + omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; + } + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) + { + omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; + } + else + { + omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME; + } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) + { + omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) + { + omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY; + } + if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) && + !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) && + !(v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)) + { + omx->post_event ((unsigned)NULL,(unsigned int)omxhdr, + OMX_COMPONENT_GENERATE_FTB); + break; + } + if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) + { + omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; + } + vdec_msg->msgdata.output_frame.bufferaddr = + omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; + int format_notably_changed = 0; + if (omxhdr->nFilledLen && + (omxhdr->nFilledLen != omx->prev_n_filled_len)) + { + if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) || + (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) { + DEBUG_PRINT_HIGH("\n Height/Width information has changed\n"); + omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom; + omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right; + format_notably_changed = 1; + } + } + if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft != + vdec_msg->msgdata.output_frame.framesize.left) + || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) + || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) + || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) { + if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) || + (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) { + omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom; + omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right; + DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n", + omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right, + omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom); + } + DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n", + omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right, + omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom); + omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; + omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; + omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; + omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; + format_notably_changed = 1; + } + if (format_notably_changed) { + if(omx->is_video_session_supported()) { + omx->post_event (NULL, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING); + } else { + if (!omx->client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); + } + omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, + OMX_COMPONENT_GENERATE_PORT_RECONFIG); + } + } + if (omxhdr->nFilledLen) + omx->prev_n_filled_len = omxhdr->nFilledLen; + + output_respbuf = (struct vdec_output_frameinfo *)\ + omxhdr->pOutputPortPrivate; + output_respbuf->len = vdec_msg->msgdata.output_frame.len; + output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) + { + output_respbuf->pic_type = PICTURE_TYPE_I; + } + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) + { + output_respbuf->pic_type = PICTURE_TYPE_P; + } + if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { + output_respbuf->pic_type = PICTURE_TYPE_B; + } + + if (omx->output_use_buffer) + memcpy ( omxhdr->pBuffer, (void *) + ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + + (unsigned long)vdec_msg->msgdata.output_frame.offset), + vdec_msg->msgdata.output_frame.len); + } + else + omxhdr->nFilledLen = 0; + omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_FBD); + } + else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) + omx->post_event ((unsigned int)NULL, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_EOS_DONE); + else + omx->post_event ((unsigned int)NULL, vdec_msg->status_code, + OMX_COMPONENT_GENERATE_HARDWARE_ERROR); + break; + case VDEC_MSG_EVT_CONFIG_CHANGED: + DEBUG_PRINT_HIGH("\n Port settings changed"); + omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, + OMX_COMPONENT_GENERATE_PORT_RECONFIG); + break; + default: + break; + } + return rc; +} + +OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ) +{ + unsigned address,p2,id; + DEBUG_PRINT_LOW("\n Empty this arbitrary"); + + if (buffer == NULL) + { + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); + DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld", + buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp); + + /* return zero length and not an EOS buffer */ + /* return buffer if input flush in progress */ + if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && + ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) + { + DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress"); + m_cb.EmptyBufferDone (hComp,m_app_data,buffer); + return OMX_ErrorNone; + } + + if (psource_frame == NULL) + { + DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp); + psource_frame = buffer; + DEBUG_PRINT_LOW("\n Try to Push One Input Buffer "); + push_input_buffer (hComp); + } + else + { + DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer); + if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL, + (unsigned)NULL)) + { + return OMX_ErrorBadParameter; + } + } + + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) +{ + unsigned address,p2,id; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if (pdest_frame == NULL || psource_frame == NULL) + { + /*Check if we have a destination buffer*/ + if (pdest_frame == NULL) + { + DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue"); + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *)address; + pdest_frame->nFilledLen = 0; + pdest_frame->nTimeStamp = LLONG_MAX; + DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame); + } + } + + /*Check if we have a destination buffer*/ + if (psource_frame == NULL) + { + DEBUG_PRINT_LOW("\n Get a source buffer from the queue"); + if (m_input_pending_q.m_size) + { + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *)address; + DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame, + psource_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu", + psource_frame->nFlags,psource_frame->nFilledLen); + + } + } + + } + + while ((pdest_frame != NULL) && (psource_frame != NULL)) + { + switch (codec_type_parse) + { + case CODEC_TYPE_MPEG4: + case CODEC_TYPE_H263: + case CODEC_TYPE_MPEG2: + ret = push_input_sc_codec(hComp); + break; + case CODEC_TYPE_H264: + ret = push_input_h264(hComp); + break; + case CODEC_TYPE_VC1: + ret = push_input_vc1(hComp); + break; + default: + break; + } + if (ret != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); + omx_report_error (); + break; + } + } + + return ret; +} + +OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) +{ + OMX_U32 partial_frame = 1; + OMX_BOOL generate_ebd = OMX_TRUE; + unsigned address = 0, p2 = 0, id = 0; + + DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld", + psource_frame,psource_frame->nTimeStamp); + if (m_frame_parser.parse_sc_frame(psource_frame, + pdest_frame,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); + return OMX_ErrorBadParameter; + } + + if (partial_frame == 0) + { + DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d", + pdest_frame->nFilledLen,psource_frame,frame_count); + + + DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp); + /*First Parsed buffer will have only header Hence skip*/ + if (frame_count == 0) + { + DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame "); + + if(codec_type_parse == CODEC_TYPE_MPEG4 || + codec_type_parse == CODEC_TYPE_DIVX) { + mp4StreamType psBits; + psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; + psBits.numBytes = pdest_frame->nFilledLen; + mp4_headerparser.parseHeader(&psBits); + } + + frame_count++; + } + else + { + pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; + if(pdest_frame->nFilledLen) + { + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *) address; + pdest_frame->nFilledLen = 0; + } + } + else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) + { + DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL"); + m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL, + (unsigned)NULL); + pdest_frame = NULL; + } + } + } + else + { + DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen); + /*Check if Destination Buffer is full*/ + if (pdest_frame->nAllocLen == + pdest_frame->nFilledLen + pdest_frame->nOffset) + { + DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); + return OMX_ErrorStreamCorrupt; + } + } + + if (psource_frame->nFilledLen == 0) + { + if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) + { + if (pdest_frame) + { + pdest_frame->nFlags |= psource_frame->nFlags; + DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d", + pdest_frame->nFilledLen,frame_count++); + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + } + else + { + DEBUG_PRINT_LOW("\n Last frame in else dest addr") ; + generate_ebd = OMX_FALSE; + } + } + if(generate_ebd) + { + DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame); + m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); + psource_frame = NULL; + + if (m_input_pending_q.m_size) + { + DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame, + psource_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu", + psource_frame->nFlags,psource_frame->nFilledLen); + } + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) +{ + OMX_U32 partial_frame = 1; + unsigned address = 0, p2 = 0, id = 0; + OMX_BOOL isNewFrame = OMX_FALSE; + OMX_BOOL generate_ebd = OMX_TRUE; + + if (h264_scratch.pBuffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu " + "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); + DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen); + if (h264_scratch.nFilledLen && look_ahead_nal) + { + look_ahead_nal = false; + if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame"); + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + if (nal_length == 0) + { + DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code"); + if (m_frame_parser.parse_sc_frame(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); + return OMX_ErrorBadParameter; + } + } + else + { + DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); + if (m_frame_parser.parse_h264_nallength(psource_frame, + &h264_scratch,&partial_frame) == -1) + { + DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); + return OMX_ErrorBadParameter; + } + } + + if (partial_frame == 0) + { + if (nal_count == 0 && h264_scratch.nFilledLen == 0) + { + DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip"); + nal_count++; + h264_scratch.nTimeStamp = psource_frame->nTimeStamp; + h264_scratch.nFlags = psource_frame->nFlags; + } + else + { + DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen); + if(h264_scratch.nFilledLen) + { + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, + NALU_TYPE_SPS); +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, + h264_scratch.nFilledLen, NALU_TYPE_SEI); + else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + // If timeinfo is present frame info from SEI is already processed + h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, + h264_scratch.nFilledLen, NALU_TYPE_SEI); +#endif + m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); + nal_count++; + if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { + pdest_frame->nTimeStamp = h264_last_au_ts; + pdest_frame->nFlags = h264_last_au_flags; +#ifdef PANSCAN_HDLR + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + h264_parser->update_panscan_data(h264_last_au_ts); +#endif + } + if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || + m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { + h264_last_au_ts = h264_scratch.nTimeStamp; + h264_last_au_flags = h264_scratch.nFlags; +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); + if (!VALID_TS(h264_last_au_ts)) + h264_last_au_ts = ts_in_sei; + } +#endif + } else + h264_last_au_ts = LLONG_MAX; + } + + if (!isNewFrame) + { + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu", + h264_scratch.nFilledLen); + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) + pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + else + { + look_ahead_nal = true; + DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d", + pdest_frame->nFilledLen,frame_count++); + + if (pdest_frame->nFilledLen == 0) + { + DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it"); + look_ahead_nal = false; + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + } + else + { + if(psource_frame->nFilledLen || h264_scratch.nFilledLen) + { + DEBUG_PRINT_LOW("\n Reset the EOS Flag"); + pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; + } + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + //frame_count++; + pdest_frame = NULL; + if (m_input_free_q.m_size) + { + m_input_free_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame); + pdest_frame->nFilledLen = 0; + pdest_frame->nFlags = 0; + pdest_frame->nTimeStamp = LLONG_MAX; + } + } + } + } + } + else + { + DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen); + /*Check if Destination Buffer is full*/ + if (h264_scratch.nAllocLen == + h264_scratch.nFilledLen + h264_scratch.nOffset) + { + DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); + return OMX_ErrorStreamCorrupt; + } + } + + if (!psource_frame->nFilledLen) + { + DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame); + + if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) + { + if (pdest_frame) + { + DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer"); + if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= + h264_scratch.nFilledLen) + { + memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), + h264_scratch.pBuffer,h264_scratch.nFilledLen); + pdest_frame->nFilledLen += h264_scratch.nFilledLen; + h264_scratch.nFilledLen = 0; + } + else + { + DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264"); + return OMX_ErrorBadParameter; + } + pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; + pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; + + DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx", + pdest_frame->nFilledLen,pdest_frame->nTimeStamp); + DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++); +#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT + if (client_extradata & OMX_TIMEINFO_EXTRADATA) + { + OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); + if (!VALID_TS(pdest_frame->nTimeStamp)) + pdest_frame->nTimeStamp = ts_in_sei; + } +#endif + /*Push the frame to the Decoder*/ + if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) + { + return OMX_ErrorBadParameter; + } + frame_count++; + pdest_frame = NULL; + } + else + { + DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu", + pdest_frame,h264_scratch.nFilledLen); + generate_ebd = OMX_FALSE; + } + } + } + if(generate_ebd && !psource_frame->nFilledLen) + { + m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); + psource_frame = NULL; + if (m_input_pending_q.m_size) + { + DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); + m_input_pending_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE *) address; + DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu", + psource_frame->nFlags,psource_frame->nFilledLen); + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) +{ + OMX_U8 *buf, *pdest; + OMX_U32 partial_frame = 1; + OMX_U32 buf_len, dest_len; + + if(first_frame == 0) + { + first_frame = 1; + DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n"); + if(!m_vendor_config.pData) + { + DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n"); + buf = psource_frame->pBuffer; + buf_len = psource_frame->nFilledLen; + + if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == + VC1_SP_MP_START_CODE) + { + m_vc1_profile = VC1_SP_MP_RCV; + } + else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) + { + m_vc1_profile = VC1_AP; + } + else + { + DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n"); + return OMX_ErrorStreamCorrupt; + } + } + else + { + pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + + pdest_frame->nOffset; + dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + + pdest_frame->nOffset); + + if(dest_len < m_vendor_config.nDataSize) + { + DEBUG_PRINT_ERROR("\nDestination buffer full\n"); + return OMX_ErrorBadParameter; + } + else + { + memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); + pdest_frame->nFilledLen += m_vendor_config.nDataSize; + } + } + } + + switch(m_vc1_profile) + { + case VC1_AP: + DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code"); + if (push_input_sc_codec(hComp) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); + return OMX_ErrorBadParameter; + } + break; + + case VC1_SP_MP_RCV: + default: + DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n"); + return OMX_ErrorBadParameter; + } + return OMX_ErrorNone; +} + +#ifndef USE_ION +bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, + OMX_U32 alignment) +{ + struct pmem_allocation allocation; + allocation.size = buffer_size; + allocation.align = clip2(alignment); + if (allocation.align < 4096) + { + allocation.align = 4096; + } + if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) + { + DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", + allocation.align, allocation.size); + return false; + } + return true; +} +#endif +#ifdef USE_ION +int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, + OMX_U32 alignment, struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data, int flag) +{ + int fd = -EINVAL; + int rc = -EINVAL; + int ion_dev_flag; + struct vdec_ion ion_buf_info; + if (!alloc_data || buffer_size <= 0 || !fd_data) { + DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n"); + return -EINVAL; + } + ion_dev_flag = O_RDONLY; + fd = open (MEM_DEVICE, ion_dev_flag); + if (fd < 0) { + DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd); + return fd; + } + alloc_data->flags = 0; + if(!secure_mode && (flag & ION_FLAG_CACHED)) + { + alloc_data->flags |= ION_FLAG_CACHED; + } + alloc_data->len = buffer_size; + alloc_data->align = clip2(alignment); + if (alloc_data->align < 4096) + { + alloc_data->align = 4096; + } + if ((secure_mode) && (flag & ION_SECURE)) + alloc_data->flags |= ION_SECURE; + + alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); + if (secure_mode) + alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); + rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); + if (rc || !alloc_data->handle) { + DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); + alloc_data->handle = NULL; + close(fd); + fd = -ENOMEM; + return fd; + } + fd_data->handle = alloc_data->handle; + rc = ioctl(fd,ION_IOC_MAP,fd_data); + if (rc) { + DEBUG_PRINT_ERROR("\n ION MAP failed "); + ion_buf_info.ion_alloc_data = *alloc_data; + ion_buf_info.ion_device_fd = fd; + ion_buf_info.fd_ion_data = *fd_data; + free_ion_memory(&ion_buf_info); + fd_data->fd =-1; + close(fd); + fd = -ENOMEM; + } + + return fd; +} + +void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) { + + if(!buf_ion_info) { + DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata"); + return; + } + if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, + &buf_ion_info->ion_alloc_data.handle)) { + DEBUG_PRINT_ERROR("\n ION: free failed" ); + } + close(buf_ion_info->ion_device_fd); + buf_ion_info->ion_device_fd = -1; + buf_ion_info->ion_alloc_data.handle = NULL; + buf_ion_info->fd_ion_data.fd = -1; +} +#endif +void omx_vdec::free_output_buffer_header() +{ + DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released"); + output_use_buffer = false; + ouput_egl_buffers = false; + + if (m_out_mem_ptr) + { + free (m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + + if(m_platform_list) + { + free(m_platform_list); + m_platform_list = NULL; + } + + if (drv_ctx.ptr_respbuffer) + { + free (drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } + if (drv_ctx.ptr_outputbuffer) + { + free (drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif +} + +void omx_vdec::free_input_buffer_header() +{ + input_use_buffer = false; + if (arbitrary_bytes) + { + if (m_frame_parser.mutils) + { + DEBUG_PRINT_LOW("\n Free utils parser"); + delete (m_frame_parser.mutils); + m_frame_parser.mutils = NULL; + } + + if (m_inp_heap_ptr) + { + DEBUG_PRINT_LOW("\n Free input Heap Pointer"); + free (m_inp_heap_ptr); + m_inp_heap_ptr = NULL; + } + + if (m_phdr_pmem_ptr) + { + DEBUG_PRINT_LOW("\n Free input pmem header Pointer"); + free (m_phdr_pmem_ptr); + m_phdr_pmem_ptr = NULL; + } + } + if (m_inp_mem_ptr) + { + DEBUG_PRINT_LOW("\n Free input pmem Pointer area"); + free (m_inp_mem_ptr); + m_inp_mem_ptr = NULL; + } + if (drv_ctx.ptr_inputbuffer) + { + DEBUG_PRINT_LOW("\n Free Driver Context pointer"); + free (drv_ctx.ptr_inputbuffer); + drv_ctx.ptr_inputbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.ip_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free ion context"); + free(drv_ctx.ip_buf_ion_info); + drv_ctx.ip_buf_ion_info = NULL; + } +#endif +} + +int omx_vdec::stream_off(OMX_U32 port) +{ + enum v4l2_buf_type btype; + int rc = 0; + enum v4l2_ports v4l2_port = OUTPUT_PORT; + + if (port == OMX_CORE_INPUT_PORT_INDEX) { + btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + v4l2_port = OUTPUT_PORT; + } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { + btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + v4l2_port = CAPTURE_PORT; + } else if (port == OMX_ALL) { + int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); + int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); + + if (!rc_input) + return rc_input; + else + return rc_output; + } + + if (!streaming[v4l2_port]) { + // already streamed off, warn and move on + DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," + " which is already streamed off", v4l2_port); + return 0; + } + + DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); + + rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); + if (rc) { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port); + } else { + streaming[v4l2_port] = false; + } + + return rc; +} + +OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_requestbuffers bufreq; + unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; + struct v4l2_format fmt; + int ret = 0; + DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 1; + if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.pixelformat = output_capability; + }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.pixelformat = capture_capability; + }else {eRet = OMX_ErrorBadParameter;} + if(eRet==OMX_ErrorNone){ + ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); + } + if(ret) + { + DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); + /*TODO: How to handle this case */ + eRet = OMX_ErrorInsufficientResources; + return eRet; + } + else + { + buffer_prop->actualcount = bufreq.count; + buffer_prop->mincount = bufreq.count; + DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count); + } + DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); + + update_resolution(fmt.fmt.pix_mp.width, + fmt.fmt.pix_mp.height, + fmt.fmt.pix_mp.plane_fmt[0].bytesperline, + fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); + if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) + drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; + DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); + + if(ret) + { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + int extra_idx = 0; + + eRet = is_video_session_supported(); + if (eRet) + return eRet; + + buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + buf_size = buffer_prop->buffer_size; + extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + if (client_extradata & OMX_FRAMEINFO_EXTRADATA) + { + DEBUG_PRINT_HIGH("Frame info extra data enabled!"); + client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; + } + if (client_extradata & OMX_INTERLACE_EXTRADATA) + { + client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; + } + if (client_extradata & OMX_PORTDEF_EXTRADATA) + { + client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; + DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n", + client_extra_data_size); + } + if (client_extra_data_size) + { + client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator + buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit + } + drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size; + drv_ctx.extradata_info.count = buffer_prop->actualcount; + drv_ctx.extradata_info.buffer_size = extra_data_size; + buf_size += client_extra_data_size; + buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); + DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size, buf_size); + if (in_reconfig) // BufReq will be set to driver when port is disabled + buffer_prop->buffer_size = buf_size; + else if (buf_size != buffer_prop->buffer_size) + { + buffer_prop->buffer_size = buf_size; + eRet = set_buffer_req(buffer_prop); + } + } + DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + return eRet; +} + +OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned buf_size = 0; + struct v4l2_format fmt; + struct v4l2_requestbuffers bufreq; + int ret; + DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", + buffer_prop->actualcount, buffer_prop->buffer_size); + buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); + if (buf_size != buffer_prop->buffer_size) + { + DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", + buffer_prop->buffer_size, buf_size); + eRet = OMX_ErrorBadParameter; + } + else + { + fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; + fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; + + if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ + fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.pixelformat = output_capability; + } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.pixelformat = capture_capability; + } else {eRet = OMX_ErrorBadParameter;} + + ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); + if (ret) + { + /*TODO: How to handle this case */ + DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); + eRet = OMX_ErrorInsufficientResources; + } + + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = buffer_prop->actualcount; + if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + } else {eRet = OMX_ErrorBadParameter;} + + if (eRet==OMX_ErrorNone) { + ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); + } + + if (ret) + { + DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); + /*TODO: How to handle this case */ + eRet = OMX_ErrorInsufficientResources; + } else if (bufreq.count < buffer_prop->actualcount) { + DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" + " on v4l2 port %d to %d (prefers %d)", bufreq.type, + buffer_prop->actualcount, bufreq.count); + eRet = OMX_ErrorInsufficientResources; + } else { + if (!client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); + eRet = OMX_ErrorInsufficientResources; + } + } + } + return eRet; +} + +OMX_ERRORTYPE omx_vdec::update_picture_resolution() +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + return eRet; +} + +OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (!portDefn) + { + return OMX_ErrorBadParameter; + } + DEBUG_PRINT_LOW("omx_vdec::update_portdef\n"); + portDefn->nVersion.nVersion = OMX_SPEC_VERSION; + portDefn->nSize = sizeof(portDefn); + portDefn->eDomain = OMX_PortDomainVideo; + if (drv_ctx.frame_rate.fps_denominator > 0) + portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / + drv_ctx.frame_rate.fps_denominator; + else { + DEBUG_PRINT_ERROR("Error: Divide by zero \n"); + return OMX_ErrorBadParameter; + } + if (0 == portDefn->nPortIndex) + { + portDefn->eDir = OMX_DirInput; + portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; + portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; + portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; + portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; + portDefn->format.video.eCompressionFormat = eCompressionFormat; + portDefn->bEnabled = m_inp_bEnabled; + portDefn->bPopulated = m_inp_bPopulated; + } + else if (1 == portDefn->nPortIndex) + { + unsigned int buf_size = 0; + if (!client_buffers.update_buffer_req()) { + DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed"); + return OMX_ErrorHardware; + } + if (!client_buffers.get_buffer_req(buf_size)) { + DEBUG_PRINT_ERROR("\n update buffer requirements"); + return OMX_ErrorHardware; + } + portDefn->nBufferSize = buf_size; + portDefn->eDir = OMX_DirOutput; + portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; + portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; + portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + portDefn->bEnabled = m_out_bEnabled; + portDefn->bPopulated = m_out_bPopulated; + if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { + DEBUG_PRINT_ERROR("\n Error in getting color format"); + return OMX_ErrorHardware; + } + } + else + { + portDefn->eDir = OMX_DirMax; + DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; + portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; + portDefn->format.video.nStride = drv_ctx.video_resolution.stride; + portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; + DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld" + " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight, + portDefn->format.video.nStride, + portDefn->format.video.nSliceHeight); + return eRet; + +} + +OMX_ERRORTYPE omx_vdec::allocate_output_headers() +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr = NULL; + unsigned i= 0; + + if(!m_out_mem_ptr) { + DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation"); + int nBufHdrSize = 0; + int nPlatformEntrySize = 0; + int nPlatformListSize = 0; + int nPMEMInfoSize = 0; + OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; + OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; + + DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n", + drv_ctx.op_buf.actualcount); + nBufHdrSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_BUFFERHEADERTYPE); + + nPMEMInfoSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); + nPlatformListSize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); + nPlatformEntrySize = drv_ctx.op_buf.actualcount * + sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); + + DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, + sizeof(OMX_BUFFERHEADERTYPE), + nPMEMInfoSize, + nPlatformListSize); + DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize, + m_out_bm_count); + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + // Alloc mem for platform specific info + char *pPtr=NULL; + pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + + nPMEMInfoSize,1); + drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ + calloc (sizeof(struct vdec_bufferpayload), + drv_ctx.op_buf.actualcount); + drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ + calloc (sizeof (struct vdec_output_frameinfo), + drv_ctx.op_buf.actualcount); +#ifdef USE_ION + drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ + calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); +#endif + + if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer + && drv_ctx.ptr_respbuffer) + { + bufHdr = m_out_mem_ptr; + m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); + m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) + (((char *) m_platform_list) + nPlatformListSize); + m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + (((char *) m_platform_entry) + nPlatformEntrySize); + pPlatformList = m_platform_list; + pPlatformEntry = m_platform_entry; + pPMEMInfo = m_pmem_info; + + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); + + // Settting the entire storage nicely + DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, + m_out_mem_ptr,pPlatformEntry); + DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); + for(i=0; i < drv_ctx.op_buf.actualcount ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = 0; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = NULL; + bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pPlatformEntry->entry = pPMEMInfo; + // Initialize the Platform List + pPlatformList->nEntries = 1; + pPlatformList->entryList = pPlatformEntry; + // Keep pBuffer NULL till vdec is opened + bufHdr->pBuffer = NULL; + pPMEMInfo->offset = 0; + pPMEMInfo->pmem_fd = 0; + bufHdr->pPlatformPrivate = pPlatformList; + drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; +#ifdef USE_ION + drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; +#endif + /*Create a mapping between buffers*/ + bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; + drv_ctx.ptr_respbuffer[i].client_data = (void *) \ + &drv_ctx.ptr_outputbuffer[i]; + // Move the buffer and buffer header pointers + bufHdr++; + pPMEMInfo++; + pPlatformEntry++; + pPlatformList++; + } + } + else + { + DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ + m_out_mem_ptr, pPtr); + if(m_out_mem_ptr) + { + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(pPtr) + { + free(pPtr); + pPtr = NULL; + } + if(drv_ctx.ptr_outputbuffer) + { + free(drv_ctx.ptr_outputbuffer); + drv_ctx.ptr_outputbuffer = NULL; + } + if(drv_ctx.ptr_respbuffer) + { + free(drv_ctx.ptr_respbuffer); + drv_ctx.ptr_respbuffer = NULL; + } +#ifdef USE_ION + if (drv_ctx.op_buf_ion_info) { + DEBUG_PRINT_LOW("\n Free o/p ion context"); + free(drv_ctx.op_buf_ion_info); + drv_ctx.op_buf_ion_info = NULL; + } +#endif + eRet = OMX_ErrorInsufficientResources; + } + } else { + eRet = OMX_ErrorInsufficientResources; + } + return eRet; +} + +void omx_vdec::complete_pending_buffer_done_cbs() +{ + unsigned p1; + unsigned p2; + unsigned ident; + omx_cmd_queue tmp_q, pending_bd_q; + pthread_mutex_lock(&m_lock); + // pop all pending GENERATE FDB from ftb queue + while (m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_FBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to ftb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_ftb_q.insert_entry(p1,p2,ident); + } + // pop all pending GENERATE EDB from etb queue + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_EBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to etb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_etb_q.insert_entry(p1,p2,ident); + } + pthread_mutex_unlock(&m_lock); + // process all pending buffer dones + while(pending_bd_q.m_size) + { + pending_bd_q.pop_entry(&p1,&p2,&ident); + switch(ident) + { + case OMX_COMPONENT_GENERATE_EBD: + if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); + omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FBD: + if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); + omx_report_error (); + } + break; + } + } +} + +void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) +{ + OMX_U32 new_frame_interval = 0; + if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts + && llabs(act_timestamp - prev_ts) > 2000) + { + new_frame_interval = client_set_fps ? frm_int : + llabs(act_timestamp - prev_ts); + if (new_frame_interval < frm_int || frm_int == 0) + { + frm_int = new_frame_interval; + if(frm_int) + { + drv_ctx.frame_rate.fps_numerator = 1e6; + drv_ctx.frame_rate.fps_denominator = frm_int; + DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)", + frm_int, drv_ctx.frame_rate.fps_numerator / + (float)drv_ctx.frame_rate.fps_denominator); + + /* We need to report the difference between this FBD and the previous FBD + * back to the driver for clock scaling purposes. */ + struct v4l2_outputparm oparm; + /*XXX: we're providing timing info as seconds per frame rather than frames + * per second.*/ + oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; + oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; + + struct v4l2_streamparm sparm; + sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + sparm.parm.output = oparm; + if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) + { + DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ + performance might be affected"); + } + + } + } + } + prev_ts = act_timestamp; +} + +void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) +{ + if (rst_prev_ts && VALID_TS(act_timestamp)) + { + prev_ts = act_timestamp; + rst_prev_ts = false; + } + else if (VALID_TS(prev_ts)) + { + bool codec_cond = (drv_ctx.timestamp_adjust)? + (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? + (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): + (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); + if(frm_int > 0 && codec_cond) + { + DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); + act_timestamp = prev_ts + frm_int; + DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); + prev_ts = act_timestamp; + } + else + set_frame_rate(act_timestamp); + } + else if (frm_int > 0) // In this case the frame rate was set along + { // with the port definition, start ts with 0 + act_timestamp = prev_ts = 0; // and correct if a valid ts is received. + rst_prev_ts = true; + } +} + +void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) +{ + OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; + OMX_U32 num_conceal_MB = 0; + OMX_U32 frame_rate = 0; + int consumed_len = 0; + OMX_U32 num_MB_in_frame; + OMX_U32 recovery_sei_flags = 1; + int enable = 0; + OMX_U32 mbaff = 0; + int buf_index = p_buf_hdr - m_out_mem_ptr; + struct msm_vidc_panscan_window_payload *panscan_payload = NULL; + OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) + + p_buf_hdr->nOffset; + if (!drv_ctx.extradata_info.uaddr) { + return; + } + p_extra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); + char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; + if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) + p_extra = NULL; + OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; + if (data) { + while((consumed_len < drv_ctx.extradata_info.buffer_size) + && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) { + if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) { + DEBUG_PRINT_LOW("Invalid extra data size"); + break; + } + switch((unsigned long)data->eType) { + case EXTRADATA_INTERLACE_VIDEO: + struct msm_vidc_interlace_payload *payload; + payload = (struct msm_vidc_interlace_payload *)data->data; + mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; + if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; + else { + drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; + enable = 1; + } + if(m_enable_android_native_buffers) + setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, + PP_PARAM_INTERLACED, (void*)&enable); + if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) { + append_interlace_extradata(p_extra, payload->format); + p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); + } + break; + case EXTRADATA_FRAME_RATE: + struct msm_vidc_framerate_payload *frame_rate_payload; + frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data; + frame_rate = frame_rate_payload->frame_rate; + break; + case EXTRADATA_TIMESTAMP: + struct msm_vidc_ts_payload *time_stamp_payload; + time_stamp_payload = (struct msm_vidc_ts_payload *)data->data; + p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo; + p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); + break; + case EXTRADATA_NUM_CONCEALED_MB: + struct msm_vidc_concealmb_payload *conceal_mb_payload; + conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data; + num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * + (drv_ctx.video_resolution.frame_height + 15)) >> 8; + num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); + break; + case EXTRADATA_INDEX: + int *etype; + etype = (int *)(data->data); + if (etype && *etype == EXTRADATA_ASPECT_RATIO) { + struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; + aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype); + if (aspect_ratio_payload) { + ((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; + ((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; + } + } + break; + case EXTRADATA_RECOVERY_POINT_SEI: + struct msm_vidc_recoverysei_payload *recovery_sei_payload; + recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data; + recovery_sei_flags = recovery_sei_payload->flags; + if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; + DEBUG_PRINT_HIGH("\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); + DEBUG_PRINT_HIGH("***************************************************\n"); + } + break; + case EXTRADATA_PANSCAN_WINDOW: + panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data; + break; + case EXTRADATA_MPEG2_SEQDISP: + struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload; + seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data; + if (seqdisp_payload) { + m_disp_hor_size = seqdisp_payload->disp_width; + m_disp_vert_size = seqdisp_payload->disp_height; + } + break; + default: + goto unrecognized_extradata; + } + consumed_len += data->nSize; + data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); + } + if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) { + p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; + append_frame_info_extradata(p_extra, + num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, + panscan_payload,&((struct vdec_output_frameinfo *) + p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);} + } +unrecognized_extradata: + if(!secure_mode && client_extradata) + append_terminator_extradata(p_extra); + return; +} + +OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, + bool is_internal, bool enable) +{ + OMX_ERRORTYPE ret = OMX_ErrorNone; + struct v4l2_control control; + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); + return OMX_ErrorIncorrectStateOperation; + } + DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n", + client_extradata, requested_extradata, enable, is_internal); + + if (!is_internal) { + if (enable) + client_extradata |= requested_extradata; + else + client_extradata = client_extradata & ~requested_extradata; + } + + if (enable) { + if (requested_extradata & OMX_INTERLACE_EXTRADATA) { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set interlaced extradata." + " Quality of interlaced clips might be impacted.\n"); + } + } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) + { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set framerate extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); + } + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); + } + if (output_capability == V4L2_PIX_FMT_MPEG2) + { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); + } + } + } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) + { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; + if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n"); + } + } + } + ret = get_buffer_req(&drv_ctx.op_buf); + return ret; +} + +OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; + OMX_U8 *data_ptr = extra->data, data = 0; + while (byte_count < extra->nDataSize) + { + data = *data_ptr; + while (data) + { + num_MB += (data&0x01); + data >>= 1; + } + data_ptr++; + byte_count++; + } + num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * + (drv_ctx.video_resolution.frame_height + 15)) >> 8; + return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); +} + +void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + if (!m_debug_extradata) + return; + + DEBUG_PRINT_HIGH( + "============== Extra Data ==============\n" + " Size: %lu \n" + " Version: %lu \n" + " PortIndex: %lu \n" + " Type: %x \n" + " DataSize: %lu \n", + extra->nSize, extra->nVersion.nVersion, + extra->nPortIndex, extra->eType, extra->nDataSize); + + if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) + { + OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; + DEBUG_PRINT_HIGH( + "------ Interlace Format ------\n" + " Size: %lu \n" + " Version: %lu \n" + " PortIndex: %lu \n" + " Is Interlace Format: %d \n" + " Interlace Formats: %lu \n" + "=========== End of Interlace ===========\n", + intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, + intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); + } + else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) + { + OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; + + DEBUG_PRINT_HIGH( + "-------- Frame Format --------\n" + " Picture Type: %d \n" + " Interlace Type: %d \n" + " Pan Scan Total Frame Num: %lu \n" + " Concealed Macro Blocks: %lu \n" + " frame rate: %lu \n" + " Aspect Ratio X: %lu \n" + " Aspect Ratio Y: %lu \n", + fminfo->ePicType, + fminfo->interlaceType, + fminfo->panScan.numWindows, + fminfo->nConcealedMacroblocks, + fminfo->nFrameRate, + fminfo->aspectRatio.aspectRatioX, + fminfo->aspectRatio.aspectRatioY); + + for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) + { + DEBUG_PRINT_HIGH( + "------------------------------\n" + " Pan Scan Frame Num: %lu \n" + " Rectangle x: %ld \n" + " Rectangle y: %ld \n" + " Rectangle dx: %ld \n" + " Rectangle dy: %ld \n", + i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, + fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); + } + + DEBUG_PRINT_HIGH("========= End of Frame Format =========="); + } + else if (extra->eType == OMX_ExtraDataNone) + { + DEBUG_PRINT_HIGH("========== End of Terminator ==========="); + } + else + { + DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); + } +} + +void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 interlaced_format_type) +{ + OMX_STREAMINTERLACEFORMAT *interlace_format; + OMX_U32 mbaff = 0; + if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { + return; + } + extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; + extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); + interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; + interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); + interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; + interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; + if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) + { + interlace_format->bInterlaceFormat = OMX_FALSE; + interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; + drv_ctx.interlace = VDEC_InterlaceFrameProgressive; + } + else + { + interlace_format->bInterlaceFormat = OMX_TRUE; + interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; + drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; + } + print_debug_extradata(extra); +} + +void omx_vdec::fill_aspect_ratio_info( + struct vdec_aspectratioinfo *aspect_ratio_info, + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) +{ + m_extradata = frame_info; + m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; + m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; + DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX, + m_extradata->aspectRatio.aspectRatioY); +} + +void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, + OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate, + struct msm_vidc_panscan_window_payload *panscan_payload, + struct vdec_aspectratioinfo *aspect_ratio_info) +{ + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; + struct msm_vidc_panscan_window *panscan_window; + if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { + return; + } + extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; + extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); + frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; + switch (picture_type) + { + case PICTURE_TYPE_I: + frame_info->ePicType = OMX_VIDEO_PictureTypeI; + break; + case PICTURE_TYPE_P: + frame_info->ePicType = OMX_VIDEO_PictureTypeP; + break; + case PICTURE_TYPE_B: + frame_info->ePicType = OMX_VIDEO_PictureTypeB; + break; + default: + frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; + } + if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) + frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; + else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) + frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; + else + frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; + memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); + frame_info->nConcealedMacroblocks = num_conceal_mb; + frame_info->nFrameRate = frame_rate; + frame_info->panScan.numWindows = 0; + if (output_capability == V4L2_PIX_FMT_MPEG2) + { + if (m_disp_hor_size && m_disp_vert_size) + { + frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size; + frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size; + } + } + + if(panscan_payload) { + frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; + panscan_window = &panscan_payload->wnd[0]; + for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) + { + frame_info->panScan.window[i].x = panscan_window->panscan_window_width; + frame_info->panScan.window[i].y = panscan_window->panscan_window_height; + frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; + frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; + panscan_window++; + } + } + fill_aspect_ratio_info(aspect_ratio_info, frame_info); + print_debug_extradata(extra); +} + +void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; + extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; + extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; + *portDefn = m_port_def; + DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu " + "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight, + portDefn->format.video.nFrameWidth, + portDefn->format.video.nStride, + portDefn->format.video.nSliceHeight); +} + +void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) +{ + if (!client_extradata) { + return; + } + extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); + extra->nVersion.nVersion = OMX_SPEC_VERSION; + extra->eType = OMX_ExtraDataNone; + extra->nDataSize = 0; + extra->data[0] = 0; + + print_debug_extradata(extra); +} + +OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (index >= drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found"); + return OMX_ErrorInsufficientResources; + } + if (m_desc_buffer_ptr == NULL) + { + m_desc_buffer_ptr = (desc_buffer_hdr*) \ + calloc( (sizeof(desc_buffer_hdr)), + drv_ctx.ip_buf.actualcount); + if (m_desc_buffer_ptr == NULL) + { + DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + } + + m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); + if (m_desc_buffer_ptr[index].buf_addr == NULL) + { + DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed "); + return OMX_ErrorInsufficientResources; + } + + return eRet; +} + +void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) +{ + DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries); + if (m_demux_entries < 8192) + { + m_demux_offsets[m_demux_entries++] = address_offset; + } + return; +} + +void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) +{ + OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; + OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; + OMX_U32 index = 0; + + m_demux_entries = 0; + + while (index < bytes_to_parse) + { + if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && + (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || + ((buf[index] == 0x00) && (buf[index+1] == 0x00) && + (buf[index+2] == 0x01)) ) + { + //Found start code, insert address offset + insert_demux_addr_offset(index); + if (buf[index+2] == 0x01) // 3 byte start code + index += 3; + else //4 byte start code + index += 4; + } + else + index++; + } + DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries); + return; +} + +OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) +{ + //fix this, handle 3 byte start code, vc1 terminator entry + OMX_U8 *p_demux_data = NULL; + OMX_U32 desc_data = 0; + OMX_U32 start_addr = 0; + OMX_U32 nal_size = 0; + OMX_U32 suffix_byte = 0; + OMX_U32 demux_index = 0; + OMX_U32 buffer_index = 0; + + if (m_desc_buffer_ptr == NULL) + { + DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); + return OMX_ErrorBadParameter; + } + + buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + if (buffer_index > drv_ctx.ip_buf.actualcount) + { + DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index); + return OMX_ErrorBadParameter; + } + + p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; + + if ( ((OMX_U8*)p_demux_data == NULL) || + ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) + { + DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); + return OMX_ErrorBadParameter; + } + else + { + for (; demux_index < m_demux_entries; demux_index++) + { + desc_data = 0; + start_addr = m_demux_offsets[demux_index]; + if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) + { + suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; + } + else + { + suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; + } + if (demux_index < (m_demux_entries - 1)) + { + nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; + } + else + { + nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; + } + DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)", + (void *)start_addr, + suffix_byte, + nal_size, + demux_index); + desc_data = (start_addr >> 3) << 1; + desc_data |= (start_addr & 7) << 21; + desc_data |= suffix_byte << 24; + + memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); + memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); + memset(p_demux_data + 8, 0, sizeof(OMX_U32)); + memset(p_demux_data + 12, 0, sizeof(OMX_U32)); + + p_demux_data += 16; + } + if (codec_type_parse == CODEC_TYPE_VC1) + { + DEBUG_PRINT_LOW("VC1 terminator entry"); + desc_data = 0; + desc_data = 0x82 << 24; + memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); + memset(p_demux_data + 4, 0, sizeof(OMX_U32)); + memset(p_demux_data + 8, 0, sizeof(OMX_U32)); + memset(p_demux_data + 12, 0, sizeof(OMX_U32)); + p_demux_data += 16; + m_demux_entries++; + } + //Add zero word to indicate end of descriptors + memset(p_demux_data, 0, sizeof(OMX_U32)); + + m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); + DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size); + } + memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); + m_demux_entries = 0; + DEBUG_PRINT_LOW("Demux table complete!"); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_vdec::createDivxDrmContext() +{ + OMX_ERRORTYPE err = OMX_ErrorNone; + iDivXDrmDecrypt = DivXDrmDecrypt::Create(); + if (iDivXDrmDecrypt) { + OMX_ERRORTYPE err = iDivXDrmDecrypt->Init(); + if(err!=OMX_ErrorNone) { + DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err); + delete iDivXDrmDecrypt; + iDivXDrmDecrypt = NULL; + } + } + else { + DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM"); + err = OMX_ErrorUndefined; + } + return err; +} + +omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() +{ + enabled = false; + omx = NULL; + init_members(); + ColorFormat = OMX_COLOR_FormatMax; +} + +void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) +{ + omx = reinterpret_cast(client); +} + +void omx_vdec::allocate_color_convert_buf::init_members() { + allocated_count = 0; + buffer_size_req = 0; + buffer_alignment_req = 0; + memset(m_platform_list_client,0,sizeof(m_platform_list_client)); + memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); + memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); + memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); +#ifdef USE_ION + memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); +#endif + for (int i = 0; i < MAX_COUNT;i++) + pmem_fd[i] = -1; +} + +omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() { + c2d.destroy(); +} + +bool omx_vdec::allocate_color_convert_buf::update_buffer_req() +{ + bool status = true; + unsigned int src_size = 0, destination_size = 0; + OMX_COLOR_FORMATTYPE drv_color_format; + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid client in color convert"); + return false; + } + if (!enabled){ + DEBUG_PRINT_ERROR("\n No color conversion required"); + return status; + } + pthread_mutex_lock(&omx->c_lock); + if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && + ColorFormat != OMX_COLOR_FormatYUV420Planar) { + DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion"); + status = false; + goto fail_update_buf_req; + } + c2d.close(); + status = c2d.open(omx->drv_ctx.video_resolution.frame_height, + omx->drv_ctx.video_resolution.frame_width, + NV12_128m,YCbCr420P); + if (status) { + status = c2d.get_buffer_size(C2D_INPUT,src_size); + if (status) + status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); + } + if (status) { + if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || + !destination_size) { + DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d" + "driver size %d destination size %d", + src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); + status = false; + c2d.close(); + buffer_size_req = 0; + } else { + buffer_size_req = destination_size; + if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) + buffer_size_req = omx->drv_ctx.op_buf.buffer_size; + if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) + buffer_alignment_req = omx->drv_ctx.op_buf.alignment; + } + } +fail_update_buf_req: + pthread_mutex_unlock(&omx->c_lock); + return status; +} + +bool omx_vdec::allocate_color_convert_buf::set_color_format( + OMX_COLOR_FORMATTYPE dest_color_format) +{ + bool status = true; + OMX_COLOR_FORMATTYPE drv_color_format; + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid client in color convert"); + return false; + } + pthread_mutex_lock(&omx->c_lock); + if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) + drv_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + else { + DEBUG_PRINT_ERROR("\n Incorrect color format"); + status = false; + } + if (status && (drv_color_format != dest_color_format)) { + DEBUG_PRINT_LOW("Enabling C2D\n"); + if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { + DEBUG_PRINT_ERROR("\n Unsupported color format for c2d"); + status = false; + } else { + ColorFormat = OMX_COLOR_FormatYUV420Planar; + if (enabled) + c2d.destroy(); + enabled = false; + if (!c2d.init()) { + DEBUG_PRINT_ERROR("\n open failed for c2d"); + status = false; + } else + enabled = true; + } + } else { + if (enabled) + c2d.destroy(); + enabled = false; + } + pthread_mutex_unlock(&omx->c_lock); + return status; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return omx->m_out_mem_ptr; + return m_out_mem_ptr_client; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr + (OMX_BUFFERHEADERTYPE *bufadd) +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return bufadd; + + unsigned index = 0; + index = bufadd - omx->m_out_mem_ptr; + if (index < omx->drv_ctx.op_buf.actualcount) { + m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); + m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; + bool status; + if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { + pthread_mutex_lock(&omx->c_lock); + status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, + omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index], + pmem_baseaddress[index], pmem_baseaddress[index]); + pthread_mutex_unlock(&omx->c_lock); + m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; + if (!status){ + DEBUG_PRINT_ERROR("\n Failed color conversion %d", status); + m_out_mem_ptr_client[index].nFilledLen = 0; + return &m_out_mem_ptr_client[index]; + } + } else + m_out_mem_ptr_client[index].nFilledLen = 0; + return &m_out_mem_ptr_client[index]; + } + DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr"); + return NULL; +} + +OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr + (OMX_BUFFERHEADERTYPE *bufadd) +{ + if (!omx){ + DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); + return NULL; + } + if (!enabled) + return bufadd; + unsigned index = 0; + index = bufadd - m_out_mem_ptr_client; + if (index < omx->drv_ctx.op_buf.actualcount) { + return &omx->m_out_mem_ptr[index]; + } + DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr"); + return NULL; +} +bool omx_vdec::allocate_color_convert_buf::get_buffer_req + (unsigned int &buffer_size) +{ + bool status = true; + pthread_mutex_lock(&omx->c_lock); + if (!enabled) + buffer_size = omx->drv_ctx.op_buf.buffer_size; + else { + if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { + DEBUG_PRINT_ERROR("\n Get buffer size failed"); + status = false; + goto fail_get_buffer_size; + } + } + if (buffer_size < omx->drv_ctx.op_buf.buffer_size) + buffer_size = omx->drv_ctx.op_buf.buffer_size; + if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) + buffer_alignment_req = omx->drv_ctx.op_buf.alignment; +fail_get_buffer_size: + pthread_mutex_unlock(&omx->c_lock); + return status; +} +OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( + OMX_BUFFERHEADERTYPE *bufhdr) { + unsigned int index = 0; + + if (!enabled) + return omx->free_output_buffer(bufhdr); + if (enabled && omx->is_component_secure()) + return OMX_ErrorNone; + if (!allocated_count || !bufhdr) { + DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr); + return OMX_ErrorBadParameter; + } + index = bufhdr - m_out_mem_ptr_client; + if (index >= omx->drv_ctx.op_buf.actualcount){ + DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer"); + return OMX_ErrorBadParameter; + } + if (pmem_fd[index] > 0) { + munmap(pmem_baseaddress[index], buffer_size_req); + close(pmem_fd[index]); + } + pmem_fd[index] = -1; +#ifdef USE_ION + omx->free_ion_memory(&op_buf_ion_info[index]); +#endif + m_heap_ptr[index].video_heap_ptr = NULL; + if (allocated_count > 0) + allocated_count--; + else + allocated_count = 0; + if (!allocated_count) { + pthread_mutex_lock(&omx->c_lock); + c2d.close(); + init_members(); + pthread_mutex_unlock(&omx->c_lock); + } + return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); +} + +OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if (!enabled){ + eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); + return eRet; + } + if (enabled && omx->is_component_secure()) { + DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d", + omx->is_component_secure()); + return OMX_ErrorUnsupportedSetting; + } + if (!bufferHdr || bytes > buffer_size_req) { + DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr); + DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu", + buffer_size_req,bytes); + return OMX_ErrorBadParameter; + } + if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert"); + return OMX_ErrorInsufficientResources; + } + OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; + eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, + port,appData,omx->drv_ctx.op_buf.buffer_size); + if (eRet != OMX_ErrorNone || !temp_bufferHdr){ + DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert"); + return eRet; + } + if ((temp_bufferHdr - omx->m_out_mem_ptr) >= + omx->drv_ctx.op_buf.actualcount) { + DEBUG_PRINT_ERROR("\n Invalid header index %d", + (temp_bufferHdr - omx->m_out_mem_ptr)); + return OMX_ErrorUndefined; + } + unsigned int i = allocated_count; +#ifdef USE_ION + op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( + buffer_size_req,buffer_alignment_req, + &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, + 0); + pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; + if (op_buf_ion_info[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert"); + return OMX_ErrorInsufficientResources; + } + pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, + PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); + + if (pmem_baseaddress[i] == MAP_FAILED) { + DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req); + close(pmem_fd[i]); + omx->free_ion_memory(&op_buf_ion_info[i]); + return OMX_ErrorInsufficientResources; + } + m_heap_ptr[i].video_heap_ptr = new VideoHeap ( + op_buf_ion_info[i].ion_device_fd,buffer_size_req, + pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); +#endif + m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); + m_pmem_info_client[i].offset = 0; + m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; + m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + m_platform_list_client[i].nEntries = 1; + m_platform_list_client[i].entryList = &m_platform_entry_client[i]; + m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; + m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; + m_out_mem_ptr_client[i].nFilledLen = 0; + m_out_mem_ptr_client[i].nFlags = 0; + m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; + m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); + m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; + m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; + m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; + m_out_mem_ptr_client[i].pAppPrivate = appData; + *bufferHdr = &m_out_mem_ptr_client[i]; + DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr); + allocated_count++; + return eRet; +} + +bool omx_vdec::is_component_secure() +{ + return secure_mode; +} + +bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) +{ + bool status = true; + if (!enabled) { + if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) + dest_color_format = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; + else + status = false; + } else { + if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { + status = false; + } else + dest_color_format = OMX_COLOR_FormatYUV420Planar; + } + return status; +} diff --git a/mm-video-v4l2/vidc/vdec/src/power_module.cpp b/mm-video-v4l2/vidc/vdec/src/power_module.cpp new file mode 100644 index 00000000..38492186 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/power_module.cpp @@ -0,0 +1,54 @@ +/*------------------------------------------------------------------------- +Copyright (c) 2012, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#include "power_module.h" + +PowerModule *PowerModule::mPowerModuleInstance = NULL; + +PowerModule *PowerModule::getInstance() +{ + if (mPowerModuleInstance == NULL) { + mPowerModuleInstance = new PowerModule; + + if (mPowerModuleInstance) { + mPowerModuleInstance->mPowerModuleHandle = NULL; + + hw_get_module(POWER_HARDWARE_MODULE_ID, + (const hw_module_t **)&(mPowerModuleInstance->mPowerModuleHandle)); + } + } + + return mPowerModuleInstance; +} + +power_module_t *PowerModule::getPowerModuleHandle() +{ + return mPowerModuleHandle; +} diff --git a/mm-video-v4l2/vidc/vdec/src/queue.c b/mm-video-v4l2/vidc/vdec/src/queue.c new file mode 100755 index 00000000..368d7c4d --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/queue.c @@ -0,0 +1,128 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +/* + Queue with Linked list +*/ + +#include "queue.h" +#include +#include + + +typedef struct Node +{ + void *element; + struct Node *next; +} Node; + +struct Queue +{ + Node *head; + Node *tail; + int current_size; +}; + +Queue *alloc_queue() +{ + Queue *q = (Queue *) malloc(sizeof(Queue)); + if (q) + { + q->head = q->tail = NULL; + q->current_size = 0; + } + return q; +} + +void free_queue(Queue *q) +{ + while (q->current_size) + { + pop(q); + } +} + +void free_queue_and_qelement(Queue *q) +{ + while (q->current_size) + { + void *element = pop(q); + if (element) + free(element); + } +} + +int push(Queue *q, void * element) +{ + Node *new_node = (Node *) malloc(sizeof(Node)); + + if (new_node == NULL) + return -1; + + new_node->element = element; + new_node->next = NULL; + + if (q->current_size == 0) + { + q->head = new_node; + } + else + { + q->tail->next = new_node; + } + + q->tail = new_node; + q->current_size++; + + return 0; +} + +void *pop(Queue *q) +{ + Node *temp; + void *element; + + if (q->current_size == 0) + return NULL; + + temp = q->head; + element = temp->element; + + if (q->current_size == 1) + { + q->head = q->tail = NULL; + } + else + { + q->head = q->head->next; + } + + free(temp); + q->current_size--; + return element; +} + diff --git a/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp b/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp new file mode 100644 index 00000000..44aa2005 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp @@ -0,0 +1,268 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "ts_parser.h" + +#define DEBUG ALOGE +void omx_time_stamp_reorder::set_timestamp_reorder_mode(bool mode) +{ + reorder_ts = mode; +} + +void omx_time_stamp_reorder::enable_debug_print(bool flag) +{ + print_debug = flag; +} + +omx_time_stamp_reorder::~omx_time_stamp_reorder() +{ + delete_list(); +} + +omx_time_stamp_reorder::omx_time_stamp_reorder() +{ + reorder_ts = false; + phead = pcurrent = NULL; + error = false; + print_debug = false; +} + +void omx_time_stamp_reorder::delete_list() +{ + time_stamp_list *ptemp; + if (!phead) return; + while(phead->next != phead) { + ptemp = phead; + phead = phead->next; + phead->prev = ptemp->prev; + ptemp->prev->next = phead; + delete ptemp; + } + delete phead; + phead = NULL; +} + +bool omx_time_stamp_reorder::get_current_list() +{ + if (!phead) { + if(!add_new_list()) { + handle_error(); + return false; + } + } + pcurrent = phead->prev; + return true; +} + +bool omx_time_stamp_reorder::update_head() +{ + time_stamp_list *ptemp; + if(!phead) return false; + if (phead->next != phead) { + ptemp = phead; + phead = ptemp->next; + phead->prev = ptemp->prev; + ptemp->prev->next = phead; + delete ptemp; + } + return true; +} + +bool omx_time_stamp_reorder::add_new_list() +{ + bool status = true; + time_stamp_list *ptemp = NULL; + if (!phead) { + ptemp = phead = new time_stamp_list; + if (!phead) { + handle_error(); + status = false; + return status; + } + phead->prev = phead->next = phead; + } else { + ptemp = new time_stamp_list; + if (!ptemp) { + handle_error(); + status = false; + return status; + } + ptemp->prev = phead->prev; + ptemp->next = phead; + phead->prev->next = ptemp; + phead->prev = ptemp; + } + ptemp->entries_filled = 0; + for(int i=0; i < TIME_SZ; i++) { + ptemp->input_timestamps[i].in_use = false; + ptemp->input_timestamps[i].timestamps = -1; + } + return status; +} + +bool omx_time_stamp_reorder::insert_timestamp(OMX_BUFFERHEADERTYPE *header) +{ + OMX_TICKS *table_entry = NULL; + if (!reorder_ts || error || !header) { + if (error || !header) + DEBUG("\n Invalid condition in insert_timestamp %p", header); + return false; + } + if(!get_current_list()) { + handle_error(); + return false; + } + if (pcurrent->entries_filled > (TIME_SZ - 1)) { + DEBUG("\n Table full return error"); + handle_error(); + return false; + } + if (header->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { + return true; + } + if ((header->nFlags & OMX_BUFFERFLAG_EOS) && !header->nFilledLen) + { + DEBUG("\n EOS with zero length recieved"); + if (!add_new_list()) { + handle_error(); + return false; + } + return true; + } + for(int i = 0; i < TIME_SZ && !table_entry; i++) { + if (!pcurrent->input_timestamps[i].in_use) { + table_entry = &pcurrent->input_timestamps[i].timestamps; + pcurrent->input_timestamps[i].in_use = true; + pcurrent->entries_filled++; + } + } + if (!table_entry) { + DEBUG("\n All entries in use"); + handle_error(); + return false; + } + *table_entry = header->nTimeStamp; + if (print_debug) + DEBUG("Time stamp inserted %lld", header->nTimeStamp); + if (header->nFlags & OMX_BUFFERFLAG_EOS) { + if (!add_new_list()) { + handle_error(); + return false; + } + } + return true; +} + +bool omx_time_stamp_reorder::remove_time_stamp(OMX_TICKS ts, bool is_interlaced = false) +{ + unsigned int num_ent_remove = (is_interlaced)?2:1; + if (!reorder_ts || error) { + DEBUG("\n not in avi mode"); + return false; + } + if (!phead || !phead->entries_filled) return false; + for(int i=0; i < TIME_SZ && num_ent_remove; i++) { + if (phead->input_timestamps[i].in_use && phead->input_timestamps[i].timestamps == ts) { + phead->input_timestamps[i].in_use = false; + phead->entries_filled--; + num_ent_remove--; + if (print_debug) + DEBUG("Removed TS %lld", ts); + } + } + if (!phead->entries_filled) { + if (!update_head()) { + handle_error(); + return false; + } + } + return true; +} + +void omx_time_stamp_reorder::flush_timestamp() +{ + delete_list(); +} + +bool omx_time_stamp_reorder::get_next_timestamp(OMX_BUFFERHEADERTYPE *header, bool is_interlaced) +{ + timestamp *element = NULL,*duplicate = NULL; + bool status = false; + if (!reorder_ts || error || !header) { + if (error || !header) + DEBUG("\n Invalid condition in insert_timestamp %p", header); + return false; + } + if(!phead || !phead->entries_filled) return false; + for(int i=0; i < TIME_SZ; i++) { + if (phead->input_timestamps[i].in_use) { + status = true; + if (!element) + element = &phead->input_timestamps[i]; + else { + if (element->timestamps > phead->input_timestamps[i].timestamps){ + element = &phead->input_timestamps[i]; + duplicate = NULL; + } else if(element->timestamps == phead->input_timestamps[i].timestamps) + duplicate = &phead->input_timestamps[i]; + } + } + } + if (element) { + phead->entries_filled--; + header->nTimeStamp = element->timestamps; + if (print_debug) + DEBUG("Getnext Time stamp %lld", header->nTimeStamp); + element->in_use = false; + } + if(is_interlaced && duplicate) { + phead->entries_filled--; + duplicate->in_use = false; + } else if (is_interlaced && !duplicate) { + element = NULL; + for(int i=0; i < TIME_SZ; i++) { + if (phead->input_timestamps[i].in_use) { + if (!element) + element = &phead->input_timestamps[i]; + else if (element->timestamps > phead->input_timestamps[i].timestamps) + element = &phead->input_timestamps[i]; + } + } + if (element) { + phead->entries_filled--; + header->nTimeStamp = element->timestamps; + element->in_use = false; + } + } + if (!phead->entries_filled) { + if (!update_head()) { + handle_error(); + return false; + } + } + return status; +} diff --git a/mm-video-v4l2/vidc/vdec/test/decoder_driver_test.c b/mm-video-v4l2/vidc/vdec/test/decoder_driver_test.c new file mode 100755 index 00000000..fe870f82 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/test/decoder_driver_test.c @@ -0,0 +1,1198 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "decoder_driver_test.h" + +#define DEBUG_PRINT printf +/************************************************************************/ +/* #DEFINES */ +/************************************************************************/ + +#define VOP_START_CODE 0x000001B6 +#define SHORT_HEADER_START_CODE 0x00008000 +#define H264_START_CODE 0x00000001 + +/************************************************************************/ +/* STATIC VARIABLES */ +/************************************************************************/ + +static int Code_type; +static int total_frames = 0; +static unsigned int header_code = 0; +static pthread_mutex_t read_lock; + +static unsigned int read_frame ( unsigned char *dataptr,unsigned int length, + FILE * inputBufferFile + ); +static int Read_Buffer_From_DAT_File( unsigned char *dataptr, unsigned int length, + FILE * inputBufferFile + ); + +static unsigned clp2(unsigned x) +{ + x = x - 1; + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >>16); + return x + 1; +} + +static void* video_thread (void *); +static void* async_thread (void *); + +int main (int argc, char **argv) +{ + struct video_decoder_context *decoder_context = NULL; + char *file_name = NULL; + FILE *file_ptr = NULL; + int temp1 =0,temp2 =0; + int error = 1; + unsigned int i = 0; + + file_name = argv [1]; + file_ptr = fopen (file_name,"rb"); + + if (file_ptr == NULL) + { + DEBUG_PRINT("\n File is not located "); + return -1; + } + + + decoder_context = (struct video_decoder_context *) \ + calloc (sizeof (struct video_decoder_context),1); + if (decoder_context == NULL) + { + return -1; + } + decoder_context->outputBufferFile = NULL; + decoder_context->inputBufferFile = NULL; + decoder_context->video_driver_fd = -1; + decoder_context->inputBufferFile = file_ptr; + + file_ptr = fopen ("/data/output.yuv","wb"); + if (file_ptr == NULL) + { + DEBUG_PRINT("\n File can't be created"); + free (decoder_context); + return -1; + } + decoder_context->outputBufferFile = file_ptr; + + switch (atoi(argv[2])) + { + case 0: + DEBUG_PRINT("\n MPEG4 codec selected"); + decoder_context->decoder_format = VDEC_CODECTYPE_MPEG4; + Code_type = 0; + break; + case 1: + DEBUG_PRINT("\n H.263"); + decoder_context->decoder_format = VDEC_CODECTYPE_H263; + Code_type = 0; + break; + case 2: + DEBUG_PRINT("\n H.264"); + decoder_context->decoder_format = VDEC_CODECTYPE_H264; + Code_type = 1; + break; + default: + DEBUG_PRINT("\n Wrong codec type"); + error = -1; + break; + } + + if (error != -1) + { + temp1 = atoi(argv[3]); + temp2 = atoi(argv[4]); + + if (((temp1%16) != 0) || ((temp2%16) != 0)) + { + error = -1; + } + else + { + decoder_context->video_resoultion.frame_height = temp1; + decoder_context->video_resoultion.frame_width = temp2; + } + } + + switch (atoi(argv[5])) + { + case 0: + DEBUG_PRINT("\n No Sink"); + decoder_context->outputBufferFile = NULL; + break; + } + + if ( error != -1 && (init_decoder (decoder_context) == -1 )) + { + DEBUG_PRINT("\n Init decoder fails "); + error = -1; + } + DEBUG_PRINT("\n Decoder open successfull"); + + + /*Allocate input and output buffers*/ + if (error != -1 && (allocate_buffer (VDEC_BUFFER_TYPE_INPUT, + decoder_context)== -1)) + { + DEBUG_PRINT("\n Error in input Buffer allocation"); + error = -1; + } + + if (error != -1 && (allocate_buffer (VDEC_BUFFER_TYPE_OUTPUT, + decoder_context)== -1)) + { + DEBUG_PRINT("\n Error in output Buffer allocation"); + error = -1; + } + + + if (error != -1 && (start_decoding (decoder_context) == -1)) + { + DEBUG_PRINT("\n Error in start decoding call"); + error = -1; + } + + if (error != -1 && (stop_decoding (decoder_context) == -1)) + { + DEBUG_PRINT("\n Error in stop decoding call"); + error = -1; + } + + DEBUG_PRINT("\n De-init the decoder"); + if ((deinit_decoder (decoder_context) == -1)) + { + error = -1; + } + + + (void)free_buffer (VDEC_BUFFER_TYPE_INPUT,decoder_context); + (void)free_buffer (VDEC_BUFFER_TYPE_OUTPUT,decoder_context); + + if (decoder_context->inputBufferFile != NULL) + { + fclose (decoder_context->inputBufferFile); + } + if (decoder_context->outputBufferFile != NULL) + { + fclose (decoder_context->outputBufferFile); + } + DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames); + DEBUG_PRINT("\n closing the driver"); + free (decoder_context); + + return error; +} + +int init_decoder ( struct video_decoder_context *init_decode ) +{ + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + struct video_queue_context *queue_ptr = NULL; +#ifdef MAX_RES_720P + enum vdec_output_fromat output_format = VDEC_YUV_FORMAT_NV12; +#endif +#ifdef MAX_RES_1080P + enum vdec_output_fromat output_format = VDEC_YUV_FORMAT_TILE_4x2; +#endif + + pthread_mutexattr_t init_values; + + DEBUG_PRINT("\n Before calling the open"); + + init_decode->video_driver_fd = open ("/dev/msm_vidc_dec", \ + O_RDWR | O_NONBLOCK); + + + + if (init_decode->video_driver_fd < 0) + { + DEBUG_PRINT("\n Open failed"); + return -1; + } + + + /*Initialize Decoder with codec type and resolution*/ + ioctl_msg.in = &init_decode->decoder_format; + ioctl_msg.out = NULL; + + if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_CODEC, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set codec type failed"); + return -1; + } + + /*Set the output format*/ + ioctl_msg.in = &output_format; + ioctl_msg.out = NULL; + + if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set output format failed"); + return -1; + } + + ioctl_msg.in = &init_decode->video_resoultion; + ioctl_msg.out = NULL; + + if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_PICRES, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set Resolution failed"); + return -1; + } + DEBUG_PRINT("\n After Set Resolution"); + + DEBUG_PRINT("\n Query Input bufffer requirements"); + /*Get the Buffer requirements for input and output ports*/ + + init_decode->input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; + ioctl_msg.in = NULL; + ioctl_msg.out = &init_decode->input_buffer; + + if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Requesting for input buffer requirements failed"); + return -1; + } + + DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \ + init_decode->input_buffer.buffer_size,\ + init_decode->input_buffer.mincount,\ + init_decode->input_buffer.actualcount); + + + init_decode->input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; + ioctl_msg.in = &init_decode->input_buffer; + ioctl_msg.out = NULL; + init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2; + + if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set Buffer Requirements Failed"); + return -1; + } + + + DEBUG_PRINT("\n Query output bufffer requirements"); + init_decode->output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; + ioctl_msg.in = NULL; + ioctl_msg.out = &init_decode->output_buffer; + + if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Requesting for output buffer requirements failed"); + return -1; + } + + DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \ + init_decode->output_buffer.buffer_size,\ + init_decode->output_buffer.mincount,\ + init_decode->output_buffer.actualcount); + + /*Create Queue related data structures*/ + queue_ptr = &init_decode->queue_context; + queue_ptr->commandq_size = 50; + queue_ptr->dataq_size = 50; + + sem_init(&queue_ptr->sem_message,0, 0); + sem_init(&init_decode->sem_synchronize,0, 0); + + pthread_mutexattr_init (&init_values); + pthread_mutex_init (&queue_ptr->mutex,&init_values); + pthread_mutex_init (&read_lock,&init_values); + DEBUG_PRINT("\n create Queues"); + queue_ptr->ptr_cmdq = (struct video_msgq*) \ + calloc (sizeof (struct video_msgq), + queue_ptr->commandq_size); + queue_ptr->ptr_dataq = (struct video_msgq*) \ + calloc (sizeof (struct video_msgq), + queue_ptr->dataq_size + ); + + if ( queue_ptr->ptr_cmdq == NULL || + queue_ptr->ptr_dataq == NULL + ) + { + return -1; + } + DEBUG_PRINT("\n create Threads"); + /*Create two threads*/ + if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread, + init_decode) < 0) || + (pthread_create (&init_decode->asyncthread_id,NULL,async_thread, + init_decode) < 0) + ) + { + return -1; + } + + return 1; +} + + + +int free_buffer ( enum vdec_buffer buffer_dir, + struct video_decoder_context *decode_context + ) +{ + unsigned int buffercount = 0,i=0; + struct vdec_bufferpayload **ptemp = NULL; + + if (decode_context == NULL) + { + return -1; + } + + if (buffer_dir == VDEC_BUFFER_TYPE_INPUT && decode_context->ptr_inputbuffer) + { + buffercount = decode_context->input_buffer.actualcount; + ptemp = decode_context->ptr_inputbuffer; + + for (i=0;ipmem_fd != -1) + { + munmap ( ptemp [i]->bufferaddr,ptemp [i]->mmaped_size); + ptemp [i]->bufferaddr = NULL; + close (ptemp [i]->pmem_fd); + } + free (ptemp [i]); + ptemp [i] = NULL; + } + } + free (decode_context->ptr_inputbuffer); + decode_context->ptr_inputbuffer = NULL; + } + else if ( buffer_dir == VDEC_BUFFER_TYPE_OUTPUT ) + { + buffercount = decode_context->output_buffer.actualcount; + ptemp = decode_context->ptr_outputbuffer; + + if (decode_context->ptr_respbuffer) + { + for (i=0;iptr_respbuffer [i]) + { + free (decode_context->ptr_respbuffer[i]); + decode_context->ptr_respbuffer [i] = NULL; + } + } + free (decode_context->ptr_respbuffer); + decode_context->ptr_respbuffer = NULL; + } + + if (ptemp) + { + for (i=0;ipmem_fd != -1) + { + munmap ( ptemp [i]->bufferaddr,ptemp [i]->mmaped_size); + ptemp [i]->bufferaddr = NULL; + close (ptemp [i]->pmem_fd); + } + free (ptemp [i]); + ptemp [i] = NULL; + } + } + free (ptemp); + decode_context->ptr_outputbuffer = NULL; + } + } + + return 1; +} + +int allocate_buffer ( enum vdec_buffer buffer_dir, + struct video_decoder_context *decode_context + ) +{ + struct vdec_setbuffer_cmd setbuffers; + struct vdec_bufferpayload **ptemp = NULL; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + unsigned int buffercount = 0,i=0,alignedsize=0; + unsigned int buffersize = 0; + + if ( decode_context == NULL) + { + DEBUG_PRINT ("\nallocate_buffer: context is NULL"); + return -1; + } + + if ( buffer_dir == VDEC_BUFFER_TYPE_INPUT ) + { + /*Check if buffers are allocated*/ + if (decode_context->ptr_inputbuffer != NULL) + { + DEBUG_PRINT ("\nallocate_buffer: decode_context->ptr_inputbuffer is set"); + return -1; + } + + buffercount = decode_context->input_buffer.actualcount; + alignedsize = decode_context->input_buffer.alignment; + buffersize = decode_context->input_buffer.buffer_size; + buffersize = (buffersize + alignedsize) & (~alignedsize); + } + else if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT) + { + /*Check if buffers are allocated*/ + if (decode_context->ptr_outputbuffer != NULL) + { + DEBUG_PRINT ("\nallocate_buffer: Double allcoate output"); + return -1; + } + + buffercount = decode_context->output_buffer.actualcount; + alignedsize = decode_context->output_buffer.alignment; + buffersize = decode_context->output_buffer.buffer_size; + buffersize = (buffersize + alignedsize) & (~alignedsize); + + decode_context->ptr_respbuffer = (struct vdec_output_frameinfo **)\ + calloc (sizeof (struct vdec_output_frameinfo *),buffercount); + + if (decode_context->ptr_respbuffer == NULL) + { + DEBUG_PRINT ("\n Allocate failure ptr_respbuffer"); + return -1; + } + + for (i=0; i< buffercount; i++) + { + decode_context->ptr_respbuffer [i] = (struct vdec_output_frameinfo *)\ + calloc (sizeof (struct vdec_output_frameinfo),buffercount); + if (decode_context->ptr_respbuffer [i] == NULL) + { + DEBUG_PRINT ("\nfailed to allocate vdec_output_frameinfo"); + return -1; + } + } + } + else + { + DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions"); + return -1; + } + + ptemp = (struct vdec_bufferpayload **)\ + calloc (sizeof (struct vdec_bufferpayload *),buffercount); + + if (ptemp == NULL) + { + DEBUG_PRINT ("\nallocate_buffer: vdec_bufferpayload failure"); + return -1; + } + + + if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT) + { + DEBUG_PRINT ("\nallocate_buffer: OUT"); + decode_context->ptr_outputbuffer = ptemp; + } + else + { + DEBUG_PRINT ("\nallocate_buffer: IN"); + decode_context->ptr_inputbuffer = ptemp; + } + + /*Allocate buffer headers*/ + for (i=0; i< buffercount; i++) + { + ptemp [i] = (struct vdec_bufferpayload*)\ + calloc (sizeof (struct vdec_bufferpayload),1); + + if (ptemp [i] == NULL) + { + DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure"); + return -1; + } + + if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT) + { + decode_context->ptr_respbuffer [i]->client_data = \ + (void *) ptemp [i]; + } + ptemp [i]->pmem_fd = -1; + + } + + for (i=0; i< buffercount; i++) + { + ptemp [i]->pmem_fd = open ("/dev/pmem_adsp",O_RDWR); + + if (ptemp [i]->pmem_fd < 0) + { + DEBUG_PRINT ("\nallocate_buffer: open pmem_adsp failed"); + return -1; + } + + ptemp [i]->bufferaddr = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE, + MAP_SHARED,ptemp [i]->pmem_fd,0); + DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->pmem_fd,\ + ptemp [i]->bufferaddr); + if (ptemp [i]->bufferaddr == MAP_FAILED) + { + ptemp [i]->bufferaddr = NULL; + DEBUG_PRINT ("\nallocate_buffer: MMAP failed"); + return -1; + } + ptemp [i]->buffer_len = buffersize; + ptemp [i]->mmaped_size = clp2 (buffersize); + + setbuffers.buffer_type = buffer_dir; + memcpy (&setbuffers.buffer,ptemp [i],sizeof (struct vdec_bufferpayload)); + + ioctl_msg.in = &setbuffers; + ioctl_msg.out = NULL; + + if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_SET_BUFFER, + &ioctl_msg) < 0) + { + DEBUG_PRINT ("\nallocate_buffer: Set Buffer IOCTL failed"); + return -1; + } + + } + DEBUG_PRINT ("\nallocate_buffer: Success"); + return 1; +} + + + +int start_decoding (struct video_decoder_context *decode_context) +{ + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + struct vdec_input_frameinfo frameinfo; + struct vdec_fillbuffer_cmd fillbuffer; + unsigned int i = 0; + unsigned int data_len =0; + + memset ((unsigned char*)&frameinfo,0,sizeof (struct vdec_input_frameinfo)); + memset ((unsigned char*)&fillbuffer,0,sizeof (struct vdec_fillbuffer_cmd)); + + if (decode_context == NULL) + { + return -1; + } + + if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_CMD_START, + NULL) < 0) + { + DEBUG_PRINT("\n Start failed"); + return -1; + } + + DEBUG_PRINT("\n Start Issued successfully waiting for Start Done"); + /*Wait for Start command response*/ + sem_wait (&decode_context->sem_synchronize); + + /*Push output Buffers*/ + i = 0; + while (i < decode_context->output_buffer.mincount) + { + fillbuffer.buffer.buffer_len = + decode_context->ptr_outputbuffer [i]->buffer_len; + fillbuffer.buffer.bufferaddr = + decode_context->ptr_outputbuffer [i]->bufferaddr; + fillbuffer.buffer.offset = + decode_context->ptr_outputbuffer [i]->offset; + fillbuffer.buffer.pmem_fd = + decode_context->ptr_outputbuffer [i]->pmem_fd; + fillbuffer.client_data = (void *)decode_context->ptr_respbuffer [i]; + DEBUG_PRINT ("\n Client Data on output = %p",fillbuffer.client_data); + ioctl_msg.in = &fillbuffer; + ioctl_msg.out = NULL; + + if (ioctl (decode_context->video_driver_fd, + VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Decoder frame failed"); + return -1; + } + i++; + } + + + /*push input buffers*/ + i = 0; + while (i < decode_context->input_buffer.mincount) + { + DEBUG_PRINT("\n Read Frame from File"); + data_len = read_frame ( decode_context->ptr_inputbuffer [i]->bufferaddr, + decode_context->ptr_inputbuffer [i]->buffer_len, + decode_context->inputBufferFile); + if (data_len == 0) + { + DEBUG_PRINT("\n Length is zero error"); + return -1; + } + DEBUG_PRINT("\n Read Frame from File szie = %u",data_len); + frameinfo.bufferaddr = + decode_context->ptr_inputbuffer [i]->bufferaddr; + frameinfo.offset = 0; + frameinfo.pmem_fd = decode_context->ptr_inputbuffer [i]->pmem_fd; + frameinfo.pmem_offset = decode_context->ptr_inputbuffer [i]->offset; + frameinfo.datalen = data_len; + frameinfo.client_data = (struct vdec_bufferpayload *)\ + decode_context->ptr_inputbuffer [i]; + /*TODO: Time stamp needs to be updated*/ + ioctl_msg.in = &frameinfo; + ioctl_msg.out = NULL; + + if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_DECODE_FRAME, + &ioctl_msg) < 0) + { + DEBUG_PRINT("\n Decoder frame failed"); + return -1; + } + total_frames++; + i++; + } + DEBUG_PRINT ("\n Wait for EOS"); + /*Wait for EOS or Error condition*/ + sem_wait (&decode_context->sem_synchronize); + DEBUG_PRINT ("\n Reached EOS"); + + return 1; +} + +int stop_decoding (struct video_decoder_context *decode_context) +{ + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_INPUT; + + if (decode_context == NULL) + { + return -1; + } + + ioctl_msg.in = &flush_dir; + ioctl_msg.out = NULL; + + if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_FLUSH, + &ioctl_msg) < 0) + { + DEBUG_PRINT("\n Flush input failed"); + } + else + { + sem_wait (&decode_context->sem_synchronize); + } + + flush_dir = VDEC_FLUSH_TYPE_OUTPUT; + ioctl_msg.in = &flush_dir; + ioctl_msg.out = NULL; + + if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_FLUSH, + &ioctl_msg) < 0) + { + DEBUG_PRINT("\n Flush output failed"); + } + else + { + sem_wait (&decode_context->sem_synchronize); + } + + DEBUG_PRINT("\n Stop VDEC_IOCTL_CMD_STOP"); + if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_STOP, + NULL) < 0) + { + DEBUG_PRINT("\n Stop failed"); + } + else + { + sem_wait (&decode_context->sem_synchronize); + } + return 1; +} + +int deinit_decoder (struct video_decoder_context *init_decode) +{ + if (init_decode == NULL) + { + return -1; + } + + /*Close the driver*/ + if (init_decode->video_driver_fd != -1) + { + close (init_decode->video_driver_fd); + } + + if (init_decode->queue_context.ptr_cmdq) + { + free (init_decode->queue_context.ptr_cmdq); + init_decode->queue_context.ptr_cmdq = NULL; + } + + if (init_decode->queue_context.ptr_dataq) + { + free (init_decode->queue_context.ptr_dataq); + init_decode->queue_context.ptr_dataq = NULL; + } + + sem_destroy (&init_decode->queue_context.sem_message); + sem_destroy (&init_decode->sem_synchronize); + + pthread_mutex_destroy(&init_decode->queue_context.mutex); + pthread_mutex_destroy (&read_lock); + + return 1; +} + +static void* video_thread (void *context) +{ + struct video_decoder_context *decode_context = NULL; + struct video_msgq *queueitem = NULL; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + struct vdec_input_frameinfo frameinfo; + struct vdec_fillbuffer_cmd fillbuffer; + struct vdec_output_frameinfo *outputbuffer = NULL; + struct vdec_bufferpayload *tempbuffer = NULL; + unsigned int data_len =0; + + + if (context == NULL) + { + DEBUG_PRINT("\n video thread recieved NULL context"); + return NULL; + } + decode_context = (struct video_decoder_context *) context; + + /* Thread function which will accept commands from async thread + * or main thread + */ + while (1) + { + queueitem = queue_get_cmd (&decode_context ->queue_context); + if (queueitem != NULL) + { + switch (queueitem->cmd) + { + case VDEC_MSG_EVT_HW_ERROR: + DEBUG_PRINT("\n FATAL ERROR "); + break; + case VDEC_MSG_RESP_INPUT_FLUSHED: + DEBUG_PRINT("\n Input Buffer Flushed"); + break; + case VDEC_MSG_RESP_OUTPUT_FLUSHED: + DEBUG_PRINT("\n Output buffer Flushed"); + break; + case VDEC_MSG_RESP_START_DONE: + DEBUG_PRINT("\n recived start done command"); + sem_post (&decode_context->sem_synchronize); + break; + + case VDEC_MSG_RESP_STOP_DONE: + DEBUG_PRINT("\n recieved stop done"); + sem_post (&decode_context->sem_synchronize); + break; + + case VDEC_MSG_RESP_INPUT_BUFFER_DONE: + + tempbuffer = (struct vdec_bufferpayload *)queueitem->clientdata; + if (tempbuffer == NULL) + { + DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); + sem_post (&decode_context->sem_synchronize); + break; + } + data_len = read_frame ( tempbuffer->bufferaddr, + tempbuffer->buffer_len, + decode_context->inputBufferFile + ); + + if (data_len == 0) + { + DEBUG_PRINT ("\n End of stream reached"); + sem_post (&decode_context->sem_synchronize); + break; + } + + frameinfo.bufferaddr = tempbuffer->bufferaddr; + frameinfo.offset = 0; + frameinfo.pmem_fd = tempbuffer->pmem_fd; + frameinfo.pmem_offset = tempbuffer->offset; + frameinfo.datalen = data_len; + frameinfo.client_data = (struct vdec_bufferpayload *)\ + tempbuffer; + /*TODO: Time stamp needs to be updated*/ + ioctl_msg.in = &frameinfo; + ioctl_msg.out = NULL; + total_frames++; + if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_DECODE_FRAME, + &ioctl_msg) < 0) + { + DEBUG_PRINT("\n Decoder frame failed"); + sem_post (&decode_context->sem_synchronize); + } + DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\ + total_frames); + break; + + case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: + + outputbuffer = (struct vdec_output_frameinfo *)\ + queueitem->clientdata; + DEBUG_PRINT("\n Value of client Data in VT %p",queueitem->clientdata); + if (outputbuffer == NULL || outputbuffer->bufferaddr == NULL || + outputbuffer->client_data == NULL + ) + { + DEBUG_PRINT("\n FATAL ERROR output buffer is bad"); + DEBUG_PRINT("\nValues outputbuffer = %p",outputbuffer); + if (outputbuffer != NULL) + { + DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\ + outputbuffer->bufferaddr); + DEBUG_PRINT("\nValues outputbuffer->client_data = %p",\ + outputbuffer->client_data); + } + sem_post (&decode_context->sem_synchronize); + break; + } + + + if (outputbuffer->len == 0) + { + DEBUG_PRINT("\n Filled Length is zero Close decoding"); + sem_post (&decode_context->sem_synchronize); + break; + } + + if (decode_context->outputBufferFile != NULL) + { + fwrite (outputbuffer->bufferaddr,1,outputbuffer->len, + decode_context->outputBufferFile); + } + + tempbuffer = (struct vdec_bufferpayload *)\ + outputbuffer->client_data; + + DEBUG_PRINT("\n recieved output buffer consume outbuffer"); + DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\ + outputbuffer->bufferaddr); + DEBUG_PRINT ("\n Vir address of allocated buffer %p",\ + tempbuffer->bufferaddr); + fillbuffer.buffer.buffer_len = tempbuffer->buffer_len; + fillbuffer.buffer.bufferaddr = tempbuffer->bufferaddr; + fillbuffer.buffer.offset = tempbuffer->offset; + fillbuffer.buffer.pmem_fd = tempbuffer->pmem_fd; + fillbuffer.client_data = (void *)outputbuffer; + + ioctl_msg.in = &fillbuffer; + ioctl_msg.out = NULL; + + if (ioctl (decode_context->video_driver_fd, + VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Decoder frame failed"); + return NULL; + } + + break; + + case VDEC_MSG_RESP_FLUSH_INPUT_DONE: + DEBUG_PRINT("\n Flush input complete"); + sem_post (&decode_context->sem_synchronize); + break; + + case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: + DEBUG_PRINT("\n Flush output complete"); + sem_post (&decode_context->sem_synchronize); + break; + } + + if (queueitem->cmd == VDEC_MSG_RESP_STOP_DONE) + { + DEBUG_PRINT("\n Playback has ended thread will exit"); + return NULL; + } + } + else + { + DEBUG_PRINT("\n Error condition recieved NULL from Queue"); + } + + } +} + +static void* async_thread (void *context) +{ + struct video_decoder_context *decode_context = NULL; + struct vdec_output_frameinfo *outputframe = NULL; + struct video_msgq queueitem ; + struct vdec_msginfo vdec_msg; + struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; + int result = -1; + + if (context == NULL) + { + DEBUG_PRINT("\n aynsc thread recieved NULL context"); + return NULL; + } + decode_context = (struct video_decoder_context *) context; + DEBUG_PRINT("\n Entering the async thread"); + + while (1) + { + ioctl_msg.in = NULL; + + ioctl_msg.out = (void*)&vdec_msg; + DEBUG_PRINT ("\n Sizeof vdec_msginfo = %d ",sizeof (vdec_msg)); + DEBUG_PRINT("\n Address of Vdec msg in async thread %p",\ + ioctl_msg.out); + if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG,\ + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Error in ioctl read next msg"); + } + else + { + switch (vdec_msg.msgcode) + { + case VDEC_MSG_RESP_FLUSH_INPUT_DONE: + case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: + case VDEC_MSG_RESP_START_DONE: + case VDEC_MSG_RESP_STOP_DONE: + case VDEC_MSG_EVT_HW_ERROR: + DEBUG_PRINT("\nioctl read next msg"); + queueitem.cmd = vdec_msg.msgcode; + queueitem.status = vdec_msg.status_code; + queueitem.clientdata = NULL; + break; + + case VDEC_MSG_RESP_INPUT_FLUSHED: + case VDEC_MSG_RESP_INPUT_BUFFER_DONE: + + queueitem.cmd = vdec_msg.msgcode; + queueitem.status = vdec_msg.status_code; + queueitem.clientdata = (void *)\ + vdec_msg.msgdata.input_frame_clientdata; + break; + + case VDEC_MSG_RESP_OUTPUT_FLUSHED: + case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: + queueitem.cmd = vdec_msg.msgcode; + queueitem.status = vdec_msg.status_code; + outputframe = (struct vdec_output_frameinfo *)\ + vdec_msg.msgdata.output_frame.client_data; + DEBUG_PRINT ("\n Client Data value in %p", \ + vdec_msg.msgdata.output_frame.client_data); + outputframe->bufferaddr = vdec_msg.msgdata.output_frame.bufferaddr; + outputframe->framesize.bottom = \ + vdec_msg.msgdata.output_frame.framesize.bottom; + outputframe->framesize.left = \ + vdec_msg.msgdata.output_frame.framesize.left; + outputframe->framesize.right = \ + vdec_msg.msgdata.output_frame.framesize.right; + outputframe->framesize.top = \ + vdec_msg.msgdata.output_frame.framesize.top; + outputframe->framesize = vdec_msg.msgdata.output_frame.framesize; + outputframe->len = vdec_msg.msgdata.output_frame.len; + outputframe->time_stamp = vdec_msg.msgdata.output_frame.time_stamp; + queueitem.clientdata = (void *)outputframe; + DEBUG_PRINT ("\n Client Data value Copy %p",queueitem.clientdata); + break; + + default: + DEBUG_PRINT("\nIn Default of get next message %d",vdec_msg.msgcode); + queueitem.cmd = vdec_msg.msgcode; + queueitem.status = vdec_msg.status_code; + queueitem.clientdata = NULL; + break; + } + result = queue_post_cmdq (&decode_context->queue_context,&queueitem); + while (result == 0) + { + result = queue_post_cmdq (&decode_context->queue_context, + &queueitem); + } + + if (result == -1) + { + DEBUG_PRINT("\n FATAL ERROR WITH Queue"); + } + } + if (vdec_msg.msgcode == VDEC_MSG_RESP_STOP_DONE) + { + /*Thread can exit at this point*/ + return NULL; + } + } +} + + +static unsigned int read_frame (unsigned char *dataptr, unsigned int length, + FILE * inputBufferFile) +{ + + unsigned int readOffset = 0; + int bytes_read = 0; + unsigned int code = 0; + int found = 0; + + DEBUG_PRINT ("\n Inside the readframe"); + + if (dataptr == NULL || length == 0) + { + DEBUG_PRINT ("\n dataptr = %p length = %u",dataptr,length); + return 0; + } + + if (!Code_type) + { + /* Start of Critical Section*/ + pthread_mutex_lock(&read_lock); + do + { + //Start codes are always byte aligned. + bytes_read = fread(&dataptr[readOffset],1, 1,inputBufferFile); + if( !bytes_read) + { + DEBUG_PRINT("\n Bytes read Zero \n"); + break; + } + code <<= 8; + code |= (0x000000FF & dataptr[readOffset]); + //VOP start code comparision + if (readOffset>3) + { + if(!header_code ) + { + if( VOP_START_CODE == code) + { + DEBUG_PRINT ("\n Found VOP Code"); + header_code = VOP_START_CODE; + } + else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE ) + { + header_code = SHORT_HEADER_START_CODE; + } + } + if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE)) + { + //Seek backwards by 4 + fseek(inputBufferFile, -4, SEEK_CUR); + readOffset-=4; + found = 1; + break; + + } + else if (( header_code == SHORT_HEADER_START_CODE ) && + ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00))) + { + //Seek backwards by 4 + fseek(inputBufferFile, -4, SEEK_CUR); + readOffset-=4; + found = 1; + break; + } + } + readOffset++; + }while (readOffset < length); + pthread_mutex_unlock(&read_lock); + /* End of Critical Section*/ + if (found == 1) + { + //DEBUG_PRINT ("Found a Frame"); + return (readOffset+1); + } + else + { + //DEBUG_PRINT ("No Frames detected"); + return 0; + } + } + else + { + + readOffset = Read_Buffer_From_DAT_File(dataptr,length,inputBufferFile); + if (total_frames == 0) + { + bytes_read = Read_Buffer_From_DAT_File(&dataptr[readOffset], + (length-readOffset), + inputBufferFile); + readOffset += bytes_read; + } + return (readOffset); + } + +} + +static int Read_Buffer_From_DAT_File(unsigned char *dataptr, unsigned int length, + FILE * inputBufferFile) +{ + + + long frameSize=0; + char temp_buffer[10]; + char temp_byte; + int bytes_read=0; + int i=0; + unsigned char *read_buffer=NULL; + char c = '1'; //initialize to anything except '\0'(0) + char inputFrameSize[12]; + int count =0; char cnt =0; + memset(temp_buffer, 0, sizeof(temp_buffer)); + + while (cnt < 10) + /* Check the input file format, may result in infinite loop */ + { + count = fread(&inputFrameSize[cnt],1,1,inputBufferFile); + if(inputFrameSize[cnt] == '\0' ) + break; + cnt++; + } + inputFrameSize[cnt]='\0'; + frameSize = atoi(inputFrameSize); + //length = 0; + DEBUG_PRINT ("\n Frame Size is %d",frameSize); + + /* get the frame length */ + fseek(inputBufferFile, -1, SEEK_CUR); + bytes_read = fread(dataptr, 1, frameSize, inputBufferFile); + + if(bytes_read == 0 || bytes_read < frameSize ) { + return 0; + } + return bytes_read; +} diff --git a/mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp b/mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp new file mode 100644 index 00000000..a191ee28 --- /dev/null +++ b/mm-video-v4l2/vidc/vdec/test/omx_vdec_test.cpp @@ -0,0 +1,4543 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +/* + An Open max test application .... +*/ + +#define LOG_TAG "OMX-VDEC-TEST" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "OMX_QCOMExtns.h" +#include +#include + +#include + +#ifdef _ANDROID_ +#include + +extern "C"{ +#include +} +#define DEBUG_PRINT +#define DEBUG_PRINT_ERROR ALOGE + +//#define __DEBUG_DIVX__ // Define this macro to print (through logcat) + // the kind of frames packed per buffer and + // timestamps adjustments for divx. + +//#define TEST_TS_FROM_SEI // Define this macro to calculate the timestamps + // from the SEI and VUI data for H264 + +#else +#include +#define strlcpy g_strlcpy + +#define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args) +#define DEBUG_PRINT printf +#define DEBUG_PRINT_ERROR printf +#endif /* _ANDROID_ */ + +#include "OMX_Core.h" +#include "OMX_Component.h" +#include "OMX_QCOMExtns.h" +extern "C" { +#include "queue.h" +} + +#include +#include +#include + +/************************************************************************/ +/* #DEFINES */ +/************************************************************************/ +#define DELAY 66 +#define false 0 +#define true 1 +#define H264_START_CODE 0x00000001 +#define VOP_START_CODE 0x000001B6 +#define SHORT_HEADER_START_CODE 0x00008000 +#define MPEG2_FRAME_START_CODE 0x00000100 +#define MPEG2_SEQ_START_CODE 0x000001B3 +#define VC1_START_CODE 0x00000100 +#define VC1_FRAME_START_CODE 0x0000010D +#define VC1_FRAME_FIELD_CODE 0x0000010C +#define VC1_SEQUENCE_START_CODE 0x0000010F +#define VC1_ENTRY_POINT_START_CODE 0x0000010E +#define NUMBER_OF_ARBITRARYBYTES_READ (4 * 1024) +#define VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC 32 +#define VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC 16 +static int previous_vc1_au = 0; +#define CONFIG_VERSION_SIZE(param) \ + param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\ + param.nSize = sizeof(param); + +#define FAILED(result) (result != OMX_ErrorNone) + +#define SUCCEEDED(result) (result == OMX_ErrorNone) +#define SWAPBYTES(ptrA, ptrB) { char t = *ptrA; *ptrA = *ptrB; *ptrB = t;} +#define SIZE_NAL_FIELD_MAX 4 +#define MDP_DEINTERLACE 0x80000000 + +#define ALLOCATE_BUFFER 0 + +#ifdef MAX_RES_720P +#define PMEM_DEVICE "/dev/pmem_adsp" +#elif MAX_RES_1080P_EBI +#define PMEM_DEVICE "/dev/pmem_adsp" +#elif MAX_RES_1080P +#define PMEM_DEVICE "/dev/pmem_smipool" +#endif + +//#define USE_EXTERN_PMEM_BUF + +/************************************************************************/ +/* GLOBAL DECLARATIONS */ +/************************************************************************/ +#ifdef _ANDROID_ +using namespace android; +#endif + +#ifdef _MSM8974_ +typedef unsigned short int uint16; +const uint16 CRC_INIT = 0xFFFF ; + +const uint16 crc_16_l_table[ 256 ] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +#ifdef ANDROID_JELLYBEAN_MR1 +//Since this is unavailable on Android 4.2.2, defining it in terms of base 10 +static inline float log2f(const float& x) { + return log(x) / log(2); +} +#endif + +uint16 crc_16_l_step_nv12 (uint16 seed, const void *buf_ptr, + unsigned int byte_len, unsigned int height, unsigned int width) +{ + uint16 crc_16 = ~seed; + char *buf = (char *)buf_ptr; + char *byte_ptr = buf; + int i, j; + const unsigned int width_align = 32; + const unsigned int height_align = 32; + unsigned int stride = (width + width_align -1) & (~(width_align-1)); + unsigned int scan_lines = (height + height_align -1) & (~(height_align-1)); + for (i = 0; i < height; i++) { + for (j = 0; j < stride; j++) { + if (j < width) { + crc_16 = crc_16_l_table[ (crc_16 ^ *byte_ptr) & 0x00ff ] ^ (crc_16 >> 8); + } + byte_ptr++; + } + } + byte_ptr = buf + (scan_lines * stride); + for (i = scan_lines; i < scan_lines + height/2;i++) { + for (j = 0; j < stride; j++) { + if (j < width) { + crc_16 = crc_16_l_table[ (crc_16 ^ *byte_ptr) & 0x00ff ] ^ (crc_16 >> 8); + } + byte_ptr++; + } + } + return( ~crc_16 ); +} +#endif + +typedef enum { + CODEC_FORMAT_H264 = 1, + CODEC_FORMAT_MP4, + CODEC_FORMAT_H263, + CODEC_FORMAT_VC1, + CODEC_FORMAT_DIVX, + CODEC_FORMAT_MPEG2, +#ifdef _MSM8974_ + CODEC_FORMAT_VP8, + CODEC_FORMAT_HEVC, +#endif + CODEC_FORMAT_MAX +} codec_format; + +typedef enum { + FILE_TYPE_DAT_PER_AU = 1, + FILE_TYPE_ARBITRARY_BYTES, + FILE_TYPE_COMMON_CODEC_MAX, + + FILE_TYPE_START_OF_H264_SPECIFIC = 10, + FILE_TYPE_264_NAL_SIZE_LENGTH = FILE_TYPE_START_OF_H264_SPECIFIC, + FILE_TYPE_264_START_CODE_BASED, + + FILE_TYPE_START_OF_MP4_SPECIFIC = 20, + FILE_TYPE_PICTURE_START_CODE = FILE_TYPE_START_OF_MP4_SPECIFIC, + + FILE_TYPE_START_OF_VC1_SPECIFIC = 30, + FILE_TYPE_RCV = FILE_TYPE_START_OF_VC1_SPECIFIC, + FILE_TYPE_VC1, + + FILE_TYPE_START_OF_DIVX_SPECIFIC = 40, + FILE_TYPE_DIVX_4_5_6 = FILE_TYPE_START_OF_DIVX_SPECIFIC, + FILE_TYPE_DIVX_311, + + FILE_TYPE_START_OF_MPEG2_SPECIFIC = 50, + FILE_TYPE_MPEG2_START_CODE = FILE_TYPE_START_OF_MPEG2_SPECIFIC, + +#ifdef _MSM8974_ + FILE_TYPE_START_OF_VP8_SPECIFIC = 60, + FILE_TYPE_VP8_START_CODE = FILE_TYPE_START_OF_VP8_SPECIFIC, + FILE_TYPE_VP8 +#endif + +} file_type; + +typedef enum { + GOOD_STATE = 0, + PORT_SETTING_CHANGE_STATE, + ERROR_STATE +} test_status; + +typedef enum { + FREE_HANDLE_AT_LOADED = 1, + FREE_HANDLE_AT_IDLE, + FREE_HANDLE_AT_EXECUTING, + FREE_HANDLE_AT_PAUSE +} freeHandle_test; + +struct temp_egl { + int pmem_fd; + int offset; +}; + +static int (*Read_Buffer)(OMX_BUFFERHEADERTYPE *pBufHdr ); + +int inputBufferFileFd; + +FILE * outputBufferFile; +#ifdef _MSM8974_ +FILE * crcFile; +#endif +FILE * seqFile; +int takeYuvLog = 0; +int displayYuv = 0; +int displayWindow = 0; +int realtime_display = 0; +int num_frames_to_decode = 0; +int thumbnailMode = 0; + +Queue *etb_queue = NULL; +Queue *fbd_queue = NULL; + +pthread_t ebd_thread_id; +pthread_t fbd_thread_id; +void* ebd_thread(void*); +void* fbd_thread(void*); + +pthread_mutex_t etb_lock; +pthread_mutex_t fbd_lock; +pthread_mutex_t lock; +pthread_cond_t cond; +pthread_mutex_t eos_lock; +pthread_cond_t eos_cond; +pthread_mutex_t enable_lock; + +sem_t etb_sem; +sem_t fbd_sem; +sem_t seq_sem; +sem_t in_flush_sem, out_flush_sem; + +OMX_PARAM_PORTDEFINITIONTYPE portFmt; +OMX_PORT_PARAM_TYPE portParam; +OMX_ERRORTYPE error; +OMX_COLOR_FORMATTYPE color_fmt; +static bool input_use_buffer = false,output_use_buffer = false; +QOMX_VIDEO_DECODER_PICTURE_ORDER picture_order; + +#ifdef MAX_RES_1080P +unsigned int color_fmt_type = 1; +#else +unsigned int color_fmt_type = 0; +#endif + +#define CLR_KEY 0xe8fd +#define COLOR_BLACK_RGBA_8888 0x00000000 +#define FRAMEBUFFER_32 + +static int fb_fd = -1; +static struct fb_var_screeninfo vinfo; +static struct fb_fix_screeninfo finfo; +static struct mdp_overlay overlay, *overlayp; +static struct msmfb_overlay_data ov_front; +static int vid_buf_front_id; +static char tempbuf[16]; +int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr); +void overlay_set(); +void overlay_unset(); +void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr); +int disable_output_port(); +int enable_output_port(); +int output_port_reconfig(); +void free_output_buffers(); +int open_display(); +void close_display(); +/************************************************************************/ +/* GLOBAL INIT */ +/************************************************************************/ +int input_buf_cnt = 0; +int height =0, width =0; +int sliceheight = 0, stride = 0; +int used_ip_buf_cnt = 0; +unsigned free_op_buf_cnt = 0; +volatile int event_is_done = 0; +int ebd_cnt= 0, fbd_cnt = 0; +int bInputEosReached = 0; +int bOutputEosReached = 0; +char in_filename[512]; +#ifdef _MSM8974_ +char crclogname[512]; +#endif +char seq_file_name[512]; +unsigned char seq_enabled = 0; +bool anti_flickering = true; +unsigned char flush_input_progress = 0, flush_output_progress = 0; +unsigned cmd_data = ~(unsigned)0, etb_count = 0; + +char curr_seq_command[100]; +OMX_S64 timeStampLfile = 0; +int fps = 30; +unsigned int timestampInterval = 33333; +codec_format codec_format_option; +file_type file_type_option; +freeHandle_test freeHandle_option; +int nalSize = 0; +int sent_disabled = 0; +int waitForPortSettingsChanged = 1; +test_status currentStatus = GOOD_STATE; +struct timeval t_start = {0, 0}, t_end = {0, 0}; + +//* OMX Spec Version supported by the wrappers. Version = 1.1 */ +const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101; +OMX_COMPONENTTYPE* dec_handle = 0; + +OMX_BUFFERHEADERTYPE **pInputBufHdrs = NULL; +OMX_BUFFERHEADERTYPE **pOutYUVBufHdrs= NULL; + +static OMX_BOOL use_external_pmem_buf = OMX_FALSE; + +int rcv_v1=0; +static struct temp_egl **p_eglHeaders = NULL; +static unsigned use_buf_virt_addr[32]; + +OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList = NULL; +OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry = NULL; +OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; +OMX_CONFIG_RECTTYPE crop_rect = {0,0,0,0}; + +static int bHdrflag = 0; + +/* Performance related variable*/ +//QPERF_INIT(render_fb); +//QPERF_INIT(client_decode); + +/************************************************************************/ +/* GLOBAL FUNC DECL */ +/************************************************************************/ +int Init_Decoder(); +int Play_Decoder(); +int run_tests(); + +/**************************************************************************/ +/* STATIC DECLARATIONS */ +/**************************************************************************/ +static int video_playback_count = 1; +static int open_video_file (); +static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr ); +static int Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr); +#ifdef _MSM8974_ +static int Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE *pBufHdr); +#endif +static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE *pBufHdr); +static int Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE *pBufHdr); + +static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***pBufHdrs, + OMX_U32 nPortIndex, + long bufCntMin, long bufSize); + +static OMX_ERRORTYPE use_input_buffer(OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***bufferHdr, + OMX_U32 nPortIndex, + OMX_U32 bufSize, + long bufcnt); + +static OMX_ERRORTYPE use_output_buffer(OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***bufferHdr, + OMX_U32 nPortIndex, + OMX_U32 bufSize, + long bufcnt); + +static OMX_ERRORTYPE use_output_buffer_multiple_fd(OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***bufferHdr, + OMX_U32 nPortIndex, + OMX_U32 bufSize, + long bufcnt); + +static 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); +static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); +static OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent, + OMX_OUT OMX_PTR pAppData, + OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); + +static void do_freeHandle_and_clean_up(bool isDueToError); + +#ifndef USE_ION +static bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, + OMX_U32 alignment); +#endif +void getFreePmem(); +static int overlay_vsync_ctrl(int enable); + +static int clip2(int x) + { + x = x -1; + x = x | x >> 1; + x = x | x >> 2; + x = x | x >> 4; + x = x | x >> 16; + x = x + 1; + return x; + } +void wait_for_event(void) +{ + DEBUG_PRINT("Waiting for event\n"); + pthread_mutex_lock(&lock); + while (event_is_done == 0) { + pthread_cond_wait(&cond, &lock); + } + event_is_done = 0; + pthread_mutex_unlock(&lock); + DEBUG_PRINT("Running .... get the event\n"); +} + +void event_complete(void ) +{ + pthread_mutex_lock(&lock); + if (event_is_done == 0) { + event_is_done = 1; + pthread_cond_broadcast(&cond); + } + pthread_mutex_unlock(&lock); +} +int get_next_command(FILE *seq_file) +{ + int i = -1; + do{ + i++; + if(fread(&curr_seq_command[i], 1, 1, seq_file) != 1) + return -1; + }while(curr_seq_command[i] != '\n'); + curr_seq_command[i] = 0; + printf("\n cmd_str = %s", curr_seq_command); + return 0; +} + +int process_current_command(const char *seq_command) +{ + char *data_str = NULL; + unsigned int data = 0, bufCnt = 0, i = 0; + int frameSize; + + if(strstr(seq_command, "pause") == seq_command) + { + printf("\n\n $$$$$ PAUSE $$$$$"); + data_str = (char*)seq_command + strlen("pause") + 1; + data = atoi(data_str); + printf("\n After frame number %u", data); + cmd_data = data; + sem_wait(&seq_sem); + if (!bOutputEosReached && !bInputEosReached) + { + printf("\n Sending PAUSE cmd to OMX compt"); + OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0); + wait_for_event(); + printf("\n EventHandler for PAUSE DONE"); + } + else + seq_enabled = 0; + } + else if(strstr(seq_command, "sleep") == seq_command) + { + printf("\n\n $$$$$ SLEEP $$$$$"); + data_str = (char*)seq_command + strlen("sleep") + 1; + data = atoi(data_str); + printf("\n Sleep Time = %u ms", data); + usleep(data*1000); + } + else if(strstr(seq_command, "resume") == seq_command) + { + printf("\n\n $$$$$ RESUME $$$$$"); + printf("\n Immediate effect"); + printf("\n Sending RESUME cmd to OMX compt"); + OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0); + wait_for_event(); + printf("\n EventHandler for RESUME DONE"); + } + else if(strstr(seq_command, "flush") == seq_command) + { + printf("\n\n $$$$$ FLUSH $$$$$"); + data_str = (char*)seq_command + strlen("flush") + 1; + data = atoi(data_str); + printf("\n After frame number %u", data); + if (previous_vc1_au) + { + printf("\n Flush not allowed on Field boundary"); + return 0; + } + cmd_data = data; + sem_wait(&seq_sem); + if (!bOutputEosReached && !bInputEosReached) + { + printf("\n Sending FLUSH cmd to OMX compt"); + flush_input_progress = 1; + flush_output_progress = 1; + OMX_SendCommand(dec_handle, OMX_CommandFlush, OMX_ALL, 0); + wait_for_event(); + printf("\n EventHandler for FLUSH DONE"); + printf("\n Post EBD_thread flush sem"); + sem_post(&in_flush_sem); + printf("\n Post FBD_thread flush sem"); + sem_post(&out_flush_sem); + } + else + seq_enabled = 0; + } + else if(strstr(seq_command, "disable_op") == seq_command) + { + printf("\n\n $$$$$ DISABLE OP PORT $$$$$"); + data_str = (char*)seq_command + strlen("disable_op") + 1; + data = atoi(data_str); + printf("\n After frame number %u", data); + cmd_data = data; + sem_wait(&seq_sem); + printf("\n Sending DISABLE OP cmd to OMX compt"); + if (disable_output_port() != 0) + { + printf("\n ERROR: While DISABLE OP..."); + do_freeHandle_and_clean_up(true); + return -1; + } + else + printf("\n EventHandler for DISABLE OP"); + } + else if(strstr(seq_command, "enable_op") == seq_command) + { + printf("\n\n $$$$$ ENABLE OP PORT $$$$$"); + data_str = (char*)seq_command + strlen("enable_op") + 1; + printf("\n Sending ENABLE OP cmd to OMX compt"); + if (enable_output_port() != 0) + { + printf("\n ERROR: While ENABLE OP..."); + do_freeHandle_and_clean_up(true); + return -1; + } + else + printf("\n EventHandler for ENABLE OP"); + } + else + { + printf("\n\n $$$$$ INVALID CMD $$$$$"); + printf("\n seq_command[%s] is invalid", seq_command); + seq_enabled = 0; + } + return 0; +} + +void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement) +{ + printf("id (%d)\n", + framePackingArrangement.id); + printf("cancel_flag (%d)\n", + framePackingArrangement.cancel_flag); + printf("type (%d)\n", + framePackingArrangement.type); + printf("quincunx_sampling_flag (%d)\n", + framePackingArrangement.quincunx_sampling_flag); + printf("content_interpretation_type (%d)\n", + framePackingArrangement.content_interpretation_type); + printf("spatial_flipping_flag (%d)\n", + framePackingArrangement.spatial_flipping_flag); + printf("frame0_flipped_flag (%d)\n", + framePackingArrangement.frame0_flipped_flag); + printf("field_views_flag (%d)\n", + framePackingArrangement.field_views_flag); + printf("current_frame_is_frame0_flag (%d)\n", + framePackingArrangement.current_frame_is_frame0_flag); + printf("frame0_self_contained_flag (%d)\n", + framePackingArrangement.frame0_self_contained_flag); + printf("frame1_self_contained_flag (%d)\n", + framePackingArrangement.frame1_self_contained_flag); + printf("frame0_grid_position_x (%d)\n", + framePackingArrangement.frame0_grid_position_x); + printf("frame0_grid_position_y (%d)\n", + framePackingArrangement.frame0_grid_position_y); + printf("frame1_grid_position_x (%d)\n", + framePackingArrangement.frame1_grid_position_x); + printf("frame1_grid_position_y (%d)\n", + framePackingArrangement.frame1_grid_position_y); + printf("reserved_byte (%d)\n", + framePackingArrangement.reserved_byte); + printf("repetition_period (%d)\n", + framePackingArrangement.repetition_period); + printf("extension_flag (%d)\n", + framePackingArrangement.extension_flag); +} +void* ebd_thread(void* pArg) +{ + int signal_eos = 0; + while(currentStatus != ERROR_STATE) + { + int readBytes =0; + OMX_BUFFERHEADERTYPE* pBuffer = NULL; + + if(flush_input_progress) + { + DEBUG_PRINT("\n EBD_thread flush wait start"); + sem_wait(&in_flush_sem); + DEBUG_PRINT("\n EBD_thread flush wait complete"); + } + + sem_wait(&etb_sem); + pthread_mutex_lock(&etb_lock); + pBuffer = (OMX_BUFFERHEADERTYPE *) pop(etb_queue); + pthread_mutex_unlock(&etb_lock); + if(pBuffer == NULL) + { + DEBUG_PRINT_ERROR("Error - No etb pBuffer to dequeue\n"); + continue; + } + + if (num_frames_to_decode && (etb_count >= num_frames_to_decode)) { + printf("\n Signal EOS %d frames decoded \n", num_frames_to_decode); + signal_eos = 1; + } + + pBuffer->nOffset = 0; + if(((readBytes = Read_Buffer(pBuffer)) > 0) && !signal_eos) { + pBuffer->nFilledLen = readBytes; + DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pBuffer->nTimeStamp); + OMX_EmptyThisBuffer(dec_handle,pBuffer); + etb_count++; + } + else + { + pBuffer->nFlags |= OMX_BUFFERFLAG_EOS; + bInputEosReached = true; + pBuffer->nFilledLen = readBytes; + DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pBuffer->nTimeStamp); + OMX_EmptyThisBuffer(dec_handle,pBuffer); + DEBUG_PRINT("EBD::Either EOS or Some Error while reading file\n"); + etb_count++; + break; + } + } + return NULL; +} + +void* fbd_thread(void* pArg) +{ + long unsigned act_time = 0, display_time = 0, render_time = 5e3, lipsync = 15e3; + struct timeval t_avsync = {0, 0}, base_avsync = {0, 0}; + float total_time = 0; + int canDisplay = 1, contigous_drop_frame = 0, bytes_written = 0, ret = 0; + OMX_S64 base_timestamp = 0, lastTimestamp = 0; + OMX_BUFFERHEADERTYPE *pBuffer = NULL, *pPrevBuff = NULL; + char value[PROPERTY_VALUE_MAX] = {0}; + OMX_U32 aspectratio_prop = 0; + pthread_mutex_lock(&eos_lock); +#ifdef _MSM8974_ + int stride,scanlines,stride_c,i; +#endif + DEBUG_PRINT("First Inside %s\n", __FUNCTION__); + property_get("vidc.vdec.debug.aspectratio", value, "0"); + aspectratio_prop = atoi(value); + while(currentStatus != ERROR_STATE && !bOutputEosReached) + { + pthread_mutex_unlock(&eos_lock); + DEBUG_PRINT("Inside %s\n", __FUNCTION__); + if(flush_output_progress) + { + DEBUG_PRINT("\n FBD_thread flush wait start"); + sem_wait(&out_flush_sem); + DEBUG_PRINT("\n FBD_thread flush wait complete"); + } + sem_wait(&fbd_sem); + pthread_mutex_lock(&enable_lock); + if (sent_disabled) + { + pthread_mutex_unlock(&enable_lock); + pthread_mutex_lock(&fbd_lock); + if (pPrevBuff != NULL ) { + if(push(fbd_queue, (void *)pBuffer)) + DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); + else + sem_post(&fbd_sem); + pPrevBuff = NULL; + } + if (free_op_buf_cnt == portFmt.nBufferCountActual) + free_output_buffers(); + pthread_mutex_unlock(&fbd_lock); + pthread_mutex_lock(&eos_lock); + continue; + } + pthread_mutex_unlock(&enable_lock); + if (anti_flickering) + pPrevBuff = pBuffer; + pthread_mutex_lock(&fbd_lock); + pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue); + pthread_mutex_unlock(&fbd_lock); + if (pBuffer == NULL) + { + if (anti_flickering) + pBuffer = pPrevBuff; + DEBUG_PRINT("Error - No pBuffer to dequeue\n"); + pthread_mutex_lock(&eos_lock); + continue; + } + else if (pBuffer->nFilledLen > 0) + { + if (!fbd_cnt) + { + gettimeofday(&t_start, NULL); + } + fbd_cnt++; + DEBUG_PRINT("%s: fbd_cnt(%d) Buf(%p) Timestamp(%lld)", + __FUNCTION__, fbd_cnt, pBuffer, pBuffer->nTimeStamp); + canDisplay = 1; + if (realtime_display) + { + if (pBuffer->nTimeStamp != (lastTimestamp + timestampInterval)) + { + DEBUG_PRINT("Unexpected timestamp[%lld]! Expected[%lld]\n", + pBuffer->nTimeStamp, lastTimestamp + timestampInterval); + } + lastTimestamp = pBuffer->nTimeStamp; + gettimeofday(&t_avsync, NULL); + if (!base_avsync.tv_sec && !base_avsync.tv_usec) + { + display_time = 0; + base_avsync = t_avsync; + base_timestamp = pBuffer->nTimeStamp; + DEBUG_PRINT("base_avsync Sec(%lu) uSec(%lu) base_timestamp(%lld)", + base_avsync.tv_sec, base_avsync.tv_usec, base_timestamp); + } + else + { + act_time = (t_avsync.tv_sec - base_avsync.tv_sec) * 1e6 + + t_avsync.tv_usec - base_avsync.tv_usec; + display_time = pBuffer->nTimeStamp - base_timestamp; + DEBUG_PRINT("%s: act_time(%lu) display_time(%lu)", + __FUNCTION__, act_time, display_time); + //Frame rcvd on time + if (((act_time + render_time) >= (display_time - lipsync) && + (act_time + render_time) <= (display_time + lipsync)) || + //Display late frame + (contigous_drop_frame > 5)) + display_time = 0; + else if ((act_time + render_time) < (display_time - lipsync)) + //Delaying early frame + display_time -= (lipsync + act_time + render_time); + else + { + //Dropping late frame + canDisplay = 0; + contigous_drop_frame++; + } + } + } + if (displayYuv && canDisplay) + { + if (display_time) + usleep(display_time); + ret = overlay_fb(pBuffer); + if (ret != 0) + { + printf("\nERROR in overlay_fb, disabling display!"); + close_display(); + displayYuv = 0; + } + usleep(render_time); + contigous_drop_frame = 0; + } + + if (takeYuvLog) + { + if (color_fmt == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) + { + printf("\n width: %d height: %d\n", crop_rect.nWidth, crop_rect.nHeight); + unsigned int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portFmt.format.video.nFrameWidth); + unsigned int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portFmt.format.video.nFrameHeight); + char *temp = (char *) pBuffer->pBuffer; + int i = 0; + + temp += (stride * (int)crop_rect.nTop) + (int)crop_rect.nLeft; + for (i = 0; i < crop_rect.nHeight; i++) { + bytes_written = fwrite(temp, crop_rect.nWidth, 1, outputBufferFile); + temp += stride; + } + + temp = (char *)pBuffer->pBuffer + stride * scanlines; + temp += (stride * (int)crop_rect.nTop) + (int)crop_rect.nLeft; + for(i = 0; i < crop_rect.nHeight/2; i++) { + bytes_written += fwrite(temp, crop_rect.nWidth, 1, outputBufferFile); + temp += stride; + } + } + else + { + bytes_written = fwrite((const char *)pBuffer->pBuffer, + pBuffer->nFilledLen,1,outputBufferFile); + } + if (bytes_written < 0) { + DEBUG_PRINT("\nFillBufferDone: Failed to write to the file\n"); + } + else { + DEBUG_PRINT("\nFillBufferDone: Wrote %d YUV bytes to the file\n", + bytes_written); + } + } +#ifdef _MSM8974_ + if (crcFile) { + uint16 crc_val; + crc_val = crc_16_l_step_nv12(CRC_INIT, pBuffer->pBuffer, + pBuffer->nFilledLen, height, width); + int num_bytes = fwrite(&crc_val, 1, sizeof(crc_val), crcFile); + if (num_bytes < sizeof(crc_val)) { + printf("Failed to write CRC value into file\n"); + } + } +#endif + if (pBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) + { + OMX_OTHER_EXTRADATATYPE *pExtra; + DEBUG_PRINT(">> BUFFER WITH EXTRA DATA RCVD <<<"); + pExtra = (OMX_OTHER_EXTRADATATYPE *) + ((unsigned)(pBuffer->pBuffer + pBuffer->nOffset + + pBuffer->nFilledLen + 3)&(~3)); + while(pExtra && + (OMX_U8*)pExtra < (pBuffer->pBuffer + pBuffer->nAllocLen) && + pExtra->eType != OMX_ExtraDataNone ) + { + DEBUG_PRINT("ExtraData : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)", + pBuffer, pBuffer->nTimeStamp, pExtra->eType, pExtra->nDataSize); + switch (pExtra->eType) + { + case OMX_ExtraDataInterlaceFormat: + { + OMX_STREAMINTERLACEFORMAT *pInterlaceFormat = (OMX_STREAMINTERLACEFORMAT *)pExtra->data; + DEBUG_PRINT("OMX_ExtraDataInterlaceFormat: Buf(%p) TSmp(%lld) IntPtr(%p) Fmt(%x)", + pBuffer->pBuffer, pBuffer->nTimeStamp, + pInterlaceFormat, pInterlaceFormat->nInterlaceFormats); + break; + } + case OMX_ExtraDataFrameInfo: + { + OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtra->data; + DEBUG_PRINT("OMX_ExtraDataFrameInfo: Buf(%p) TSmp(%lld) PicType(%u) IntT(%u) ConMB(%u)", + pBuffer->pBuffer, pBuffer->nTimeStamp, frame_info->ePicType, + frame_info->interlaceType, frame_info->nConcealedMacroblocks); + if (aspectratio_prop) + DEBUG_PRINT_ERROR(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)", + frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, + frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, + frame_info->displayAspectRatio.displayVerticalSize); + else + DEBUG_PRINT(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)", + frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, + frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, + frame_info->displayAspectRatio.displayVerticalSize); + DEBUG_PRINT("PANSCAN numWindows(%d)", frame_info->panScan.numWindows); + for (int i = 0; i < frame_info->panScan.numWindows; i++) + { + DEBUG_PRINT("WINDOW Lft(%d) Tp(%d) Rgt(%d) Bttm(%d)", + frame_info->panScan.window[i].x, + frame_info->panScan.window[i].y, + frame_info->panScan.window[i].dx, + frame_info->panScan.window[i].dy); + } + break; + } + break; + case OMX_ExtraDataConcealMB: + { + OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; + OMX_U32 concealMBnum = 0, bytes_cnt = 0; + while (bytes_cnt < pExtra->nDataSize) + { + data = *data_ptr; + while (data) + { + concealMBnum += (data&0x01); + data >>= 1; + } + data_ptr++; + bytes_cnt++; + } + DEBUG_PRINT("OMX_ExtraDataConcealMB: Buf(%p) TSmp(%lld) ConcealMB(%u)", + pBuffer->pBuffer, pBuffer->nTimeStamp, concealMBnum); + } + break; + case OMX_ExtraDataMP2ExtnData: + { + DEBUG_PRINT("\nOMX_ExtraDataMP2ExtnData"); + OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; + OMX_U32 bytes_cnt = 0; + while (bytes_cnt < pExtra->nDataSize) + { + DEBUG_PRINT("\n MPEG-2 Extension Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); + data_ptr++; + bytes_cnt++; + } + } + break; + case OMX_ExtraDataMP2UserData: + { + DEBUG_PRINT("\nOMX_ExtraDataMP2UserData"); + OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; + OMX_U32 bytes_cnt = 0; + while (bytes_cnt < pExtra->nDataSize) + { + DEBUG_PRINT("\n MPEG-2 User Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); + data_ptr++; + bytes_cnt++; + } + } + break; + default: + DEBUG_PRINT_ERROR("Unknown Extrata!"); + } + if (pExtra->nSize < (pBuffer->nAllocLen - (OMX_U32)pExtra)) + pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) pExtra) + pExtra->nSize); + else + { + DEBUG_PRINT_ERROR("ERROR: Extradata pointer overflow buffer(%p) extra(%p)", + pBuffer, pExtra); + pExtra = NULL; + } + } + } + } + if(pBuffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) + { + DEBUG_PRINT("\n"); + DEBUG_PRINT("***************************************************\n"); + DEBUG_PRINT("FillBufferDone: End Of Sequence Received\n"); + DEBUG_PRINT("***************************************************\n"); + } + if(pBuffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) + { + DEBUG_PRINT("\n"); + DEBUG_PRINT("***************************************************\n"); + DEBUG_PRINT("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); + DEBUG_PRINT("***************************************************\n"); + } + /********************************************************************/ + /* De-Initializing the open max and relasing the buffers and */ + /* closing the files.*/ + /********************************************************************/ + if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS ) + { + OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement; + OMX_GetConfig(dec_handle, + (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement, + &framePackingArrangement); + PrintFramePackArrangement(framePackingArrangement); + + gettimeofday(&t_end, NULL); + total_time = ((float) ((t_end.tv_sec - t_start.tv_sec) * 1e6 + + t_end.tv_usec - t_start.tv_usec))/ 1e6; + //total frames is fbd_cnt - 1 since the start time is + //recorded after the first frame is decoded. + printf("\nAvg decoding frame rate=%f\n", (fbd_cnt - 1)/total_time); + + DEBUG_PRINT("***************************************************\n"); + DEBUG_PRINT("FillBufferDone: End Of Stream Reached\n"); + DEBUG_PRINT("***************************************************\n"); + pthread_mutex_lock(&eos_lock); + bOutputEosReached = true; + break; + } + + pthread_mutex_lock(&enable_lock); + if (flush_output_progress || sent_disabled) + { + pBuffer->nFilledLen = 0; + pBuffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; + pthread_mutex_lock(&fbd_lock); + if ( pPrevBuff != NULL ) { + if(push(fbd_queue, (void *)pPrevBuff)) + DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); + else + sem_post(&fbd_sem); + pPrevBuff = NULL; + } + if(push(fbd_queue, (void *)pBuffer) < 0) + { + DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); + } + else + sem_post(&fbd_sem); + pthread_mutex_unlock(&fbd_lock); + } + else + { + if (!anti_flickering) + pPrevBuff = pBuffer; + if (pPrevBuff) + { + pthread_mutex_lock(&fbd_lock); + pthread_mutex_lock(&eos_lock); + if (!bOutputEosReached) + { + if ( OMX_FillThisBuffer(dec_handle, pPrevBuff) == OMX_ErrorNone ) { + free_op_buf_cnt--; + } + } + pthread_mutex_unlock(&eos_lock); + pthread_mutex_unlock(&fbd_lock); + } + } + pthread_mutex_unlock(&enable_lock); + if(cmd_data <= fbd_cnt) + { + sem_post(&seq_sem); + printf("\n Posted seq_sem Frm(%d) Req(%d)", fbd_cnt, cmd_data); + cmd_data = ~(unsigned)0; + } + pthread_mutex_lock(&eos_lock); + } + if(seq_enabled) + { + seq_enabled = 0; + sem_post(&seq_sem); + printf("\n Posted seq_sem in EOS \n"); + } + pthread_cond_broadcast(&eos_cond); + pthread_mutex_unlock(&eos_lock); + return NULL; +} + +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) +{ + DEBUG_PRINT("Function %s \n", __FUNCTION__); + + switch(eEvent) { + case OMX_EventCmdComplete: + DEBUG_PRINT("\n OMX_EventCmdComplete \n"); + if(OMX_CommandPortDisable == (OMX_COMMANDTYPE)nData1) + { + DEBUG_PRINT("*********************************************\n"); + DEBUG_PRINT("Recieved DISABLE Event Command Complete[%d]\n",nData2); + DEBUG_PRINT("*********************************************\n"); + } + else if(OMX_CommandPortEnable == (OMX_COMMANDTYPE)nData1) + { + DEBUG_PRINT("*********************************************\n"); + DEBUG_PRINT("Recieved ENABLE Event Command Complete[%d]\n",nData2); + DEBUG_PRINT("*********************************************\n"); + if (currentStatus == PORT_SETTING_CHANGE_STATE) + currentStatus = GOOD_STATE; + pthread_mutex_lock(&enable_lock); + sent_disabled = 0; + pthread_mutex_unlock(&enable_lock); + } + else if(OMX_CommandFlush == (OMX_COMMANDTYPE)nData1) + { + DEBUG_PRINT("*********************************************\n"); + DEBUG_PRINT("Received FLUSH Event Command Complete[%d]\n",nData2); + DEBUG_PRINT("*********************************************\n"); + if (nData2 == 0) + flush_input_progress = 0; + else if (nData2 == 1) + flush_output_progress = 0; + } + if (!flush_input_progress && !flush_output_progress) + event_complete(); + break; + + case OMX_EventError: + printf("*********************************************\n"); + printf("Received OMX_EventError Event Command !\n"); + printf("*********************************************\n"); + currentStatus = ERROR_STATE; + if (OMX_ErrorInvalidState == (OMX_ERRORTYPE)nData1 || + OMX_ErrorHardware == (OMX_ERRORTYPE)nData1) + { + printf("Invalid State or hardware error \n"); + if(event_is_done == 0) + { + DEBUG_PRINT("Event error in the middle of Decode \n"); + pthread_mutex_lock(&eos_lock); + bOutputEosReached = true; + pthread_mutex_unlock(&eos_lock); + if(seq_enabled) + { + seq_enabled = 0; + sem_post(&seq_sem); + printf("\n Posted seq_sem in ERROR"); + } + } + } + if (waitForPortSettingsChanged) + { + waitForPortSettingsChanged = 0; + event_complete(); + } + break; + case OMX_EventPortSettingsChanged: + DEBUG_PRINT("OMX_EventPortSettingsChanged port[%d]\n", nData1); + if (nData2 == OMX_IndexConfigCommonOutputCrop) { + OMX_U32 outPortIndex = 1; + if (nData1 == outPortIndex) { + crop_rect.nPortIndex = outPortIndex; + OMX_ERRORTYPE ret = OMX_GetConfig(dec_handle, + OMX_IndexConfigCommonOutputCrop, &crop_rect); + if (FAILED(ret)) { + DEBUG_PRINT_ERROR("Failed to get crop rectangle\n"); + break; + } else + DEBUG_PRINT("Got Crop Rect: (%d, %d) (%d x %d)\n", + crop_rect.nLeft, crop_rect.nTop, crop_rect.nWidth, crop_rect.nHeight); + } + currentStatus = GOOD_STATE; + break; + } + +#ifdef _MSM8974_ + if (nData2 != OMX_IndexParamPortDefinition) + break; +#endif + currentStatus = PORT_SETTING_CHANGE_STATE; + if (waitForPortSettingsChanged) + { + waitForPortSettingsChanged = 0; + event_complete(); + } + else + { + pthread_mutex_lock(&eos_lock); + pthread_cond_broadcast(&eos_cond); + pthread_mutex_unlock(&eos_lock); + } + break; + + case OMX_EventBufferFlag: + DEBUG_PRINT("OMX_EventBufferFlag port[%d] flags[%x]\n", nData1, nData2); +#if 0 + // we should not set the bOutputEosReached here. in stead we wait until fbd_thread to + // check the flag so that all frames can be dumped for bit exactness check. + if (nData1 == 1 && (nData2 & OMX_BUFFERFLAG_EOS)) { + pthread_mutex_lock(&eos_lock); + bOutputEosReached = true; + pthread_mutex_unlock(&eos_lock); + if(seq_enabled) + { + seq_enabled = 0; + sem_post(&seq_sem); + printf("\n Posted seq_sem in OMX_EventBufferFlag"); + } + } + else + { + DEBUG_PRINT_ERROR("OMX_EventBufferFlag Event not handled\n"); + } +#endif + break; + case OMX_EventIndexsettingChanged: + DEBUG_PRINT("OMX_EventIndexSettingChanged Interlace mode[%x]\n", nData1); + break; + default: + DEBUG_PRINT_ERROR("ERROR - Unknown Event \n"); + break; + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) +{ + int readBytes =0; int bufCnt=0; + OMX_ERRORTYPE result; + + DEBUG_PRINT("Function %s cnt[%d]\n", __FUNCTION__, ebd_cnt); + ebd_cnt++; + + + if(bInputEosReached) { + DEBUG_PRINT("*****EBD:Input EoS Reached************\n"); + return OMX_ErrorNone; + } + + pthread_mutex_lock(&etb_lock); + if(push(etb_queue, (void *) pBuffer) < 0) + { + DEBUG_PRINT_ERROR("Error in enqueue ebd data\n"); + return OMX_ErrorUndefined; + } + pthread_mutex_unlock(&etb_lock); + sem_post(&etb_sem); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent, + OMX_OUT OMX_PTR pAppData, + OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) +{ + DEBUG_PRINT("Inside %s callback_count[%d] \n", __FUNCTION__, fbd_cnt); + + /* Test app will assume there is a dynamic port setting + * In case that there is no dynamic port setting, OMX will not call event cb, + * instead OMX will send empty this buffer directly and we need to clear an event here + */ + if(waitForPortSettingsChanged) + { + waitForPortSettingsChanged = 0; + if(displayYuv) + overlay_set(); + event_complete(); + } + + pthread_mutex_lock(&fbd_lock); + free_op_buf_cnt++; + if(push(fbd_queue, (void *)pBuffer) < 0) + { + pthread_mutex_unlock(&fbd_lock); + DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); + return OMX_ErrorUndefined; + } + pthread_mutex_unlock(&fbd_lock); + sem_post(&fbd_sem); + + return OMX_ErrorNone; +} + +int main(int argc, char **argv) +{ + int i=0; + int bufCnt=0; + int num=0; + int outputOption = 0; + int test_option = 0; + int pic_order = 0; + OMX_ERRORTYPE result; + sliceheight = height = 144; + stride = width = 176; + + crop_rect.nLeft = 0; + crop_rect.nTop = 0; + crop_rect.nWidth = width; + crop_rect.nHeight = height; + + + if (argc < 2) + { + printf("To use it: ./mm-vdec-omx-test \n"); + printf("Command line argument is also available\n"); + return -1; + } + + strlcpy(in_filename, argv[1], strlen(argv[1])+1); +#ifdef _MSM8974_ + strlcpy(crclogname, argv[1], strlen(argv[1])+1); + strcat(crclogname, ".crc"); +#endif + if(argc > 2) + { + codec_format_option = (codec_format)atoi(argv[2]); + // file_type, out_op, tst_op, nal_sz, disp_win, rt_dis, (fps), color, pic_order, num_frames_to_decode + int param[10] = {2, 1, 1, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF}; + int next_arg = 3, idx = 0; + while (argc > next_arg && idx < 10) + { + if (strlen(argv[next_arg]) > 2) + { + strlcpy(seq_file_name, argv[next_arg],strlen(argv[next_arg]) + 1); + next_arg = argc; + } + else + param[idx++] = atoi(argv[next_arg++]); + } + idx = 0; + file_type_option = (file_type)param[idx++]; + if (codec_format_option == CODEC_FORMAT_H264 && file_type_option == 3) + { + nalSize = param[idx++]; + if (nalSize != 2 && nalSize != 4) + { + printf("Error - Can't pass NAL length size = %d\n", nalSize); + return -1; + } + } + outputOption = param[idx++]; + test_option = param[idx++]; + if ((outputOption == 1 || outputOption ==3) && test_option != 3) { + displayWindow = param[idx++]; + if (displayWindow > 0) + printf("Only entire display window supported! Ignoring value\n"); + realtime_display = param[idx++]; + } + if (realtime_display) + { + takeYuvLog = 0; + if(param[idx] != 0xFF) + { + fps = param[idx++]; + timestampInterval = 1e6 / fps; + } + } + color_fmt_type = (param[idx] != 0xFF)? param[idx++] : color_fmt_type; + if (test_option != 3) { + pic_order = (param[idx] != 0xFF)? param[idx++] : 0; + num_frames_to_decode = param[idx++]; + } + printf("Executing DynPortReconfig QCIF 144 x 176 \n"); + } + else + { + printf("Command line argument is available\n"); + printf("To use it: ./mm-vdec-omx-test \n"); + printf(" \n"); + printf(" \n\n\n"); + printf(" *********************************************\n"); + printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n"); + printf(" *********************************************\n"); + printf(" 1--> H264\n"); + printf(" 2--> MP4\n"); + printf(" 3--> H263\n"); + printf(" 4--> VC1\n"); + printf(" 5--> DivX\n"); + printf(" 6--> MPEG2\n"); +#ifdef _MSM8974_ + printf(" 7--> VP8\n"); + printf(" 8--> HEVC\n"); +#endif + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&codec_format_option); + fflush(stdin); + if (codec_format_option > CODEC_FORMAT_MAX) + { + printf(" Wrong test case...[%d] \n", codec_format_option); + return -1; + } + printf(" *********************************************\n"); + printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n"); + printf(" *********************************************\n"); + printf(" 1--> PER ACCESS UNIT CLIP (.dat). Clip only available for H264 and Mpeg4\n"); + printf(" 2--> ARBITRARY BYTES (need .264/.264c/.m4v/.263/.rcv/.vc1/.m2v)\n"); + if (codec_format_option == CODEC_FORMAT_H264) + { + printf(" 3--> NAL LENGTH SIZE CLIP (.264c)\n"); + printf(" 4--> START CODE BASED CLIP (.264/.h264)\n"); + } + else if ( (codec_format_option == CODEC_FORMAT_MP4) || (codec_format_option == CODEC_FORMAT_H263) ) + { + printf(" 3--> MP4 VOP or H263 P0 SHORT HEADER START CODE CLIP (.m4v or .263)\n"); + } + else if (codec_format_option == CODEC_FORMAT_VC1) + { + printf(" 3--> VC1 clip Simple/Main Profile (.rcv)\n"); + printf(" 4--> VC1 clip Advance Profile (.vc1)\n"); + } + else if (codec_format_option == CODEC_FORMAT_DIVX) + { + printf(" 3--> DivX 4, 5, 6 clip (.cmp)\n"); +#ifdef MAX_RES_1080P + printf(" 4--> DivX 3.11 clip \n"); +#endif + } + else if (codec_format_option == CODEC_FORMAT_MPEG2) + { + printf(" 3--> MPEG2 START CODE CLIP (.m2v)\n"); + } +#ifdef _MSM8974_ + else if (codec_format_option == CODEC_FORMAT_VP8) + { + printf(" 61--> VP8 START CODE CLIP (.ivf)\n"); + } +#endif + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&file_type_option); +#ifdef _MSM8974_ + if (codec_format_option == CODEC_FORMAT_VP8) + { + file_type_option = FILE_TYPE_VP8; + } +#endif + fflush(stdin); + if (codec_format_option == CODEC_FORMAT_H264 && file_type_option == 3) + { + printf(" Enter Nal length size [2 or 4] \n"); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&nalSize); + if (nalSize != 2 && nalSize != 4) + { + printf("Error - Can't pass NAL length size = %d\n", nalSize); + return -1; + } + } + + printf(" *********************************************\n"); + printf(" Output buffer option:\n"); + printf(" *********************************************\n"); + printf(" 0 --> No display and no YUV log\n"); + printf(" 1 --> Diplay YUV\n"); + printf(" 2 --> Take YUV log\n"); + printf(" 3 --> Display YUV and take YUV log\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&outputOption); + fflush(stdin); + + printf(" *********************************************\n"); + printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n"); + printf(" *********************************************\n"); + printf(" 1 --> Play the clip till the end\n"); + printf(" 2 --> Run compliance test. Do NOT expect any display for most option. \n"); + printf(" Please only see \"TEST SUCCESSFULL\" to indicate test pass\n"); + printf(" 3 --> Thumbnail decode mode\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&test_option); + fflush(stdin); + if (test_option == 3) + thumbnailMode = 1; + + if ((outputOption == 1 || outputOption == 3) && thumbnailMode == 0) + { + printf(" *********************************************\n"); + printf(" ENTER THE PORTION OF DISPLAY TO USE\n"); + printf(" *********************************************\n"); + printf(" 0 --> Entire Screen\n"); + printf(" 1 --> 1/4 th of the screen starting from top left corner to middle \n"); + printf(" 2 --> 1/4 th of the screen starting from middle to top right corner \n"); + printf(" 3 --> 1/4 th of the screen starting from middle to bottom left \n"); + printf(" 4 --> 1/4 th of the screen starting from middle to bottom right \n"); + printf(" Please only see \"TEST SUCCESSFULL\" to indidcate test pass\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&displayWindow); + fflush(stdin); + if(displayWindow > 0) + { + printf(" Curently display window 0 only supported; ignoring other values\n"); + displayWindow = 0; + } + } + + if ((outputOption == 1 || outputOption == 3) && thumbnailMode == 0) + { + printf(" *********************************************\n"); + printf(" DO YOU WANT TEST APP TO RENDER in Real time \n"); + printf(" 0 --> NO\n 1 --> YES\n"); + printf(" Warning: For H264, it require one NAL per frame clip.\n"); + printf(" For Arbitrary bytes option, Real time display is not recommended\n"); + printf(" *********************************************\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&realtime_display); + fflush(stdin); + } + + + if (realtime_display) + { + printf(" *********************************************\n"); + printf(" ENTER THE CLIP FPS\n"); + printf(" Exception: Timestamp extracted from clips will be used.\n"); + printf(" *********************************************\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&fps); + fflush(stdin); + timestampInterval = 1000000/fps; + } + + printf(" *********************************************\n"); + printf(" ENTER THE COLOR FORMAT \n"); + printf(" 0 --> Semiplanar \n 1 --> Tile Mode\n"); + printf(" *********************************************\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&color_fmt_type); + fflush(stdin); + + if (thumbnailMode != 1) { + printf(" *********************************************\n"); + printf(" Output picture order option: \n"); + printf(" *********************************************\n"); + printf(" 0 --> Display order\n 1 --> Decode order\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&pic_order); + fflush(stdin); + + printf(" *********************************************\n"); + printf(" Number of frames to decode: \n"); + printf(" 0 ---> decode all frames: \n"); + printf(" *********************************************\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&num_frames_to_decode); + fflush(stdin); + } + } + if (file_type_option >= FILE_TYPE_COMMON_CODEC_MAX) + { + switch (codec_format_option) + { + case CODEC_FORMAT_H264: + file_type_option = (file_type)(FILE_TYPE_START_OF_H264_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); + break; + case CODEC_FORMAT_DIVX: + file_type_option = (file_type)(FILE_TYPE_START_OF_DIVX_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); + break; + case CODEC_FORMAT_MP4: + case CODEC_FORMAT_H263: + file_type_option = (file_type)(FILE_TYPE_START_OF_MP4_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); + break; + case CODEC_FORMAT_VC1: + file_type_option = (file_type)(FILE_TYPE_START_OF_VC1_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); + break; + case CODEC_FORMAT_MPEG2: + file_type_option = (file_type)(FILE_TYPE_START_OF_MPEG2_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); + break; +#ifdef _MSM8974_ + case CODEC_FORMAT_VP8: + break; +#endif + default: + printf("Error: Unknown code %d\n", codec_format_option); + } + } + + CONFIG_VERSION_SIZE(picture_order); + picture_order.eOutputPictureOrder = QOMX_VIDEO_DISPLAY_ORDER; + if (pic_order == 1) + picture_order.eOutputPictureOrder = QOMX_VIDEO_DECODE_ORDER; + + if (outputOption == 0) + { + displayYuv = 0; + takeYuvLog = 0; + realtime_display = 0; + } + else if (outputOption == 1) + { + displayYuv = 1; + } + else if (outputOption == 2) + { + takeYuvLog = 1; + realtime_display = 0; + } + else if (outputOption == 3) + { + displayYuv = 1; + takeYuvLog = !realtime_display; + } + else + { + printf("Wrong option. Assume you want to see the YUV display\n"); + displayYuv = 1; + } + + if (test_option == 2) + { + printf(" *********************************************\n"); + printf(" ENTER THE COMPLIANCE TEST YOU WOULD LIKE TO EXECUTE\n"); + printf(" *********************************************\n"); + printf(" 1 --> Call Free Handle at the OMX_StateLoaded\n"); + printf(" 2 --> Call Free Handle at the OMX_StateIdle\n"); + printf(" 3 --> Call Free Handle at the OMX_StateExecuting\n"); + printf(" 4 --> Call Free Handle at the OMX_StatePause\n"); + fflush(stdin); + fgets(tempbuf,sizeof(tempbuf),stdin); + sscanf(tempbuf,"%d",&freeHandle_option); + fflush(stdin); + } + else + { + freeHandle_option = (freeHandle_test)0; + } + + printf("Input values: inputfilename[%s]\n", in_filename); + printf("*******************************************************\n"); + pthread_cond_init(&cond, 0); + pthread_cond_init(&eos_cond, 0); + pthread_mutex_init(&eos_lock, 0); + pthread_mutex_init(&lock, 0); + pthread_mutex_init(&etb_lock, 0); + pthread_mutex_init(&fbd_lock, 0); + pthread_mutex_init(&enable_lock, 0); + if (-1 == sem_init(&etb_sem, 0, 0)) + { + printf("Error - sem_init failed %d\n", errno); + } + if (-1 == sem_init(&fbd_sem, 0, 0)) + { + printf("Error - sem_init failed %d\n", errno); + } + if (-1 == sem_init(&seq_sem, 0, 0)) + { + printf("Error - sem_init failed %d\n", errno); + } + if (-1 == sem_init(&in_flush_sem, 0, 0)) + { + printf("Error - sem_init failed %d\n", errno); + } + if (-1 == sem_init(&out_flush_sem, 0, 0)) + { + printf("Error - sem_init failed %d\n", errno); + } + etb_queue = alloc_queue(); + if (etb_queue == NULL) + { + printf("\n Error in Creating etb_queue\n"); + return -1; + } + + fbd_queue = alloc_queue(); + if (fbd_queue == NULL) + { + printf("\n Error in Creating fbd_queue\n"); + free_queue(etb_queue); + return -1; + } + + if(0 != pthread_create(&fbd_thread_id, NULL, fbd_thread, NULL)) + { + printf("\n Error in Creating fbd_thread \n"); + free_queue(etb_queue); + free_queue(fbd_queue); + return -1; + } + + if (displayYuv) + { + if (open_display() != 0) + { + printf("\n Error opening display! Video won't be displayed..."); + displayYuv = 0; + } + } + + run_tests(); + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&lock); + pthread_mutex_destroy(&etb_lock); + pthread_mutex_destroy(&fbd_lock); + pthread_mutex_destroy(&enable_lock); + pthread_cond_destroy(&eos_cond); + pthread_mutex_destroy(&eos_lock); + if (-1 == sem_destroy(&etb_sem)) + { + DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); + } + if (-1 == sem_destroy(&fbd_sem)) + { + DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); + } + if (-1 == sem_destroy(&seq_sem)) + { + DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); + } + if (-1 == sem_destroy(&in_flush_sem)) + { + DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); + } + if (-1 == sem_destroy(&out_flush_sem)) + { + DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); + } + if (displayYuv) + close_display(); + return 0; +} + +int run_tests() +{ + int cmd_error = 0; + DEBUG_PRINT("Inside %s\n", __FUNCTION__); + waitForPortSettingsChanged = 1; + + if(file_type_option == FILE_TYPE_DAT_PER_AU) { + Read_Buffer = Read_Buffer_From_DAT_File; + } + else if(file_type_option == FILE_TYPE_ARBITRARY_BYTES) { + Read_Buffer = Read_Buffer_ArbitraryBytes; + } + else if(codec_format_option == CODEC_FORMAT_H264) { + if (file_type_option == FILE_TYPE_264_NAL_SIZE_LENGTH) { + Read_Buffer = Read_Buffer_From_Size_Nal; + } else if (file_type_option == FILE_TYPE_264_START_CODE_BASED) { + Read_Buffer = Read_Buffer_From_H264_Start_Code_File; + } else { + DEBUG_PRINT_ERROR("Invalid file_type_option(%d) for H264", file_type_option); + return -1; + } + } + else if((codec_format_option == CODEC_FORMAT_H263) || + (codec_format_option == CODEC_FORMAT_MP4)) { + Read_Buffer = Read_Buffer_From_Vop_Start_Code_File; + } + else if (codec_format_option == CODEC_FORMAT_MPEG2) { + Read_Buffer = Read_Buffer_From_Mpeg2_Start_Code; + } + else if(file_type_option == FILE_TYPE_DIVX_4_5_6) { + Read_Buffer = Read_Buffer_From_DivX_4_5_6_File; + } +#ifdef MAX_RES_1080P + else if(file_type_option == FILE_TYPE_DIVX_311) { + Read_Buffer = Read_Buffer_From_DivX_311_File; + } +#endif + else if(file_type_option == FILE_TYPE_RCV) { + Read_Buffer = Read_Buffer_From_RCV_File; + } +#ifdef _MSM8974_ + else if(file_type_option == FILE_TYPE_VP8) { + Read_Buffer = Read_Buffer_From_VP8_File; + } +#endif + else if(file_type_option == FILE_TYPE_VC1) { + Read_Buffer = Read_Buffer_From_VC1_File; + } + + DEBUG_PRINT("file_type_option %d!\n", file_type_option); + + switch(file_type_option) + { + case FILE_TYPE_DAT_PER_AU: + case FILE_TYPE_ARBITRARY_BYTES: + case FILE_TYPE_264_START_CODE_BASED: + case FILE_TYPE_264_NAL_SIZE_LENGTH: + case FILE_TYPE_PICTURE_START_CODE: + case FILE_TYPE_MPEG2_START_CODE: + case FILE_TYPE_RCV: + case FILE_TYPE_VC1: +#ifdef _MSM8974_ + case FILE_TYPE_VP8: +#endif + case FILE_TYPE_DIVX_4_5_6: +#ifdef MAX_RES_1080P + case FILE_TYPE_DIVX_311: +#endif + if(Init_Decoder()!= 0x00) + { + DEBUG_PRINT_ERROR("Error - Decoder Init failed\n"); + return -1; + } + if(Play_Decoder() != 0x00) + { + return -1; + } + break; + default: + DEBUG_PRINT_ERROR("Error - Invalid Entry...%d\n",file_type_option); + break; + } + + anti_flickering = true; + if(strlen(seq_file_name)) + { + seqFile = fopen (seq_file_name, "rb"); + if (seqFile == NULL) + { + DEBUG_PRINT_ERROR("Error - Seq file %s could NOT be opened\n", + seq_file_name); + return -1; + } + else + { + DEBUG_PRINT("Seq file %s is opened \n", seq_file_name); + seq_enabled = 1; + anti_flickering = false; + } + } + + pthread_mutex_lock(&eos_lock); + while (bOutputEosReached == false && cmd_error == 0) + { + if(seq_enabled) + { + pthread_mutex_unlock(&eos_lock); + if(!get_next_command(seqFile)) + cmd_error = process_current_command(curr_seq_command); + else + { + printf("\n Error in get_next_cmd or EOF"); + seq_enabled = 0; + } + pthread_mutex_lock(&eos_lock); + } + else + pthread_cond_wait(&eos_cond, &eos_lock); + + if (currentStatus == PORT_SETTING_CHANGE_STATE) + { + pthread_mutex_unlock(&eos_lock); + cmd_error = output_port_reconfig(); + pthread_mutex_lock(&eos_lock); + } + } + pthread_mutex_unlock(&eos_lock); + + // Wait till EOS is reached... + if(bOutputEosReached) + do_freeHandle_and_clean_up(currentStatus == ERROR_STATE); + return 0; +} + +int Init_Decoder() +{ + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + OMX_ERRORTYPE omxresult; + OMX_U32 total = 0; + char vdecCompNames[50]; + typedef OMX_U8* OMX_U8_PTR; + char *role ="video_decoder"; + + static OMX_CALLBACKTYPE call_back = {&EventHandler, &EmptyBufferDone, &FillBufferDone}; + + int i = 0; + long bufCnt = 0; + + /* Init. the OpenMAX Core */ + DEBUG_PRINT("\nInitializing OpenMAX Core....\n"); + omxresult = OMX_Init(); + + if(OMX_ErrorNone != omxresult) { + DEBUG_PRINT_ERROR("\n Failed to Init OpenMAX core"); + return -1; + } + else { + DEBUG_PRINT_ERROR("\nOpenMAX Core Init Done\n"); + } + + /* Query for video decoders*/ + OMX_GetComponentsOfRole(role, &total, 0); + DEBUG_PRINT("\nTotal components of role=%s :%d", role, total); + + if(total) + { + /* Allocate memory for pointers to component name */ + OMX_U8** vidCompNames = (OMX_U8**)malloc((sizeof(OMX_U8*))*total); + if (vidCompNames == NULL) { + DEBUG_PRINT_ERROR("\nFailed to allocate vidCompNames\n"); + return -1; + } + + for (i = 0; i < total; ++i) { + vidCompNames[i] = (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_MAX_STRINGNAME_SIZE); + if (vidCompNames[i] == NULL) { + DEBUG_PRINT_ERROR("\nFailed to allocate vidCompNames[%d]\n", i); + return -1; + } + } + OMX_GetComponentsOfRole(role, &total, vidCompNames); + DEBUG_PRINT("\nComponents of Role:%s\n", role); + for (i = 0; i < total; ++i) { + DEBUG_PRINT("\nComponent Name [%s]\n",vidCompNames[i]); + free(vidCompNames[i]); + } + free(vidCompNames); + } + else { + DEBUG_PRINT_ERROR("No components found with Role:%s", role); + } + + if (codec_format_option == CODEC_FORMAT_H264) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.avc", 27); + //strlcpy(vdecCompNames, "OMX.SEC.qcom.video.decoder.avc", 31); + } + else if (codec_format_option == CODEC_FORMAT_MP4) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg4", 29); + } + else if (codec_format_option == CODEC_FORMAT_H263) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.h263", 28); + } + else if (codec_format_option == CODEC_FORMAT_VC1) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.vc1", 27); + } + else if (codec_format_option == CODEC_FORMAT_MPEG2) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg2", 29); + } + else if (file_type_option == FILE_TYPE_RCV) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.wmv", 27); + } + else if (file_type_option == FILE_TYPE_DIVX_4_5_6) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.divx", 28); + } +#ifdef _MSM8974_ + else if (codec_format_option == CODEC_FORMAT_VP8) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.vp8", 27); + } +#endif + else if (codec_format_option == CODEC_FORMAT_HEVC) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.hevc", 28); + } +#ifdef MAX_RES_1080P + else if (file_type_option == FILE_TYPE_DIVX_311) + { + strlcpy(vdecCompNames, "OMX.qcom.video.decoder.divx311", 31); + } +#endif + else + { + DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option); + return -1; + } + + omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&dec_handle), + (OMX_STRING)vdecCompNames, NULL, &call_back); + if (FAILED(omxresult)) { + DEBUG_PRINT_ERROR("\nFailed to Load the component:%s\n", vdecCompNames); + return -1; + } + else + { + DEBUG_PRINT("\nComponent %s is in LOADED state\n", vdecCompNames); + } + + QOMX_VIDEO_QUERY_DECODER_INSTANCES decoder_instances; + omxresult = OMX_GetConfig(dec_handle, + (OMX_INDEXTYPE)OMX_QcomIndexQueryNumberOfVideoDecInstance, + &decoder_instances); + DEBUG_PRINT("\n Number of decoder instances %d", + decoder_instances.nNumOfInstances); + + /* Get the port information */ + CONFIG_VERSION_SIZE(portParam); + omxresult = OMX_GetParameter(dec_handle, OMX_IndexParamVideoInit, + (OMX_PTR)&portParam); + + if(FAILED(omxresult)) { + DEBUG_PRINT_ERROR("ERROR - Failed to get Port Param\n"); + return -1; + } + else + { + DEBUG_PRINT("portParam.nPorts:%d\n", portParam.nPorts); + DEBUG_PRINT("portParam.nStartPortNumber:%d\n", portParam.nStartPortNumber); + } + + /* Set the compression format on i/p port */ + if (codec_format_option == CODEC_FORMAT_H264) + { + portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } + else if (codec_format_option == CODEC_FORMAT_MP4) + { + portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + } + else if (codec_format_option == CODEC_FORMAT_H263) + { + portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + } + else if (codec_format_option == CODEC_FORMAT_VC1) + { + portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; + } + else if (codec_format_option == CODEC_FORMAT_DIVX) + { + portFmt.format.video.eCompressionFormat = + (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; + } + else if (codec_format_option == CODEC_FORMAT_MPEG2) + { + portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2; + } + else if (codec_format_option == CODEC_FORMAT_HEVC) + { + portFmt.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; + } + else + { + DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option); + } + + if (thumbnailMode == 1) { + QOMX_ENABLETYPE thumbNailMode; + thumbNailMode.bEnable = OMX_TRUE; + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode, + (OMX_PTR)&thumbNailMode); + DEBUG_PRINT("Enabled Thumbnail mode\n"); + } + + return 0; +} + +int Play_Decoder() +{ + OMX_VIDEO_PARAM_PORTFORMATTYPE videoportFmt = {0}; + int i, bufCnt, index = 0; + int frameSize=0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE* pBuffer = NULL; + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + + /* open the i/p and o/p files based on the video file format passed */ + if(open_video_file()) { + DEBUG_PRINT_ERROR("Error in opening video file\n"); + return -1; + } + + OMX_QCOM_PARAM_PORTDEFINITIONTYPE inputPortFmt; + memset(&inputPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE)); + CONFIG_VERSION_SIZE(inputPortFmt); + inputPortFmt.nPortIndex = 0; // input port + switch (file_type_option) + { + case FILE_TYPE_DAT_PER_AU: + case FILE_TYPE_PICTURE_START_CODE: + case FILE_TYPE_MPEG2_START_CODE: + case FILE_TYPE_264_START_CODE_BASED: + case FILE_TYPE_RCV: + case FILE_TYPE_VC1: +#ifdef MAX_RES_1080P + case FILE_TYPE_DIVX_311: +#endif + { + inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame; + break; + } + + case FILE_TYPE_ARBITRARY_BYTES: + case FILE_TYPE_264_NAL_SIZE_LENGTH: + case FILE_TYPE_DIVX_4_5_6: + { + inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Arbitrary; + break; + } +#ifdef _MSM8974_ + case FILE_TYPE_VP8: + { + inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame; + break; + } +#endif + default: + inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Unspecified; + } + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn, + (OMX_PTR)&inputPortFmt); +#ifdef USE_EXTERN_PMEM_BUF + OMX_QCOM_PARAM_PORTDEFINITIONTYPE outPortFmt; + memset(&outPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE)); + CONFIG_VERSION_SIZE(outPortFmt); + outPortFmt.nPortIndex = 1; // output port + outPortFmt.nCacheAttr = OMX_QCOM_CacheAttrNone; + outPortFmt.nMemRegion = OMX_QCOM_MemRegionSMI; + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn, + (OMX_PTR)&outPortFmt); + + OMX_QCOM_PLATFORMPRIVATE_EXTN outPltPvtExtn; + memset(&outPltPvtExtn, 0, sizeof(OMX_QCOM_PLATFORMPRIVATE_EXTN)); + CONFIG_VERSION_SIZE(outPltPvtExtn); + outPltPvtExtn.nPortIndex = 1; // output port + outPltPvtExtn.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPlatformPvt, + (OMX_PTR)&outPltPvtExtn); + use_external_pmem_buf = OMX_TRUE; +#endif + QOMX_ENABLETYPE extra_data; + extra_data.bEnable = OMX_TRUE; +#if 0 + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamInterlaceExtraData, + (OMX_PTR)&extra_data); +#endif +#if 0 + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamConcealMBMapExtraData, + (OMX_PTR)&extra_data); +#endif +#if 1 + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamFrameInfoExtraData, + (OMX_PTR)&extra_data); +#endif +#ifdef TEST_TS_FROM_SEI + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamH264TimeInfo, + (OMX_PTR)&extra_data); +#endif +#if 0 + extra_data.bEnable = OMX_FALSE; + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamConcealMBMapExtraData, + (OMX_PTR)&extra_data); +#endif +#if 0 + extra_data.bEnable = OMX_TRUE; + OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData, + (OMX_PTR)&extra_data); +#endif + /* Query the decoder outport's min buf requirements */ + CONFIG_VERSION_SIZE(portFmt); + + /* Port for which the Client needs to obtain info */ + portFmt.nPortIndex = portParam.nStartPortNumber; + + OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); + DEBUG_PRINT("\nDec: Min Buffer Count %d\n", portFmt.nBufferCountMin); + DEBUG_PRINT("\nDec: Buffer Size %d\n", portFmt.nBufferSize); + + if(OMX_DirInput != portFmt.eDir) { + printf ("\nDec: Expect Input Port\n"); + return -1; + } +#ifdef MAX_RES_1080P + if( (codec_format_option == CODEC_FORMAT_DIVX) && + (file_type_option == FILE_TYPE_DIVX_311) ) { + + int off; + + if ( read(inputBufferFileFd, &width, 4 ) == -1 ) { + DEBUG_PRINT_ERROR("\nFailed to read width for divx\n"); + return -1; + } + + DEBUG_PRINT("\nWidth for DIVX = %d\n", width); + + if ( read(inputBufferFileFd, &height, 4 ) == -1 ) { + DEBUG_PRINT_ERROR("\nFailed to read height for divx\n"); + return -1; + } + + DEBUG_PRINT("\nHeight for DIVX = %u\n", height); + sliceheight = height; + stride = width; + } +#endif +#ifdef _MSM8974_ + if( (codec_format_option == CODEC_FORMAT_VC1) && + (file_type_option == FILE_TYPE_RCV) ) { + //parse struct_A data to get height and width information + unsigned int temp; + lseek64(inputBufferFileFd, 0, SEEK_SET); + if (read(inputBufferFileFd, &temp, 4) < 0) { + DEBUG_PRINT_ERROR("\nFailed to read vc1 data\n"); + return -1; + } + //Refer to Annex L of SMPTE 421M-2006 VC1 decoding standard + //We need to skip 12 bytes after 0xC5 in sequence layer data + //structure to read struct_A, which includes height and + //width information. + if ((temp & 0xFF000000) == 0xC5000000) { + lseek64(inputBufferFileFd, 12, SEEK_SET); + + if ( read(inputBufferFileFd, &height, 4 ) < -1 ) { + DEBUG_PRINT_ERROR("\nFailed to read height for vc-1\n"); + return -1; + } + if ( read(inputBufferFileFd, &width, 4 ) == -1 ) { + DEBUG_PRINT_ERROR("\nFailed to read width for vc-1\n"); + return -1; + } + lseek64(inputBufferFileFd, 0, SEEK_SET); + } + if ((temp & 0xFF000000) == 0x85000000) { + lseek64(inputBufferFileFd, 0, SEEK_SET); + } + DEBUG_PRINT("\n RCV clip width = %u height = %u \n",width, height); + } +#endif + crop_rect.nWidth = width; + crop_rect.nHeight = height; + + bufCnt = 0; + portFmt.format.video.nFrameHeight = height; + portFmt.format.video.nFrameWidth = width; + portFmt.format.video.xFramerate = fps; + OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition, (OMX_PTR)&portFmt); + OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition, &portFmt); + DEBUG_PRINT("\nDec: New Min Buffer Count %d", portFmt.nBufferCountMin); + CONFIG_VERSION_SIZE(videoportFmt); +#ifdef MAX_RES_720P + if(color_fmt_type == 0) + { + color_fmt = OMX_COLOR_FormatYUV420SemiPlanar; + } + else + { + color_fmt = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; + } +#elif _MSM8974_ + color_fmt = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; +#else + color_fmt = (OMX_COLOR_FORMATTYPE) + QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; +#endif + + while (ret == OMX_ErrorNone) + { + videoportFmt.nPortIndex = 1; + videoportFmt.nIndex = index; + ret = OMX_GetParameter(dec_handle, OMX_IndexParamVideoPortFormat, + (OMX_PTR)&videoportFmt); + + if((ret == OMX_ErrorNone) && (videoportFmt.eColorFormat == + color_fmt)) + { + DEBUG_PRINT("\n Format[%u] supported by OMX Decoder", color_fmt); + break; + } + index++; + } + + if(ret == OMX_ErrorNone) + { + if(OMX_SetParameter(dec_handle, OMX_IndexParamVideoPortFormat, + (OMX_PTR)&videoportFmt) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\n Setting Tile format failed"); + return -1; + } + } + else + { + DEBUG_PRINT_ERROR("\n Error in retrieving supported color formats"); + return -1; + } + picture_order.nPortIndex = 1; + DEBUG_PRINT("\nSet picture order\n"); + if(OMX_SetParameter(dec_handle, + (OMX_INDEXTYPE)OMX_QcomIndexParamVideoDecoderPictureOrder, + (OMX_PTR)&picture_order) != OMX_ErrorNone) + { + printf("\n ERROR: Setting picture order!"); + return -1; + } + DEBUG_PRINT("\nVideo format: W x H (%d x %d)", + portFmt.format.video.nFrameWidth, + portFmt.format.video.nFrameHeight); + if(codec_format_option == CODEC_FORMAT_H264 || + codec_format_option == CODEC_FORMAT_HEVC) + { + OMX_VIDEO_CONFIG_NALSIZE naluSize; + naluSize.nNaluBytes = nalSize; + DEBUG_PRINT("\n Nal length is %d index %d",nalSize,OMX_IndexConfigVideoNalSize); + OMX_SetConfig(dec_handle,OMX_IndexConfigVideoNalSize,(OMX_PTR)&naluSize); + DEBUG_PRINT("SETTING THE NAL SIZE to %d\n",naluSize.nNaluBytes); + } + DEBUG_PRINT("\nOMX_SendCommand Decoder -> IDLE\n"); + OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle,0); + + input_buf_cnt = portFmt.nBufferCountActual; + DEBUG_PRINT("Transition to Idle State succesful...\n"); + +#if ALLOCATE_BUFFER + // Allocate buffer on decoder's i/p port + error = Allocate_Buffer(dec_handle, &pInputBufHdrs, portFmt.nPortIndex, + portFmt.nBufferCountActual, portFmt.nBufferSize); + if (error != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Input buffer error\n"); + return -1; + } + else { + DEBUG_PRINT("\nOMX_AllocateBuffer Input buffer success\n"); + } +#else + // Use buffer on decoder's i/p port + input_use_buffer = true; + DEBUG_PRINT_ERROR("\n before OMX_UseBuffer %p", &pInputBufHdrs); + error = use_input_buffer(dec_handle, + &pInputBufHdrs, + portFmt.nPortIndex, + portFmt.nBufferSize, + portFmt.nBufferCountActual); + if (error != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed"); + return -1; + } + else { + DEBUG_PRINT("OMX_UseBuffer Input buffer success\n"); + } +#endif + portFmt.nPortIndex = portParam.nStartPortNumber+1; + // Port for which the Client needs to obtain info + + OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); + DEBUG_PRINT("nMin Buffer Count=%d", portFmt.nBufferCountMin); + DEBUG_PRINT("nBuffer Size=%d", portFmt.nBufferSize); + if(OMX_DirOutput != portFmt.eDir) { + DEBUG_PRINT_ERROR("Error - Expect Output Port\n"); + return -1; + } + + if (anti_flickering) { + ret = OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); + if (ret != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("%s: OMX_GetParameter failed: %d",__FUNCTION__, ret); + return -1; + } + portFmt.nBufferCountActual += 1; + ret = OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); + if (ret != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("%s: OMX_SetParameter failed: %d",__FUNCTION__, ret); + return -1; + } + } + +#ifndef USE_EGL_IMAGE_TEST_APP + if (use_external_pmem_buf) + { + DEBUG_PRINT_ERROR("\n Use External pmem buf: OMX_UseBuffer %p", &pInputBufHdrs); + error = use_output_buffer_multiple_fd(dec_handle, + &pOutYUVBufHdrs, + portFmt.nPortIndex, + portFmt.nBufferSize, + portFmt.nBufferCountActual); + } + else + { + /* Allocate buffer on decoder's o/p port */ + error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex, + portFmt.nBufferCountActual, portFmt.nBufferSize); + } + free_op_buf_cnt = portFmt.nBufferCountActual; + if (error != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n"); + return -1; + } + else + { + DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n"); + } +#else + DEBUG_PRINT_ERROR("\n before OMX_UseBuffer %p", &pInputBufHdrs); + error = use_output_buffer(dec_handle, + &pOutYUVBufHdrs, + portFmt.nPortIndex, + portFmt.nBufferSize, + portFmt.nBufferCountActual); + free_op_buf_cnt = portFmt.nBufferCountActual; + if (error != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed"); + return -1; + } + else { + DEBUG_PRINT("OMX_UseBuffer Input buffer success\n"); + } +#endif + wait_for_event(); + if (currentStatus == ERROR_STATE) + { + do_freeHandle_and_clean_up(true); + return -1; + } + + if (freeHandle_option == FREE_HANDLE_AT_IDLE) + { + OMX_STATETYPE state = OMX_StateInvalid; + OMX_GetState(dec_handle, &state); + if (state == OMX_StateIdle) + { + DEBUG_PRINT("Decoder is in OMX_StateIdle and trying to call OMX_FreeHandle \n"); + do_freeHandle_and_clean_up(false); + } + else + { + DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state); + do_freeHandle_and_clean_up(true); + } + return -1; + } + + + DEBUG_PRINT("OMX_SendCommand Decoder -> Executing\n"); + OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0); + wait_for_event(); + if (currentStatus == ERROR_STATE) + { + do_freeHandle_and_clean_up(true); + return -1; + } + if (pOutYUVBufHdrs == NULL) + { + DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs is NULL\n"); + return -1; + } + for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) { + DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt); + if (pOutYUVBufHdrs[bufCnt] == NULL) + { + DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs[%d] is NULL\n", bufCnt); + return -1; + } + pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1; + pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS; + ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]); + if (OMX_ErrorNone != ret) + DEBUG_PRINT_ERROR("Error - OMX_FillThisBuffer failed with result %d\n", ret); + else + { + DEBUG_PRINT("OMX_FillThisBuffer success!\n"); + free_op_buf_cnt--; + } + } + + used_ip_buf_cnt = input_buf_cnt; + + rcv_v1 = 0; + + //QPERF_START(client_decode); + if (codec_format_option == CODEC_FORMAT_VC1) + { + pInputBufHdrs[0]->nOffset = 0; + if(file_type_option == FILE_TYPE_RCV) + { + frameSize = Read_Buffer_From_RCV_File_Seq_Layer(pInputBufHdrs[0]); + pInputBufHdrs[0]->nFilledLen = frameSize; + DEBUG_PRINT("After Read_Buffer_From_RCV_File_Seq_Layer, " + "frameSize %d\n", frameSize); + } + else if(file_type_option == FILE_TYPE_VC1) + { + bHdrflag = 1; + pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]); + bHdrflag = 0; + DEBUG_PRINT_ERROR("After 1st Read_Buffer for VC1, " + "pInputBufHdrs[0]->nFilledLen %d\n", pInputBufHdrs[0]->nFilledLen); + } + else + { + pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]); + DEBUG_PRINT("After Read_Buffer pInputBufHdrs[0]->nFilledLen %d\n", + pInputBufHdrs[0]->nFilledLen); + } + + pInputBufHdrs[0]->nInputPortIndex = 0; + pInputBufHdrs[0]->nOffset = 0; +#ifndef _MSM8974_ + pInputBufHdrs[0]->nFlags = 0; +#endif + ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[0]); + if (ret != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret); + do_freeHandle_and_clean_up(true); + return -1; + } + else + { + etb_count++; + DEBUG_PRINT("OMX_EmptyThisBuffer success!\n"); + } + i = 1; +#ifdef _MSM8974_ + pInputBufHdrs[0]->nFlags = 0; +#endif + } + else + { + i = 0; + } + + for (i; i < used_ip_buf_cnt;i++) { + pInputBufHdrs[i]->nInputPortIndex = 0; + pInputBufHdrs[i]->nOffset = 0; + if((frameSize = Read_Buffer(pInputBufHdrs[i])) <= 0 ){ + DEBUG_PRINT("NO FRAME READ\n"); + pInputBufHdrs[i]->nFilledLen = frameSize; + pInputBufHdrs[i]->nInputPortIndex = 0; + pInputBufHdrs[i]->nFlags |= OMX_BUFFERFLAG_EOS;; + bInputEosReached = true; + + OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]); + etb_count++; + DEBUG_PRINT("File is small::Either EOS or Some Error while reading file\n"); + break; + } + pInputBufHdrs[i]->nFilledLen = frameSize; + pInputBufHdrs[i]->nInputPortIndex = 0; + pInputBufHdrs[i]->nFlags = 0; +//pBufHdr[bufCnt]->pAppPrivate = this; + DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pInputBufHdrs[i]->nTimeStamp); + ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]); + if (OMX_ErrorNone != ret) { + DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret); + do_freeHandle_and_clean_up(true); + return -1; + } + else { + DEBUG_PRINT("OMX_EmptyThisBuffer success!\n"); + etb_count++; + } + } + + if(0 != pthread_create(&ebd_thread_id, NULL, ebd_thread, NULL)) + { + printf("\n Error in Creating fbd_thread \n"); + free_queue(etb_queue); + free_queue(fbd_queue); + return -1; + } + + // wait for event port settings changed event + DEBUG_PRINT("wait_for_event: dyn reconfig"); + wait_for_event(); + DEBUG_PRINT("wait_for_event: dyn reconfig rcvd, currentStatus %d\n", + currentStatus); + if (currentStatus == ERROR_STATE) + { + printf("Error - ERROR_STATE\n"); + do_freeHandle_and_clean_up(true); + return -1; + } + else if (currentStatus == PORT_SETTING_CHANGE_STATE) + { + if (output_port_reconfig() != 0) + return -1; + } + + if (freeHandle_option == FREE_HANDLE_AT_EXECUTING) + { + OMX_STATETYPE state = OMX_StateInvalid; + OMX_GetState(dec_handle, &state); + if (state == OMX_StateExecuting) + { + DEBUG_PRINT("Decoder is in OMX_StateExecuting and trying to call OMX_FreeHandle \n"); + do_freeHandle_and_clean_up(false); + } + else + { + DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state); + do_freeHandle_and_clean_up(true); + } + return -1; + } + else if (freeHandle_option == FREE_HANDLE_AT_PAUSE) + { + OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0); + wait_for_event(); + + OMX_STATETYPE state = OMX_StateInvalid; + OMX_GetState(dec_handle, &state); + if (state == OMX_StatePause) + { + DEBUG_PRINT("Decoder is in OMX_StatePause and trying to call OMX_FreeHandle \n"); + do_freeHandle_and_clean_up(false); + } + else + { + DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state); + do_freeHandle_and_clean_up(true); + } + return -1; + } + + return 0; +} + +static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***pBufHdrs, + OMX_U32 nPortIndex, + long bufCntMin, long bufSize) +{ + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + OMX_ERRORTYPE error=OMX_ErrorNone; + long bufCnt=0; + + DEBUG_PRINT("pBufHdrs = %x,bufCntMin = %d\n", pBufHdrs, bufCntMin); + *pBufHdrs= (OMX_BUFFERHEADERTYPE **) + malloc(sizeof(OMX_BUFFERHEADERTYPE)*bufCntMin); + + for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { + DEBUG_PRINT("OMX_AllocateBuffer No %d \n", bufCnt); + error = OMX_AllocateBuffer(dec_handle, &((*pBufHdrs)[bufCnt]), + nPortIndex, NULL, bufSize); + } + + return error; +} + +static OMX_ERRORTYPE use_input_buffer ( OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***pBufHdrs, + OMX_U32 nPortIndex, + OMX_U32 bufSize, + long bufCntMin) +{ + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + OMX_ERRORTYPE error=OMX_ErrorNone; + long bufCnt=0; + OMX_U8* pvirt = NULL; + + *pBufHdrs= (OMX_BUFFERHEADERTYPE **) + malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin); + if(*pBufHdrs == NULL){ + DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + + for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { + // allocate input buffers + DEBUG_PRINT("OMX_UseBuffer No %d %d \n", bufCnt, bufSize); + pvirt = (OMX_U8*) malloc (bufSize); + if(pvirt == NULL){ + DEBUG_PRINT_ERROR("\n pvirt Allocation failed "); + return OMX_ErrorInsufficientResources; + } + error = OMX_UseBuffer(dec_handle, &((*pBufHdrs)[bufCnt]), + nPortIndex, NULL, bufSize, pvirt); + } + return error; +} + +static OMX_ERRORTYPE use_output_buffer ( OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***pBufHdrs, + OMX_U32 nPortIndex, + OMX_U32 bufSize, + long bufCntMin) +{ + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + OMX_ERRORTYPE error=OMX_ErrorNone; + long bufCnt=0; + OMX_U8* pvirt = NULL; + + *pBufHdrs= (OMX_BUFFERHEADERTYPE **) + malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin); + if(*pBufHdrs == NULL){ + DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + output_use_buffer = true; + p_eglHeaders = (struct temp_egl **) + malloc(sizeof(struct temp_egl *)* bufCntMin); + if (!p_eglHeaders){ + DEBUG_PRINT_ERROR("\n EGL allocation failed"); + return OMX_ErrorInsufficientResources; + } + + for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { + // allocate input buffers + DEBUG_PRINT("OMX_UseBuffer No %d %d \n", bufCnt, bufSize); + p_eglHeaders[bufCnt] = (struct temp_egl*) + malloc(sizeof(struct temp_egl)); + if(!p_eglHeaders[bufCnt]) { + DEBUG_PRINT_ERROR("\n EGL allocation failed"); + return OMX_ErrorInsufficientResources; + } + p_eglHeaders[bufCnt]->pmem_fd = open(PMEM_DEVICE,O_RDWR); + p_eglHeaders[bufCnt]->offset = 0; + if(p_eglHeaders[bufCnt]->pmem_fd < 0) { + DEBUG_PRINT_ERROR("\n open failed %s",PMEM_DEVICE); + return OMX_ErrorInsufficientResources; + } + +#ifndef USE_ION + /* TBD - this commenting is dangerous */ + align_pmem_buffers(p_eglHeaders[bufCnt]->pmem_fd, bufSize, + 8192); +#endif + DEBUG_PRINT_ERROR("\n allocation size %d pmem fd %d",bufSize,p_eglHeaders[bufCnt]->pmem_fd); + pvirt = (unsigned char *)mmap(NULL,bufSize,PROT_READ|PROT_WRITE, + MAP_SHARED,p_eglHeaders[bufCnt]->pmem_fd,0); + DEBUG_PRINT_ERROR("\n Virtaul Address %p Size %d",pvirt,bufSize); + if (pvirt == MAP_FAILED) { + DEBUG_PRINT_ERROR("\n mmap failed for buffers"); + return OMX_ErrorInsufficientResources; + } + use_buf_virt_addr[bufCnt] = (unsigned)pvirt; + error = OMX_UseEGLImage(dec_handle, &((*pBufHdrs)[bufCnt]), + nPortIndex, pvirt,(void *)p_eglHeaders[bufCnt]); + } + return error; +} + +static OMX_ERRORTYPE use_output_buffer_multiple_fd ( OMX_COMPONENTTYPE *dec_handle, + OMX_BUFFERHEADERTYPE ***pBufHdrs, + OMX_U32 nPortIndex, + OMX_U32 bufSize, + long bufCntMin) +{ + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + OMX_ERRORTYPE error=OMX_ErrorNone; + long bufCnt=0; + OMX_U8* pvirt = NULL; + + *pBufHdrs= (OMX_BUFFERHEADERTYPE **) + malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin); + if(*pBufHdrs == NULL){ + DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); + return OMX_ErrorInsufficientResources; + } + pPlatformList = (OMX_QCOM_PLATFORM_PRIVATE_LIST *) + malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST)* bufCntMin); + + if(pPlatformList == NULL){ + DEBUG_PRINT_ERROR("\n pPlatformList Allocation failed "); + return OMX_ErrorInsufficientResources; + } + + pPlatformEntry = (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) + malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY)* bufCntMin); + + if(pPlatformEntry == NULL){ + DEBUG_PRINT_ERROR("\n pPlatformEntry Allocation failed "); + return OMX_ErrorInsufficientResources; + } + + pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO)* bufCntMin); + + if(pPMEMInfo == NULL){ + DEBUG_PRINT_ERROR("\n pPMEMInfo Allocation failed "); + return OMX_ErrorInsufficientResources; + } + + //output_use_buffer = true; + for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { + // allocate input buffers + DEBUG_PRINT("OMX_UseBuffer_multiple_fd No %d %d \n", bufCnt, bufSize); + + pPlatformEntry[bufCnt].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; + pPlatformEntry[bufCnt].entry = &pPMEMInfo[bufCnt]; + // Initialize the Platform List + pPlatformList[bufCnt].nEntries = 1; + pPlatformList[bufCnt].entryList = &pPlatformEntry[bufCnt]; + pPMEMInfo[bufCnt].offset = 0; + pPMEMInfo[bufCnt].pmem_fd = open(PMEM_DEVICE,O_RDWR);; + if(pPMEMInfo[bufCnt].pmem_fd < 0) { + DEBUG_PRINT_ERROR("\n open failed %s",PMEM_DEVICE); + return OMX_ErrorInsufficientResources; + } +#ifndef USE_ION + /* TBD - this commenting is dangerous */ + align_pmem_buffers(pPMEMInfo[bufCnt].pmem_fd, bufSize, + 8192); +#endif + DEBUG_PRINT("\n allocation size %d pmem fd 0x%x",bufSize,pPMEMInfo[bufCnt].pmem_fd); + pvirt = (unsigned char *)mmap(NULL,bufSize,PROT_READ|PROT_WRITE, + MAP_SHARED,pPMEMInfo[bufCnt].pmem_fd,0); + getFreePmem(); + DEBUG_PRINT("\n Virtaul Address %p Size %d pmem_fd=0x%x",pvirt,bufSize,pPMEMInfo[bufCnt].pmem_fd); + if (pvirt == MAP_FAILED) { + DEBUG_PRINT_ERROR("\n mmap failed for buffers"); + return OMX_ErrorInsufficientResources; + } + use_buf_virt_addr[bufCnt] = (unsigned)pvirt; + error = OMX_UseBuffer(dec_handle, &((*pBufHdrs)[bufCnt]), + nPortIndex, &pPlatformList[bufCnt], bufSize, pvirt); + } + return error; +} +static void do_freeHandle_and_clean_up(bool isDueToError) +{ + int bufCnt = 0; + OMX_STATETYPE state = OMX_StateInvalid; + OMX_GetState(dec_handle, &state); + if (state == OMX_StateExecuting || state == OMX_StatePause) + { + DEBUG_PRINT("Requesting transition to Idle"); + OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle, 0); + wait_for_event(); + } + OMX_GetState(dec_handle, &state); + if (state == OMX_StateIdle) + { + DEBUG_PRINT("Requesting transition to Loaded"); + OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateLoaded, 0); + for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) + { + if (pInputBufHdrs[bufCnt]->pBuffer && input_use_buffer) + { + free(pInputBufHdrs[bufCnt]->pBuffer); + pInputBufHdrs[bufCnt]->pBuffer = NULL; + DEBUG_PRINT_ERROR("\nFree(pInputBufHdrs[%d]->pBuffer)",bufCnt); + } + OMX_FreeBuffer(dec_handle, 0, pInputBufHdrs[bufCnt]); + } + if (pInputBufHdrs) + { + free(pInputBufHdrs); + pInputBufHdrs = NULL; + } + for(bufCnt = 0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) { + if (output_use_buffer && p_eglHeaders) { + if(p_eglHeaders[bufCnt]) { + munmap (pOutYUVBufHdrs[bufCnt]->pBuffer, + pOutYUVBufHdrs[bufCnt]->nAllocLen); + close(p_eglHeaders[bufCnt]->pmem_fd); + p_eglHeaders[bufCnt]->pmem_fd = -1; + free(p_eglHeaders[bufCnt]); + p_eglHeaders[bufCnt] = NULL; + } + } + if (use_external_pmem_buf) + { + DEBUG_PRINT("Freeing in external pmem case: buffer=0x%x, pmem_fd=0x%d", + pOutYUVBufHdrs[bufCnt]->pBuffer, + pPMEMInfo[bufCnt].pmem_fd); + if (pOutYUVBufHdrs[bufCnt]->pBuffer) + { + munmap (pOutYUVBufHdrs[bufCnt]->pBuffer, + pOutYUVBufHdrs[bufCnt]->nAllocLen); + } + if (&pPMEMInfo[bufCnt]) + { + close(pPMEMInfo[bufCnt].pmem_fd); + pPMEMInfo[bufCnt].pmem_fd = -1; + } + } + OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]); + } + if(p_eglHeaders) { + free(p_eglHeaders); + p_eglHeaders = NULL; + } + if (pPMEMInfo) + { + DEBUG_PRINT("Freeing in external pmem case:PMEM"); + free(pPMEMInfo); + pPMEMInfo = NULL; + } + if (pPlatformEntry) + { + DEBUG_PRINT("Freeing in external pmem case:ENTRY"); + free(pPlatformEntry); + pPlatformEntry = NULL; + } + if (pPlatformList) + { + DEBUG_PRINT("Freeing in external pmem case:LIST"); + free(pPlatformList); + pPlatformList = NULL; + } + wait_for_event(); + } + + DEBUG_PRINT("[OMX Vdec Test] - Free handle decoder\n"); + OMX_ERRORTYPE result = OMX_FreeHandle(dec_handle); + if (result != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("[OMX Vdec Test] - OMX_FreeHandle error. Error code: %d\n", result); + } + dec_handle = NULL; + + /* Deinit OpenMAX */ + DEBUG_PRINT("[OMX Vdec Test] - De-initializing OMX \n"); + OMX_Deinit(); + + DEBUG_PRINT("[OMX Vdec Test] - closing all files\n"); + if(inputBufferFileFd != -1) + { + close(inputBufferFileFd); + inputBufferFileFd = -1; + } + + DEBUG_PRINT("[OMX Vdec Test] - after free inputfile\n"); + + if (takeYuvLog && outputBufferFile) { + fclose(outputBufferFile); + outputBufferFile = NULL; + } +#ifdef _MSM8974_ + if (crcFile) { + fclose(crcFile); + crcFile = NULL; + } +#endif + DEBUG_PRINT("[OMX Vdec Test] - after free outputfile\n"); + + if(etb_queue) + { + free_queue(etb_queue); + etb_queue = NULL; + } + DEBUG_PRINT("[OMX Vdec Test] - after free etb_queue \n"); + if(fbd_queue) + { + free_queue(fbd_queue); + fbd_queue = NULL; + } + DEBUG_PRINT("[OMX Vdec Test] - after free iftb_queue\n"); + printf("*****************************************\n"); + if (isDueToError) + printf("************...TEST FAILED...************\n"); + else + printf("**********...TEST SUCCESSFULL...*********\n"); + printf("*****************************************\n"); +} + +static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + long frameSize=0; + char temp_buffer[10]; + char temp_byte; + int bytes_read=0; + int i=0; + unsigned char *read_buffer=NULL; + char c = '1'; //initialize to anything except '\0'(0) + char inputFrameSize[12]; + int count =0; char cnt =0; + memset(temp_buffer, 0, sizeof(temp_buffer)); + + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + + while (cnt < 10) + /* Check the input file format, may result in infinite loop */ + { + DEBUG_PRINT("loop[%d] count[%d]\n",cnt,count); + count = read( inputBufferFileFd, &inputFrameSize[cnt], 1); + if(inputFrameSize[cnt] == '\0' ) + break; + cnt++; + } + inputFrameSize[cnt]='\0'; + frameSize = atoi(inputFrameSize); + pBufHdr->nFilledLen = 0; + + /* get the frame length */ + lseek64(inputBufferFileFd, -1, SEEK_CUR); + bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer, frameSize); + + DEBUG_PRINT("Actual frame Size [%d] bytes_read using fread[%d]\n", + frameSize, bytes_read); + + if(bytes_read == 0 || bytes_read < frameSize ) { + DEBUG_PRINT("Bytes read Zero After Read frame Size \n"); + DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n", + video_playback_count); + return 0; + } + pBufHdr->nTimeStamp = timeStampLfile; + timeStampLfile += timestampInterval; + return bytes_read; +} + +static int Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + int bytes_read = 0; + int cnt = 0; + unsigned int code = 0; + int naluType = 0; + int newFrame = 0; + char *dataptr = (char *)pBufHdr->pBuffer; + DEBUG_PRINT("Inside %s", __FUNCTION__); + do + { + newFrame = 0; + bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1); + if (!bytes_read) + { + DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__); + break; + } + code <<= 8; + code |= (0x000000FF & dataptr[cnt]); + cnt++; + if ((cnt == 4) && (code != H264_START_CODE)) + { + DEBUG_PRINT_ERROR("\n%s: ERROR: Invalid start code found 0x%x", __FUNCTION__, code); + cnt = 0; + break; + } + if ((cnt > 4) && (code == H264_START_CODE)) + { + DEBUG_PRINT("%s: Found H264_START_CODE", __FUNCTION__); + bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1); + if (!bytes_read) + { + DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__); + break; + } + DEBUG_PRINT("%s: READ Byte[%d] = 0x%x", __FUNCTION__, cnt, dataptr[cnt]); + naluType = dataptr[cnt] & 0x1F; + cnt++; + if ((naluType == 1) || (naluType == 5)) + { + DEBUG_PRINT("%s: Found AU", __FUNCTION__); + bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1); + if (!bytes_read) + { + DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__); + break; + } + DEBUG_PRINT("%s: READ Byte[%d] = 0x%x", __FUNCTION__, cnt, dataptr[cnt]); + newFrame = (dataptr[cnt] & 0x80); + cnt++; + if (newFrame) + { + lseek64(inputBufferFileFd, -6, SEEK_CUR); + cnt -= 6; + DEBUG_PRINT("%s: Found a NAL unit (type 0x%x) of size = %d", __FUNCTION__, (dataptr[4] & 0x1F), cnt); + break; + } + else + { + DEBUG_PRINT("%s: Not a New Frame", __FUNCTION__); + } + } + else + { + lseek64(inputBufferFileFd, -5, SEEK_CUR); + cnt -= 5; + DEBUG_PRINT("%s: Found NAL unit (type 0x%x) of size = %d", __FUNCTION__, (dataptr[4] & 0x1F), cnt); + break; + } + } + } while (1); + +#ifdef TEST_TS_FROM_SEI + if (timeStampLfile == 0) + pBufHdr->nTimeStamp = 0; + else + pBufHdr->nTimeStamp = LLONG_MAX; +#else + pBufHdr->nTimeStamp = timeStampLfile; +#endif + timeStampLfile += timestampInterval; + + return cnt; +} + +static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + int bytes_read=0; + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer, NUMBER_OF_ARBITRARYBYTES_READ); + if(bytes_read == 0) { + DEBUG_PRINT("Bytes read Zero After Read frame Size \n"); + DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n", + video_playback_count); + return 0; + } +#ifdef TEST_TS_FROM_SEI + if (timeStampLfile == 0) + pBufHdr->nTimeStamp = 0; + else + pBufHdr->nTimeStamp = LLONG_MAX; +#else + pBufHdr->nTimeStamp = timeStampLfile; +#endif + timeStampLfile += timestampInterval; + return bytes_read; +} + +static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + unsigned int readOffset = 0; + int bytes_read = 0; + unsigned int code = 0; + pBufHdr->nFilledLen = 0; + static unsigned int header_code = 0; + + DEBUG_PRINT("Inside %s", __FUNCTION__); + + do + { + //Start codes are always byte aligned. + bytes_read = read(inputBufferFileFd, &pBufHdr->pBuffer[readOffset], 1); + if(bytes_read == 0 || bytes_read == -1) + { + DEBUG_PRINT("Bytes read Zero \n"); + break; + } + code <<= 8; + code |= (0x000000FF & pBufHdr->pBuffer[readOffset]); + //VOP start code comparision + if (readOffset>3) + { + if(!header_code ){ + if( VOP_START_CODE == code) + { + header_code = VOP_START_CODE; + } + else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE ) + { + header_code = SHORT_HEADER_START_CODE; + } + } + if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE)) + { + //Seek backwards by 4 + lseek64(inputBufferFileFd, -4, SEEK_CUR); + readOffset-=3; + break; + } + else if (( header_code == SHORT_HEADER_START_CODE ) && ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00))) + { + //Seek backwards by 4 + lseek64(inputBufferFileFd, -4, SEEK_CUR); + readOffset-=3; + break; + } + } + readOffset++; + }while (1); + pBufHdr->nTimeStamp = timeStampLfile; + timeStampLfile += timestampInterval; + return readOffset; +} +static int Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + unsigned int readOffset = 0; + int bytesRead = 0; + unsigned int code = 0; + pBufHdr->nFilledLen = 0; + static unsigned int firstParse = true; + unsigned int seenFrame = false; + + DEBUG_PRINT("Inside %s", __FUNCTION__); + + /* Read one byte at a time. Construct the code every byte in order to + * compare to the start codes. Keep looping until we've read in a complete + * frame, which can be either just a picture start code + picture, or can + * include the sequence header as well + */ + while (1) { + bytesRead = read(inputBufferFileFd, &pBufHdr->pBuffer[readOffset], 1); + + /* Exit the loop if we can't read any more bytes */ + if (bytesRead == 0 || bytesRead == -1) { + break; + } + + /* Construct the code one byte at a time */ + code <<= 8; + code |= (0x000000FF & pBufHdr->pBuffer[readOffset]); + + /* Can't compare the code to MPEG2 start codes until we've read the + * first four bytes + */ + if (readOffset >= 3) { + + /* If this is the first time we're reading from the file, then we + * need to throw away the system start code information at the + * beginning. We can just look for the first sequence header. + */ + if (firstParse) { + if (code == MPEG2_SEQ_START_CODE) { + /* Seek back by 4 bytes and reset code so that we can skip + * down to the common case below. + */ + lseek(inputBufferFileFd, -4, SEEK_CUR); + code = 0; + readOffset -= 3; + firstParse = false; + continue; + } + } + + /* If we have already parsed a frame and we see a sequence header, then + * the sequence header is part of the next frame so we seek back and + * break. + */ + if (code == MPEG2_SEQ_START_CODE) { + if (seenFrame) { + lseek(inputBufferFileFd, -4, SEEK_CUR); + readOffset -= 3; + break; + } + /* If we haven't seen a frame yet, then read in all the data until we + * either see another frame start code or sequence header start code. + */ + } else if (code == MPEG2_FRAME_START_CODE) { + if (!seenFrame) { + seenFrame = true; + } else { + lseek(inputBufferFileFd, -4, SEEK_CUR); + readOffset -= 3; + break; + } + } + } + + readOffset++; + } + + pBufHdr->nTimeStamp = timeStampLfile; + timeStampLfile += timestampInterval; + return readOffset; +} + + +static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + // NAL unit stream processing + char temp_size[SIZE_NAL_FIELD_MAX]; + int i = 0; + int j = 0; + unsigned int size = 0; // Need to make sure that uint32 has SIZE_NAL_FIELD_MAX (4) bytes + int bytes_read = 0; + + // read the "size_nal_field"-byte size field + bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer + pBufHdr->nOffset, nalSize); + if (bytes_read == 0 || bytes_read == -1) + { + DEBUG_PRINT("Failed to read frame or it might be EOF\n"); + return 0; + } + + for (i=0; ipBuffer[pBufHdr->nOffset + j]; + } + size = (unsigned int)(*((unsigned int *)(temp_size))); + + // now read the data + bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer + pBufHdr->nOffset + nalSize, size); + if (bytes_read != size) + { + DEBUG_PRINT_ERROR("Failed to read frame\n"); + } + + pBufHdr->nTimeStamp = timeStampLfile; + timeStampLfile += timestampInterval; + + return bytes_read + nalSize; +} + +static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + unsigned int readOffset = 0, size_struct_C = 0; + unsigned int startcode = 0; + pBufHdr->nFilledLen = 0; +#ifdef _MSM8974_ + pBufHdr->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; +#else + pBufHdr->nFlags = 0; +#endif + + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + + read(inputBufferFileFd, &startcode, 4); + + /* read size of struct C as it need not be 4 always*/ + read(inputBufferFileFd, &size_struct_C, 4); + +#ifndef _MSM8974_ + /* reseek to beginning of sequence header */ + lseek64(inputBufferFileFd, -8, SEEK_CUR); +#endif + if ((startcode & 0xFF000000) == 0xC5000000) + { + + DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C); +#ifdef _MSM8974_ + readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, size_struct_C); + lseek64(inputBufferFileFd, 24, SEEK_CUR); +#else + readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC + size_struct_C); +#endif + } + else if((startcode & 0xFF000000) == 0x85000000) + { + // .RCV V1 file + + rcv_v1 = 1; + + DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C); +#ifdef _MSM8974_ + readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, size_struct_C); + lseek64(inputBufferFileFd, 8, SEEK_CUR); +#else + readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC + size_struct_C); +#endif + + } + else + { + DEBUG_PRINT_ERROR("Error: Unknown VC1 clip format %x\n", startcode); + } + +#if 0 + { + int i=0; + printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", readOffset, readOffset); + for (i=0; i<36; i++) + { + printf("0x%.2x ", pBufHdr->pBuffer[i]); + if (i%16 == 15) { + printf("\n"); + } + } + printf("\n"); + } +#endif + return readOffset; +} + +static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + unsigned int readOffset = 0; + unsigned int len = 0; + unsigned int key = 0; + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + + DEBUG_PRINT("Read_Buffer_From_RCV_File - nOffset %d\n", pBufHdr->nOffset); + if(rcv_v1) + { + /* for the case of RCV V1 format, the frame header is only of 4 bytes and has + only the frame size information */ + readOffset = read(inputBufferFileFd, &len, 4); + DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len); + + } + else + { + /* for a regular RCV file, 3 bytes comprise the frame size and 1 byte for key*/ + readOffset = read(inputBufferFileFd, &len, 3); + DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len); + + readOffset = read(inputBufferFileFd, &key, 1); + if ( (key & 0x80) == false) + { + DEBUG_PRINT("Read_Buffer_From_RCV_File - Non IDR frame key %x\n", key); + } + + } + + if(!rcv_v1) + { + /* There is timestamp field only for regular RCV format and not for RCV V1 format*/ + readOffset = read(inputBufferFileFd, &pBufHdr->nTimeStamp, 4); + DEBUG_PRINT("Read_Buffer_From_RCV_File - timeStamp %d\n", pBufHdr->nTimeStamp); + pBufHdr->nTimeStamp *= 1000; + } + else + { + pBufHdr->nTimeStamp = timeStampLfile; + timeStampLfile += timestampInterval; + } + + if(len > pBufHdr->nAllocLen) + { + DEBUG_PRINT_ERROR("Error in sufficient buffer framesize %d, allocalen %d noffset %d\n",len,pBufHdr->nAllocLen, pBufHdr->nOffset); + readOffset = read(inputBufferFileFd, pBufHdr->pBuffer+pBufHdr->nOffset, + pBufHdr->nAllocLen - pBufHdr->nOffset); + + loff_t off = (len - readOffset)*1LL; + lseek64(inputBufferFileFd, off ,SEEK_CUR); + return readOffset; + } + else { + readOffset = read(inputBufferFileFd, pBufHdr->pBuffer+pBufHdr->nOffset, len); + } + if (readOffset != len) + { + DEBUG_PRINT("EOS reach or Reading error %d, %s \n", readOffset, strerror( errno )); + return 0; + } + +#if 0 + { + int i=0; + printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", len, readOffset); + for (i=0; i<64; i++) + { + printf("0x%.2x ", pBufHdr->pBuffer[i]); + if (i%16 == 15) { + printf("\n"); + } + } + printf("\n"); + } +#endif + + return readOffset; +} + +static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + static int timeStampLfile = 0; + OMX_U8 *pBuffer = pBufHdr->pBuffer + pBufHdr->nOffset; + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + unsigned int readOffset = 0; + int bytes_read = 0; + unsigned int code = 0, total_bytes = 0; + int startCode_cnt = 0; + int bSEQflag = 0; + int bEntryflag = 0; + unsigned int SEQbytes = 0; + int numStartcodes = 0; + + numStartcodes = bHdrflag?1:2; + + do + { + if (total_bytes == pBufHdr->nAllocLen) + { + DEBUG_PRINT_ERROR("Buffer overflow!"); + break; + } + //Start codes are always byte aligned. + bytes_read = read(inputBufferFileFd, &pBuffer[readOffset],1 ); + + if(!bytes_read) + { + DEBUG_PRINT("\n Bytes read Zero \n"); + break; + } + total_bytes++; + code <<= 8; + code |= (0x000000FF & pBufHdr->pBuffer[readOffset]); + + if(!bSEQflag && (code == VC1_SEQUENCE_START_CODE)) { + if(startCode_cnt) bSEQflag = 1; + } + + if(!bEntryflag && ( code == VC1_ENTRY_POINT_START_CODE)) { + if(startCode_cnt) bEntryflag = 1; + } + + if(code == VC1_FRAME_START_CODE || code == VC1_FRAME_FIELD_CODE) + { + startCode_cnt++ ; + } + + //VOP start code comparision + if(startCode_cnt == numStartcodes) + { + if (VC1_FRAME_START_CODE == (code & 0xFFFFFFFF) || + VC1_FRAME_FIELD_CODE == (code & 0xFFFFFFFF)) + { + previous_vc1_au = 0; + if(VC1_FRAME_FIELD_CODE == (code & 0xFFFFFFFF)) + { + previous_vc1_au = 1; + } + + if(!bHdrflag && (bSEQflag || bEntryflag)) { + lseek(inputBufferFileFd,-(SEQbytes+4),SEEK_CUR); + readOffset -= (SEQbytes+3); + } + else { + //Seek backwards by 4 + lseek64(inputBufferFileFd, -4, SEEK_CUR); + readOffset-=3; + } + + while(pBufHdr->pBuffer[readOffset-1] == 0) + readOffset--; + + break; + } + } + readOffset++; + if(bSEQflag || bEntryflag) { + SEQbytes++; + } + }while (1); + + pBufHdr->nTimeStamp = timeStampLfile; + timeStampLfile += timestampInterval; + +#if 0 + { + int i=0; + printf("Read_Buffer_From_VC1_File, readOffset %d\n", readOffset); + for (i=0; i<64; i++) + { + printf("0x%.2x ", pBufHdr->pBuffer[i]); + if (i%16 == 15) { + printf("\n"); + } + } + printf("\n"); + } +#endif + + return readOffset; +} + +static int Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ +#define MAX_NO_B_FRMS 3 // Number of non-b-frames packed in each buffer +#define N_PREV_FRMS_B 1 // Number of previous non-b-frames packed + // with a set of consecutive b-frames +#define FRM_ARRAY_SIZE (MAX_NO_B_FRMS + N_PREV_FRMS_B) + char *p_buffer = NULL; + unsigned int offset_array[FRM_ARRAY_SIZE]; + int byte_cntr, pckt_end_idx; + unsigned int read_code = 0, bytes_read, byte_pos = 0, frame_type; + unsigned int i, b_frm_idx, b_frames_found = 0, vop_set_cntr = 0; + bool pckt_ready = false; +#ifdef __DEBUG_DIVX__ + char pckt_type[20]; + int pckd_frms = 0; + static unsigned long long int total_bytes = 0; + static unsigned long long int total_frames = 0; +#endif //__DEBUG_DIVX__ + + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + + do { + p_buffer = (char *)pBufHdr->pBuffer + byte_pos; + + bytes_read = read(inputBufferFileFd, p_buffer, NUMBER_OF_ARBITRARYBYTES_READ); + byte_pos += bytes_read; + for (byte_cntr = 0; byte_cntr < bytes_read && !pckt_ready; byte_cntr++) { + read_code <<= 8; + ((char*)&read_code)[0] = p_buffer[byte_cntr]; + if (read_code == VOP_START_CODE) { + if (++byte_cntr < bytes_read) { + frame_type = p_buffer[byte_cntr]; + frame_type &= 0x000000C0; +#ifdef __DEBUG_DIVX__ + switch (frame_type) { + case 0x00: pckt_type[pckd_frms] = 'I'; break; + case 0x40: pckt_type[pckd_frms] = 'P'; break; + case 0x80: pckt_type[pckd_frms] = 'B'; break; + default: pckt_type[pckd_frms] = 'X'; + } + pckd_frms++; +#endif // __DEBUG_DIVX__ + offset_array[vop_set_cntr] = byte_pos - bytes_read + byte_cntr - 4; + if (frame_type == 0x80) { // B Frame found! + if (!b_frames_found) { + // Try to packet N_PREV_FRMS_B previous frames + // with the next consecutive B frames + i = N_PREV_FRMS_B; + while ((vop_set_cntr - i) < 0 && i > 0) i--; + b_frm_idx = vop_set_cntr - i; + if (b_frm_idx > 0) { + pckt_end_idx = b_frm_idx; + pckt_ready = true; +#ifdef __DEBUG_DIVX__ + pckt_type[b_frm_idx] = '\0'; + total_frames += b_frm_idx; +#endif //__DEBUG_DIVX__ + } + } + b_frames_found++; + } else if (b_frames_found) { + pckt_end_idx = vop_set_cntr; + pckt_ready = true; +#ifdef __DEBUG_DIVX__ + pckt_type[pckd_frms - 1] = '\0'; + total_frames += pckd_frms - 1; +#endif //__DEBUG_DIVX__ + } else if (vop_set_cntr == (FRM_ARRAY_SIZE -1)) { + pckt_end_idx = MAX_NO_B_FRMS; + pckt_ready = true; +#ifdef __DEBUG_DIVX__ + pckt_type[pckt_end_idx] = '\0'; + total_frames += pckt_end_idx; +#endif //__DEBUG_DIVX__ + } else + vop_set_cntr++; + } else { + // The vop start code was found in the last 4 bytes, + // seek backwards by 4 to include this start code + // with the next buffer. + lseek64(inputBufferFileFd, -4, SEEK_CUR); + byte_pos -= 4; +#ifdef __DEBUG_DIVX__ + pckd_frms--; +#endif //__DEBUG_DIVX__ + } + } + } + if (pckt_ready) { + loff_t off = (byte_pos - offset_array[pckt_end_idx]); + if ( lseek64(inputBufferFileFd, -1LL*off , SEEK_CUR) == -1 ){ + DEBUG_PRINT_ERROR("lseek64 with offset = %lld failed with errno %d" + ", current position =0x%llx", -1LL*off, + errno, lseek64(inputBufferFileFd, 0, SEEK_CUR)); + } + } + else { + char eofByte; + int ret = read(inputBufferFileFd, &eofByte, 1 ); + if ( ret == 0 ) { + offset_array[vop_set_cntr] = byte_pos; + pckt_end_idx = vop_set_cntr; + pckt_ready = true; +#ifdef __DEBUG_DIVX__ + pckt_type[pckd_frms] = '\0'; + total_frames += pckd_frms; +#endif //__DEBUG_DIVX__ + } + else if (ret == 1){ + if ( lseek64(inputBufferFileFd, -1, SEEK_CUR ) == -1 ){ + DEBUG_PRINT_ERROR("lseek64 failed with errno = %d, " + "current fileposition = %llx", + errno, + lseek64(inputBufferFileFd, 0, SEEK_CUR)); + } + } + else { + DEBUG_PRINT_ERROR("Error when checking for EOF"); + } + } + } while (!pckt_ready); + pBufHdr->nFilledLen = offset_array[pckt_end_idx]; + pBufHdr->nTimeStamp = timeStampLfile; + timeStampLfile += timestampInterval; +#ifdef __DEBUG_DIVX__ + total_bytes += pBufHdr->nFilledLen; + ALOGE("[DivX] Packet: Type[%s] Size[%u] TS[%lld] TB[%llx] NFrms[%lld]\n", + pckt_type, pBufHdr->nFilledLen, pBufHdr->nTimeStamp, + total_bytes, total_frames); +#endif //__DEBUG_DIVX__ + return pBufHdr->nFilledLen; +} + +static int Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + static OMX_S64 timeStampLfile = 0; + char *p_buffer = NULL; + bool pkt_ready = false; + unsigned int frame_type = 0; + unsigned int bytes_read = 0; + unsigned int frame_size = 0; + unsigned int num_bytes_size = 4; + unsigned int num_bytes_frame_type = 1; + unsigned int n_offset = pBufHdr->nOffset; + + DEBUG_PRINT("Inside %s \n", __FUNCTION__); + + pBufHdr->nTimeStamp = timeStampLfile; + + if (pBufHdr != NULL) + { + p_buffer = (char *)pBufHdr->pBuffer + pBufHdr->nOffset; + } + else + { + DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: pBufHdr is NULL\n"); + return 0; + } + + if (p_buffer == NULL) + { + DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: p_bufhdr is NULL\n"); + return 0; + } + + //Read first frame based on size + //DivX 311 frame - 4 byte header with size followed by the frame + + bytes_read = read(inputBufferFileFd, &frame_size, num_bytes_size); + + DEBUG_PRINT("Read_Buffer_From_DivX_311_File: Frame size = %d\n", frame_size); + n_offset += read(inputBufferFileFd, p_buffer, frame_size); + + pBufHdr->nTimeStamp = timeStampLfile; + + timeStampLfile += timestampInterval; + + //the packet is ready to be sent + DEBUG_PRINT("\nReturning Read Buffer from Divx 311: TS=[%ld], Offset=[%d]\n", + (long int)pBufHdr->nTimeStamp, + n_offset ); + + return n_offset; +} +#ifdef _MSM8974_ +static int Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE *pBufHdr) +{ + static OMX_S64 timeStampLfile = 0; + char *p_buffer = NULL; + bool pkt_ready = false; + unsigned int frame_type = 0; + unsigned int bytes_read = 0; + unsigned int frame_size = 0; + unsigned int num_bytes_size = 4; + unsigned int num_bytes_frame_type = 1; + unsigned long long time_stamp; + unsigned int n_offset = pBufHdr->nOffset; + static int ivf_header_read; + + if (pBufHdr != NULL) + { + p_buffer = (char *)pBufHdr->pBuffer + pBufHdr->nOffset; + } + else + { + DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: pBufHdr is NULL\n"); + return 0; + } + + if (p_buffer == NULL) + { + DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: p_bufhdr is NULL\n"); + return 0; + } + + if(ivf_header_read == 0) { + bytes_read = read(inputBufferFileFd, p_buffer, 32); + ivf_header_read = 1; + if(p_buffer[0] == 'D' && p_buffer[1] == 'K' && p_buffer[2] == 'I' && p_buffer[3] == 'F') + { + printf(" \n IVF header found \n "); + } else + { + printf(" \n No IVF header found \n "); + lseek(inputBufferFileFd, -32, SEEK_CUR); + } + } + bytes_read = read(inputBufferFileFd, &frame_size, 4); + bytes_read = read(inputBufferFileFd, &time_stamp, 8); + n_offset += read(inputBufferFileFd, p_buffer, frame_size); + pBufHdr->nTimeStamp = time_stamp; + return n_offset; +} +#endif +static int open_video_file () +{ + int error_code = 0; + char outputfilename[512]; + DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename); + + if ( (inputBufferFileFd = open( in_filename, O_RDONLY | O_LARGEFILE) ) == -1 ){ + DEBUG_PRINT_ERROR("Error - i/p file %s could NOT be opened errno = %d\n", + in_filename, errno); + error_code = -1; + } + else { + DEBUG_PRINT_ERROR("i/p file %s is opened \n", in_filename); + } + + if (takeYuvLog) { + strlcpy(outputfilename, "yuvframes.yuv", 14); + outputBufferFile = fopen (outputfilename, "ab"); + if (outputBufferFile == NULL) + { + DEBUG_PRINT_ERROR("ERROR - o/p file %s could NOT be opened\n", outputfilename); + error_code = -1; + } + else + { + DEBUG_PRINT("O/p file %s is opened \n", outputfilename); + } + } +#ifdef _MSM8974_ + /*if (!crcFile) { + crcFile = fopen(crclogname, "ab"); + if (!crcFile) { + printf("Failed to open CRC file\n"); + error_code = -1; + } + }*/ +#endif + return error_code; +} + +void swap_byte(char *pByte, int nbyte) +{ + int i=0; + + for (i=0; isrc.width = stride; + overlayp->src.height = sliceheight; +#ifdef MAX_RES_720P + overlayp->src.format = MDP_Y_CRCB_H2V2; + if(color_fmt == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) + { + overlayp->src.format = MDP_Y_CRCB_H2V2_TILE; + } +#endif +#ifdef MAX_RES_1080P + overlayp->src.format = MDP_Y_CBCR_H2V2_TILE; +#endif +#ifdef _MSM8974_ + overlayp->src.format = MDP_Y_CBCR_H2V2_VENUS; +#endif + overlayp->src_rect.x = 0; + overlayp->src_rect.y = 0; + overlayp->src_rect.w = width; + overlayp->src_rect.h = height; + + if(width >= vinfo.xres) + { + overlayp->dst_rect.x = 0; + overlayp->dst_rect.w = vinfo.xres; + } + else + { + overlayp->dst_rect.x = (vinfo.xres - width)/2; + overlayp->dst_rect.w = width; + } + + if(height >= vinfo.yres) + { + overlayp->dst_rect.h = (overlayp->dst_rect.w * height)/width; + overlayp->dst_rect.y = 0; + if (overlayp->dst_rect.h < vinfo.yres) + overlayp->dst_rect.y = (vinfo.yres - overlayp->dst_rect.h)/2; + else + overlayp->dst_rect.h = vinfo.yres; + } + else + { + overlayp->dst_rect.y = (vinfo.yres - height)/2; + overlayp->dst_rect.h = height; + } + + //Decimation + MDP Downscale + overlayp->horz_deci = 0; + overlayp->vert_deci = 0; + int minHorDeci = 0; + if(overlayp->src_rect.w > 2048) { + //If the client sends us something > what a layer mixer supports + //then it means it doesn't want to use split-pipe but wants us to + //decimate. A minimum decimation of 2 will ensure that the width is + //always within layer mixer limits. + minHorDeci = 2; + } + + float horDscale = ceilf((float)overlayp->src_rect.w / + (float)overlayp->dst_rect.w); + float verDscale = ceilf((float)overlayp->src_rect.h / + (float)overlayp->dst_rect.h); + + //Next power of 2, if not already + horDscale = powf(2.0f, ceilf(log2f(horDscale))); + verDscale = powf(2.0f, ceilf(log2f(verDscale))); + + //Since MDP can do 1/4 dscale and has better quality, split the task + //between decimator and MDP downscale + horDscale /= 4.0f; + verDscale /= 4.0f; + + if(horDscale < minHorDeci) + horDscale = minHorDeci; + if((int)horDscale) + overlayp->horz_deci = (int)log2f(horDscale); + + if((int)verDscale) + overlayp->vert_deci = (int)log2f(verDscale); + + printf("overlayp->src.width = %u \n", overlayp->src.width); + printf("overlayp->src.height = %u \n", overlayp->src.height); + printf("overlayp->src_rect.x = %u \n", overlayp->src_rect.x); + printf("overlayp->src_rect.y = %u \n", overlayp->src_rect.y); + printf("overlayp->src_rect.w = %u \n", overlayp->src_rect.w); + printf("overlayp->src_rect.h = %u \n", overlayp->src_rect.h); + printf("overlayp->dst_rect.x = %u \n", overlayp->dst_rect.x); + printf("overlayp->dst_rect.y = %u \n", overlayp->dst_rect.y); + printf("overlayp->dst_rect.w = %u \n", overlayp->dst_rect.w); + printf("overlayp->dst_rect.h = %u \n", overlayp->dst_rect.h); + printf("overlayp->vert_deci = %u \n", overlayp->vert_deci); + printf("overlayp->horz_deci = %u \n", overlayp->horz_deci); + + overlayp->z_order = 0; + overlayp->alpha = 0xff; + overlayp->transp_mask = 0xFFFFFFFF; + overlayp->flags = 0; + overlayp->is_fg = 0; + + overlayp->id = MSMFB_NEW_REQUEST; + + overlay_vsync_ctrl(OMX_TRUE); + drawBG(); + vid_buf_front_id = ioctl(fb_fd, MSMFB_OVERLAY_SET, overlayp); + if (vid_buf_front_id < 0) + { + printf("ERROR: MSMFB_OVERLAY_SET failed! line=%d\n", __LINE__); + } + vid_buf_front_id = overlayp->id; + DEBUG_PRINT("\n vid_buf_front_id = %u", vid_buf_front_id); + displayYuv = 2; +} + +int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr) +{ + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; + struct msmfb_overlay_data ov_front; + memset(&ov_front, 0, sizeof(struct msmfb_overlay_data)); +#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) + MemoryHeapBase *vheap = NULL; +#endif + + DEBUG_PRINT("overlay_fb:"); + ov_front.id = overlayp->id; + if (pBufHdr->pPlatformPrivate == NULL) + { + ALOGE("overlay_fb: pPlatformPrivate is null"); + return -1; + } + pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) + pBufHdr->pPlatformPrivate)->entryList->entry; + if (pPMEMInfo == NULL) + { + + ALOGE("overlay_fb: pmem_info is null"); + return -1; + } +#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) + vheap = (MemoryHeapBase*)pPMEMInfo->pmem_fd; +#endif + + +#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) && !defined(_MSM8974_) + ov_front.data.memory_id = vheap->getHeapID(); +#else + ov_front.data.memory_id = pPMEMInfo->pmem_fd; +#endif + + ov_front.data.offset = pPMEMInfo->offset; + + DEBUG_PRINT("\n ov_front.data.memory_id = %d", ov_front.data.memory_id); + DEBUG_PRINT("\n ov_front.data.offset = %u", ov_front.data.offset); + if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, (void*)&ov_front)) + { + printf("\nERROR! MSMFB_OVERLAY_PLAY failed at frame (Line %d)\n", + __LINE__); + return -1; + } + if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) + { + printf("ERROR: FBIOPAN_DISPLAY failed! line=%d\n", __LINE__); + return -1; + } + + DEBUG_PRINT("\nMSMFB_OVERLAY_PLAY successfull"); + return 0; +} + +void overlay_unset() +{ + if (ioctl(fb_fd, MSMFB_OVERLAY_UNSET, &vid_buf_front_id)) + { + printf("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n", __LINE__); + } +} + +void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr) +{ + unsigned int addr = 0; + OMX_OTHER_EXTRADATATYPE *pExtraData = 0; + OMX_QCOM_EXTRADATA_FRAMEINFO *pExtraFrameInfo = 0; + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; + unsigned int destx, desty,destW, destH; +#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) + MemoryHeapBase *vheap = NULL; +#endif + + unsigned int end = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nAllocLen); + + struct mdp_blit_req *e; + union { + char dummy[sizeof(struct mdp_blit_req_list) + + sizeof(struct mdp_blit_req) * 1]; + struct mdp_blit_req_list list; + } img; + + if (fb_fd < 0) + { + DEBUG_PRINT_ERROR("Warning: /dev/fb0 is not opened!\n"); + return; + } + + img.list.count = 1; + e = &img.list.req[0]; + + addr = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nFilledLen); + // align to a 4 byte boundary + addr = (addr + 3) & (~3); + + // read to the end of existing extra data sections + pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr; + + while (addr < end && pExtraData->eType != OMX_ExtraDataFrameInfo) + { + addr += pExtraData->nSize; + pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr; + } + + if (pExtraData->eType != OMX_ExtraDataFrameInfo) + { + DEBUG_PRINT_ERROR("pExtraData->eType %d pExtraData->nSize %d\n",pExtraData->eType,pExtraData->nSize); + } + pExtraFrameInfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtraData->data; + + pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) + ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) + pBufHdr->pPlatformPrivate)->entryList->entry; +#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) + vheap = (MemoryHeapBase *)pPMEMInfo->pmem_fd; +#endif + + + DEBUG_PRINT_ERROR("DecWidth %d DecHeight %d\n",portFmt.format.video.nStride,portFmt.format.video.nSliceHeight); + DEBUG_PRINT_ERROR("DispWidth %d DispHeight %d\n",portFmt.format.video.nFrameWidth,portFmt.format.video.nFrameHeight); + + + + e->src.width = portFmt.format.video.nStride; + e->src.height = portFmt.format.video.nSliceHeight; + e->src.format = MDP_Y_CBCR_H2V2; + e->src.offset = pPMEMInfo->offset; +#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) + e->src.memory_id = vheap->getHeapID(); +#else + e->src.memory_id = pPMEMInfo->pmem_fd; +#endif + + DEBUG_PRINT_ERROR("pmemOffset %d pmemID %d\n",e->src.offset,e->src.memory_id); + + e->dst.width = vinfo.xres; + e->dst.height = vinfo.yres; + e->dst.format = MDP_RGB_565; + e->dst.offset = 0; + e->dst.memory_id = fb_fd; + + e->transp_mask = 0xffffffff; + DEBUG_PRINT("Frame interlace type %d!\n", pExtraFrameInfo->interlaceType); + if(pExtraFrameInfo->interlaceType != OMX_QCOM_InterlaceFrameProgressive) + { + DEBUG_PRINT("Interlaced Frame!\n"); + e->flags = MDP_DEINTERLACE; + } + else + e->flags = 0; + e->alpha = 0xff; + + switch(displayWindow) + { + case 1: destx = 0; + desty = 0; + destW = vinfo.xres/2; + destH = vinfo.yres/2; + break; + case 2: destx = vinfo.xres/2; + desty = 0; + destW = vinfo.xres/2; + destH = vinfo.yres/2; + break; + + case 3: destx = 0; + desty = vinfo.yres/2; + destW = vinfo.xres/2; + destH = vinfo.yres/2; + break; + case 4: destx = vinfo.xres/2; + desty = vinfo.yres/2; + destW = vinfo.xres/2; + destH = vinfo.yres/2; + break; + case 0: + default: + destx = 0; + desty = 0; + destW = vinfo.xres; + destH = vinfo.yres; + } + + + if(portFmt.format.video.nFrameWidth < destW) + destW = portFmt.format.video.nFrameWidth ; + + + if(portFmt.format.video.nFrameHeight < destH) + destH = portFmt.format.video.nFrameHeight; + + e->dst_rect.x = destx; + e->dst_rect.y = desty; + e->dst_rect.w = destW; + e->dst_rect.h = destH; + + //e->dst_rect.w = 800; + //e->dst_rect.h = 480; + + e->src_rect.x = 0; + e->src_rect.y = 0; + e->src_rect.w = portFmt.format.video.nFrameWidth; + e->src_rect.h = portFmt.format.video.nFrameHeight; + + //e->src_rect.w = portFmt.format.video.nStride; + //e->src_rect.h = portFmt.format.video.nSliceHeight; + + if (ioctl(fb_fd, MSMFB_BLIT, &img)) { + DEBUG_PRINT_ERROR("MSMFB_BLIT ioctl failed!\n"); + return; + } + + if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) { + DEBUG_PRINT_ERROR("FBIOPAN_DISPLAY failed! line=%d\n", __LINE__); + return; + } + + DEBUG_PRINT("render_fb complete!\n"); +} + +int disable_output_port() +{ + DEBUG_PRINT("DISABLING OP PORT\n"); + pthread_mutex_lock(&enable_lock); + sent_disabled = 1; + // Send DISABLE command + OMX_SendCommand(dec_handle, OMX_CommandPortDisable, 1, 0); + pthread_mutex_unlock(&enable_lock); + // wait for Disable event to come back + wait_for_event(); + if(p_eglHeaders) { + free(p_eglHeaders); + p_eglHeaders = NULL; + } + if (pPMEMInfo) + { + DEBUG_PRINT("Freeing in external pmem case:PMEM"); + free(pPMEMInfo); + pPMEMInfo = NULL; + } + if (pPlatformEntry) + { + DEBUG_PRINT("Freeing in external pmem case:ENTRY"); + free(pPlatformEntry); + pPlatformEntry = NULL; + } + if (pPlatformList) + { + DEBUG_PRINT("Freeing in external pmem case:LIST"); + free(pPlatformList); + pPlatformList = NULL; + } + if (currentStatus == ERROR_STATE) + { + do_freeHandle_and_clean_up(true); + return -1; + } + DEBUG_PRINT("OP PORT DISABLED!\n"); + return 0; +} + +int enable_output_port() +{ + int bufCnt = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + DEBUG_PRINT("ENABLING OP PORT\n"); + // Send Enable command + OMX_SendCommand(dec_handle, OMX_CommandPortEnable, 1, 0); +#ifndef USE_EGL_IMAGE_TEST_APP + /* Allocate buffer on decoder's o/p port */ + portFmt.nPortIndex = 1; + + if (anti_flickering) { + ret = OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); + if (ret != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("%s: OMX_GetParameter failed: %d",__FUNCTION__, ret); + return -1; + } + portFmt.nBufferCountActual += 1; + ret = OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); + if (ret != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("%s: OMX_SetParameter failed: %d",__FUNCTION__, ret); + return -1; + } + } + + if (use_external_pmem_buf) + { + DEBUG_PRINT("Enable op port: calling use_buffer_mult_fd\n"); + error = use_output_buffer_multiple_fd(dec_handle, + &pOutYUVBufHdrs, + portFmt.nPortIndex, + portFmt.nBufferSize, + portFmt.nBufferCountActual); + } + else + { + error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex, + portFmt.nBufferCountActual, portFmt.nBufferSize); + } + if (error != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n"); + return -1; + } + else + { + DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n"); + free_op_buf_cnt = portFmt.nBufferCountActual; + } +#else + error = use_output_buffer(dec_handle, + &pOutYUVBufHdrs, + portFmt.nPortIndex, + portFmt.nBufferSize, + portFmt.nBufferCountActual); + free_op_buf_cnt = portFmt.nBufferCountActual; + if (error != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed"); + return -1; + } + else { + DEBUG_PRINT("OMX_UseBuffer Input buffer success\n"); + } + +#endif + // wait for enable event to come back + wait_for_event(); + if (currentStatus == ERROR_STATE) + { + do_freeHandle_and_clean_up(true); + return -1; + } + if (pOutYUVBufHdrs == NULL) + { + DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs is NULL\n"); + return -1; + } + for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) { + DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt); + if (pOutYUVBufHdrs[bufCnt] == NULL) + { + DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs[%d] is NULL\n", bufCnt); + return -1; + } + pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1; + pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS; + ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]); + if (OMX_ErrorNone != ret) { + DEBUG_PRINT_ERROR("ERROR - OMX_FillThisBuffer failed with result %d\n", ret); + } + else + { + DEBUG_PRINT("OMX_FillThisBuffer success!\n"); + free_op_buf_cnt--; + } + } + DEBUG_PRINT("OP PORT ENABLED!\n"); + return 0; +} + +int output_port_reconfig() +{ + DEBUG_PRINT("PORT_SETTING_CHANGE_STATE\n"); + if (disable_output_port() != 0) + return -1; + + /* Port for which the Client needs to obtain info */ + portFmt.nPortIndex = 1; + OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); + DEBUG_PRINT("Min Buffer Count=%d", portFmt.nBufferCountMin); + DEBUG_PRINT("Buffer Size=%d", portFmt.nBufferSize); + if(OMX_DirOutput != portFmt.eDir) { + DEBUG_PRINT_ERROR("Error - Expect Output Port\n"); + return -1; + } + height = portFmt.format.video.nFrameHeight; + width = portFmt.format.video.nFrameWidth; + stride = portFmt.format.video.nStride; + sliceheight = portFmt.format.video.nSliceHeight; + + crop_rect.nWidth = width; + crop_rect.nHeight = height; + + if (displayYuv == 2) + { + DEBUG_PRINT("Reconfiguration at middle of playback..."); + close_display(); + if (open_display() != 0) + { + printf("\n Error opening display! Video won't be displayed..."); + displayYuv = 0; + } + } + + if (displayYuv) + overlay_set(); + + if (enable_output_port() != 0) + return -1; + DEBUG_PRINT("PORT_SETTING_CHANGE DONE!\n"); + return 0; +} + +void free_output_buffers() +{ + int index = 0; + OMX_BUFFERHEADERTYPE *pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue); + while (pBuffer) { + DEBUG_PRINT("\n pOutYUVBufHdrs %p p_eglHeaders %p output_use_buffer %d", + pOutYUVBufHdrs,p_eglHeaders,output_use_buffer); + if(pOutYUVBufHdrs && p_eglHeaders && output_use_buffer) + { + index = pBuffer - pOutYUVBufHdrs[0]; + DEBUG_PRINT("\n Index of free buffer %d",index); + DEBUG_PRINT("\n Address freed %p size freed %d",pBuffer->pBuffer, + pBuffer->nAllocLen); + munmap((void *)use_buf_virt_addr[index],pBuffer->nAllocLen); + if(p_eglHeaders[index]) + { + close(p_eglHeaders[index]->pmem_fd); + free(p_eglHeaders[index]); + p_eglHeaders[index] = NULL; + } + } + + if (pOutYUVBufHdrs && use_external_pmem_buf) + { + index = pBuffer - pOutYUVBufHdrs[0]; + DEBUG_PRINT("\n Address freed %p size freed %d,virt=0x%x,pmem_fd=0x%x", + pBuffer->pBuffer, + pBuffer->nAllocLen, + use_buf_virt_addr[index], + pPMEMInfo[index].pmem_fd); + munmap((void *)use_buf_virt_addr[index],pBuffer->nAllocLen); + getFreePmem(); + use_buf_virt_addr[index] = -1; + if (&pPMEMInfo[index]) + { + close(pPMEMInfo[index].pmem_fd); + pPMEMInfo[index].pmem_fd = -1; + } + } + DEBUG_PRINT("\n Free output buffer"); + OMX_FreeBuffer(dec_handle, 1, pBuffer); + pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue); + } +} + +#ifndef USE_ION +static bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, + OMX_U32 alignment) +{ + struct pmem_allocation allocation; + allocation.size = buffer_size; + allocation.align = clip2(alignment); + + if (allocation.align < 4096) + { + allocation.align = 4096; + } + if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) + { + DEBUG_PRINT_ERROR("\n Aligment failed with pmem driver"); + return false; + } + return true; +} +#endif + +int open_display() +{ +#ifdef _ANDROID_ + DEBUG_PRINT("\n Opening /dev/graphics/fb0"); + fb_fd = open("/dev/graphics/fb0", O_RDWR); +#else + DEBUG_PRINT("\n Opening /dev/fb0"); + fb_fd = open("/dev/fb0", O_RDWR); +#endif + if (fb_fd < 0) { + printf("[omx_vdec_test] - ERROR - can't open framebuffer!\n"); + return -1; + } + + DEBUG_PRINT("\n fb_fd = %d", fb_fd); + if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) + { + printf("[omx_vdec_test] - ERROR - can't retrieve fscreenInfo!\n"); + close(fb_fd); + return -1; + } + if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) + { + printf("[omx_vdec_test] - ERROR - can't retrieve vscreenInfo!\n"); + close(fb_fd); + return -1; + } + printf("Display xres = %d, yres = %d \n", vinfo.xres, vinfo.yres); + return 0; +} + +void close_display() +{ + overlay_unset(); + overlay_vsync_ctrl(OMX_FALSE); + close(fb_fd); + fb_fd = -1; +} + +void getFreePmem() +{ +#ifndef USE_ION + int ret = -1; + /*Open pmem device and query free pmem*/ + int pmem_fd = open (PMEM_DEVICE,O_RDWR); + + if(pmem_fd < 0) { + ALOGE("Unable to open pmem device"); + return; + } + struct pmem_freespace fs; + ret = ioctl(pmem_fd, PMEM_GET_FREE_SPACE, &fs); + if(ret) { + ALOGE("IOCTL to query pmem free space failed"); + goto freespace_query_failed; + } + ALOGE("Available free space %lx largest chunk %lx\n", fs.total, fs.largest); +freespace_query_failed: + close(pmem_fd); +#endif +} diff --git a/mm-video-v4l2/vidc/venc/Android.mk b/mm-video-v4l2/vidc/venc/Android.mk new file mode 100644 index 00000000..cb3429ae --- /dev/null +++ b/mm-video-v4l2/vidc/venc/Android.mk @@ -0,0 +1,172 @@ +ifneq ($(BUILD_TINY_ANDROID),true) + +ROOT_DIR := $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_PATH:= $(ROOT_DIR) + +# --------------------------------------------------------------------------------- +# Common definitons +# --------------------------------------------------------------------------------- + +libmm-venc-def := -g -O3 -Dlrintf=_ffix_r +libmm-venc-def += -D__align=__alignx +libmm-venc-def += -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\) +libmm-venc-def += -DT_ARM +libmm-venc-def += -Dinline=__inline +libmm-venc-def += -D_ANDROID_ +libmm-venc-def += -UENABLE_DEBUG_LOW +libmm-venc-def += -DENABLE_DEBUG_HIGH +libmm-venc-def += -DENABLE_DEBUG_ERROR +libmm-venc-def += -UINPUT_BUFFER_LOG +libmm-venc-def += -UOUTPUT_BUFFER_LOG +libmm-venc-def += -USINGLE_ENCODER_INSTANCE +ifeq ($(TARGET_BOARD_PLATFORM),msm8660) +libmm-venc-def += -DMAX_RES_1080P +libmm-venc-def += -UENABLE_GET_SYNTAX_HDR +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8960) +libmm-venc-def += -DMAX_RES_1080P +libmm-venc-def += -DMAX_RES_1080P_EBI +libmm-venc-def += -UENABLE_GET_SYNTAX_HDR +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8974) +libmm-venc-def += -DMAX_RES_1080P +libmm-venc-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libmm-venc-def += -D_MSM8974_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm7627a) +libmm-venc-def += -DMAX_RES_720P +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm7630_surf) +libmm-venc-def += -DMAX_RES_720P +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8610) +libmm-venc-def += -DMAX_RES_720P +libmm-venc-def += -D_MSM8974_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),msm8226) +libmm-venc-def += -DMAX_RES_1080P +libmm-venc-def += -D_MSM8974_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),apq8084) +libmm-venc-def += -DMAX_RES_1080P +libmm-venc-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libmm-venc-def += -D_MSM8974_ +endif +ifeq ($(TARGET_BOARD_PLATFORM),mpq8092) +libmm-venc-def += -DMAX_RES_1080P +libmm-venc-def += -DMAX_RES_1080P_EBI +libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT +libmm-venc-def += -D_MSM8974_ +endif + +ifeq ($(TARGET_USES_ION),true) +libmm-venc-def += -DUSE_ION +endif + +venc-inc = $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include + +libmm-venc-def += -D_ANDROID_ICS_ +# --------------------------------------------------------------------------------- +# Make the Shared library (libOmxVenc) +# --------------------------------------------------------------------------------- + +include $(CLEAR_VARS) + +libmm-venc-inc := bionic/libc/include +libmm-venc-inc += bionic/libstdc++/include +libmm-venc-inc += $(LOCAL_PATH)/inc +libmm-venc-inc += $(OMX_VIDEO_PATH)/vidc/common/inc +libmm-venc-inc += hardware/qcom/media/mm-core/inc +libmm-venc-inc += hardware/qcom/media/libstagefrighthw +libmm-venc-inc += hardware/qcom/display/libgralloc +libmm-venc-inc += frameworks/native/include/media/hardware +libmm-venc-inc += frameworks/native/include/media/openmax +libmm-venc-inc += hardware/qcom/media/libc2dcolorconvert +libmm-venc-inc += hardware/qcom/display/libcopybit +libmm-venc-inc += frameworks/av/include/media/stagefright +libmm-venc-inc += $(venc-inc) + +LOCAL_MODULE := libOmxVenc +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := $(libmm-venc-def) +LOCAL_C_INCLUDES := $(libmm-venc-inc) + +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils \ + libc2dcolorconvert libdl + +LOCAL_SRC_FILES := src/omx_video_base.cpp +LOCAL_SRC_FILES += src/omx_video_encoder.cpp +ifeq ($(call is-board-platform-in-list,msm8974 msm8610 msm8226 apq8084 mpq8092),true) +LOCAL_SRC_FILES += src/video_encoder_device_v4l2.cpp +else +LOCAL_SRC_FILES += src/video_encoder_device.cpp +endif + +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr + +LOCAL_SRC_FILES += ../common/src/extra_data_handler.cpp + +include $(BUILD_SHARED_LIBRARY) + +# ----------------------------------------------------------------------------- +# # Make the apps-test (mm-venc-omx-test720p) +# ----------------------------------------------------------------------------- + +include $(CLEAR_VARS) + +mm-venc-test720p-inc := $(TARGET_OUT_HEADERS)/mm-core +mm-venc-test720p-inc += $(LOCAL_PATH)/inc +mm-venc-test720p-inc += $(OMX_VIDEO_PATH)/vidc/common/inc +mm-venc-test720p-inc += hardware/qcom/media/mm-core/inc +mm-venc-test720p-inc += hardware/qcom/display/libgralloc +mm-venc-test720p-inc += $(venc-inc) + +LOCAL_MODULE := mm-venc-omx-test720p +LOCAL_MODULE_TAGS := optional +LOCAL_CFLAGS := $(libmm-venc-def) +LOCAL_C_INCLUDES := $(mm-venc-test720p-inc) +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr +LOCAL_PRELINK_MODULE := false +LOCAL_SHARED_LIBRARIES := libmm-omxcore libOmxVenc libbinder liblog + +LOCAL_SRC_FILES := test/venc_test.cpp +LOCAL_SRC_FILES += test/camera_test.cpp +LOCAL_SRC_FILES += test/venc_util.c +LOCAL_SRC_FILES += test/fb_test.c + +include $(BUILD_EXECUTABLE) + +# ----------------------------------------------------------------------------- +# Make the apps-test (mm-video-driver-test) +# ----------------------------------------------------------------------------- + +include $(CLEAR_VARS) + +venc-test-inc += $(LOCAL_PATH)/inc +venc-test-inc += hardware/qcom/display/libgralloc +venc-test-inc += $(venc-inc) + +LOCAL_MODULE := mm-video-encdrv-test +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := $(venc-test-inc) +LOCAL_C_INCLUDES += hardware/qcom/media/mm-core/inc + +LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr +LOCAL_PRELINK_MODULE := false + +LOCAL_SRC_FILES := test/video_encoder_test.c +LOCAL_SRC_FILES += test/queue.c + +include $(BUILD_EXECUTABLE) + +endif #BUILD_TINY_ANDROID + +# --------------------------------------------------------------------------------- +# END +# --------------------------------------------------------------------------------- + diff --git a/mm-video-v4l2/vidc/venc/inc/camera_test.h b/mm-video-v4l2/vidc/venc/inc/camera_test.h new file mode 100755 index 00000000..53bc2da6 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/camera_test.h @@ -0,0 +1,58 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef _CAMERA_TEST_H +#define _CAMERA_TEST_H + +#define EXTERN_C_START extern "C" { +#define EXTERN_C_END } + +#ifdef __cplusplus +EXTERN_C_START +#endif + +typedef void (*CameraPreviewCallback)(int nFD, + int nOffset, + void* pPhys, + void* pVirt, + long long nTimeStamp); + + +int CameraTest_Initialize(int nFrameRate, + int nFrameWidth, + int nFrameHeight, + CameraPreviewCallback pfnPreviewCallback); +int CameraTest_Run(); +int CameraTest_ReleaseFrame(void* pPhys, void* pVirt); +int CameraTest_Exit(); + + +#ifdef __cplusplus +EXTERN_C_END +#endif + +#endif diff --git a/mm-video-v4l2/vidc/venc/inc/fb_test.h b/mm-video-v4l2/vidc/venc/inc/fb_test.h new file mode 100755 index 00000000..52a007f1 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/fb_test.h @@ -0,0 +1,48 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef _FB_TEST_H +#define _FB_TEST_H + +#ifdef __cplusplus +extern "C" { +#endif + + +int FBTest_Initialize(int nFrameWidth, + int nFrameHeight); +int FBTest_DisplayImage(int nPmemFd, int nOffset); +int FBTest_Exit(); + +int FBTest_RunTest(); + +#ifdef __cplusplus +} +#endif + + +#endif // _FB_TEST_H diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h new file mode 100644 index 00000000..58b0d4fa --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h @@ -0,0 +1,621 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#ifndef __OMX_VIDEO_BASE_H__ +#define __OMX_VIDEO_BASE_H__ +/*============================================================================ + O p e n M A X Component + Video Encoder + +*//** @file comx_video_base.h + This module contains the class definition for openMAX decoder component. + +*//*========================================================================*/ + +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// + +#define LOG_TAG "OMX-VENC-720p" +#include +#include +#include +#ifdef _ANDROID_ + #include +#ifdef _ANDROID_ICS_ + #include "QComOMXMetadata.h" +#endif +#endif // _ANDROID_ +#include +#include +#include +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "qc_omx_component.h" +#include "omx_video_common.h" +#include "extra_data_handler.h" +#include +#include +#include "C2DColorConverter.h" + +#ifdef _ANDROID_ +using namespace android; +// local pmem heap object +class VideoHeap : public MemoryHeapBase +{ +public: + VideoHeap(int fd, size_t size, void* base); + virtual ~VideoHeap() {} +}; + +#include + +#else //_ANDROID_ +#define DEBUG_PRINT_LOW +#define DEBUG_PRINT_HIGH +#define DEBUG_PRINT_ERROR +#endif // _ANDROID_ + +#ifdef USE_ION + static const char* MEM_DEVICE = "/dev/ion"; + #if defined(MAX_RES_720P) && !defined(_MSM8974_) + #define MEM_HEAP_ID ION_CAMERA_HEAP_ID + #else + #ifdef _MSM8974_ + #define MEM_HEAP_ID ION_IOMMU_HEAP_ID + #else + #define MEM_HEAP_ID ION_CP_MM_HEAP_ID + #endif + #endif +#elif MAX_RES_720P +static const char* MEM_DEVICE = "/dev/pmem_adsp"; +#elif MAX_RES_1080P_EBI +static const char* MEM_DEVICE = "/dev/pmem_adsp"; +#elif MAX_RES_1080P +static const char* MEM_DEVICE = "/dev/pmem_smipool"; +#else +#error MEM_DEVICE cannot be determined. +#endif + +////////////////////////////////////////////////////////////////////////////// +// Module specific globals +////////////////////////////////////////////////////////////////////////////// + +#define OMX_SPEC_VERSION 0x00000101 + + +////////////////////////////////////////////////////////////////////////////// +// Macros +////////////////////////////////////////////////////////////////////////////// +#define PrintFrameHdr(bufHdr) DEBUG_PRINT("bufHdr %x buf %x size %d TS %d\n",\ + (unsigned) bufHdr,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\ + (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp) + +// BitMask Management logic +#define BITS_PER_BYTE 32 +#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE) +#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE) +#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE)) +#define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ + &= ~(BITMASK_FLAG(mIndex)) +#define BITMASK_SET(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ + |= BITMASK_FLAG(mIndex) +#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) +#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) == 0x0) +#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) +#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ + & BITMASK_FLAG(mIndex)) == 0x0) +#ifdef _ANDROID_ICS_ +#define MAX_NUM_INPUT_BUFFERS 32 +#endif +void* message_thread(void *); +#ifdef USE_ION +int alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data,int flag); +void free_ion_memory(struct venc_ion *buf_ion_info); +#endif + +// OMX video class +class omx_video: public qc_omx_component +{ +protected: +#ifdef _ANDROID_ICS_ + bool meta_mode_enable; + bool c2d_opened; + encoder_media_buffer_type meta_buffers[MAX_NUM_INPUT_BUFFERS]; + OMX_BUFFERHEADERTYPE *opaque_buffer_hdr[MAX_NUM_INPUT_BUFFERS]; + bool mUseProxyColorFormat; + bool get_syntaxhdr_enable; + OMX_BUFFERHEADERTYPE *psource_frame; + OMX_BUFFERHEADERTYPE *pdest_frame; + + class omx_c2d_conv { + public: + omx_c2d_conv(); + ~omx_c2d_conv(); + bool init(); + bool open(unsigned int height,unsigned int width, + ColorConvertFormat src, + ColorConvertFormat dest,unsigned int src_stride); + bool convert(int src_fd, void *src_base, void *src_viraddr, + int dest_fd, void *dest_base, void *dest_viraddr); + bool get_buffer_size(int port,unsigned int &buf_size); + int get_src_format(); + void close(); + private: + C2DColorConverterBase *c2dcc; + pthread_mutex_t c_lock; + void *mLibHandle; + ColorConvertFormat src_format; + createC2DColorConverter_t *mConvertOpen; + destroyC2DColorConverter_t *mConvertClose; + }; + omx_c2d_conv c2d_conv; +#endif +public: + omx_video(); // constructor + virtual ~omx_video(); // destructor + + // virtual int async_message_process (void *context, void* message); + void process_event_cb(void *ctxt,unsigned char id); + + OMX_ERRORTYPE allocate_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes + ); + + + virtual OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp)= 0; + + virtual OMX_ERRORTYPE component_init(OMX_STRING role)= 0; + + virtual OMX_U32 dev_stop(void) = 0; + virtual OMX_U32 dev_pause(void) = 0; + virtual OMX_U32 dev_start(void) = 0; + virtual OMX_U32 dev_flush(unsigned) = 0; + virtual OMX_U32 dev_resume(void) = 0; + virtual OMX_U32 dev_start_done(void) = 0; + virtual OMX_U32 dev_set_message_thread_id(pthread_t) = 0; + virtual bool dev_use_buf(void *,unsigned,unsigned) = 0; + virtual bool dev_free_buf(void *,unsigned) = 0; + virtual bool dev_empty_buf(void *, void *,unsigned,unsigned) = 0; + virtual bool dev_fill_buf(void *buffer, void *,unsigned,unsigned) = 0; + virtual bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32) = 0; + virtual bool dev_get_seq_hdr(void *, unsigned, unsigned *) = 0; + virtual bool dev_loaded_start(void) = 0; + virtual bool dev_loaded_stop(void) = 0; + virtual bool dev_loaded_start_done(void) = 0; + virtual bool dev_loaded_stop_done(void) = 0; +#ifdef _MSM8974_ + virtual int dev_handle_extradata(void*, int) = 0; + virtual int dev_set_format(int) = 0; +#endif + virtual bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height) = 0; + virtual bool dev_get_capability_ltrcount(OMX_U32 *, OMX_U32 *, OMX_U32 *) = 0; +#ifdef _ANDROID_ICS_ + void omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer); +#endif + OMX_ERRORTYPE component_role_enum( + OMX_HANDLETYPE hComp, + OMX_U8 *role, + OMX_U32 index + ); + + OMX_ERRORTYPE component_tunnel_request( + OMX_HANDLETYPE hComp, + OMX_U32 port, + OMX_HANDLETYPE peerComponent, + OMX_U32 peerPort, + OMX_TUNNELSETUPTYPE *tunnelSetup + ); + + OMX_ERRORTYPE empty_this_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + + + OMX_ERRORTYPE fill_this_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer + ); + + + OMX_ERRORTYPE free_buffer( + OMX_HANDLETYPE hComp, + OMX_U32 port, + OMX_BUFFERHEADERTYPE *buffer + ); + + OMX_ERRORTYPE get_component_version( + OMX_HANDLETYPE hComp, + OMX_STRING componentName, + OMX_VERSIONTYPE *componentVersion, + OMX_VERSIONTYPE *specVersion, + OMX_UUIDTYPE *componentUUID + ); + + OMX_ERRORTYPE get_config( + OMX_HANDLETYPE hComp, + OMX_INDEXTYPE configIndex, + OMX_PTR configData + ); + + OMX_ERRORTYPE get_extension_index( + OMX_HANDLETYPE hComp, + OMX_STRING paramName, + OMX_INDEXTYPE *indexType + ); + + OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE paramIndex, + OMX_PTR paramData); + + OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp, + OMX_STATETYPE *state); + + + + OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp, + OMX_COMMANDTYPE cmd, + OMX_U32 param1, + OMX_PTR cmdData); + + + OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp, + OMX_CALLBACKTYPE *callbacks, + OMX_PTR appData); + + virtual OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE configIndex, + OMX_PTR configData) = 0; + + virtual OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE paramIndex, + OMX_PTR paramData) =0; + + OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8 *buffer); + + + OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + void * eglImage); + + + + int m_pipe_in; + int m_pipe_out; + + pthread_t msg_thread_id; + pthread_t async_thread_id; + bool async_thread_created; + bool msg_thread_created; + + OMX_U8 m_nkind[128]; + + + //int *input_pmem_fd; + //int *output_pmem_fd; + struct pmem *m_pInput_pmem; + struct pmem *m_pOutput_pmem; +#ifdef USE_ION + struct venc_ion *m_pInput_ion; + struct venc_ion *m_pOutput_ion; +#endif + + + +public: + // Bit Positions + enum flags_bit_positions + { + // Defer transition to IDLE + OMX_COMPONENT_IDLE_PENDING =0x1, + // Defer transition to LOADING + OMX_COMPONENT_LOADING_PENDING =0x2, + // First Buffer Pending + OMX_COMPONENT_FIRST_BUFFER_PENDING =0x3, + // Second Buffer Pending + OMX_COMPONENT_SECOND_BUFFER_PENDING =0x4, + // Defer transition to Enable + OMX_COMPONENT_INPUT_ENABLE_PENDING =0x5, + // Defer transition to Enable + OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x6, + // Defer transition to Disable + OMX_COMPONENT_INPUT_DISABLE_PENDING =0x7, + // Defer transition to Disable + OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x8, + //defer flush notification + OMX_COMPONENT_OUTPUT_FLUSH_PENDING =0x9, + OMX_COMPONENT_INPUT_FLUSH_PENDING =0xA, + OMX_COMPONENT_PAUSE_PENDING =0xB, + OMX_COMPONENT_EXECUTE_PENDING =0xC, + OMX_COMPONENT_LOADED_START_PENDING = 0xD, + OMX_COMPONENT_LOADED_STOP_PENDING = 0xF, + + }; + + // Deferred callback identifiers + enum + { + //Event Callbacks from the venc component thread context + OMX_COMPONENT_GENERATE_EVENT = 0x1, + //Buffer Done callbacks from the venc component thread context + OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2, + //Frame Done callbacks from the venc component thread context + OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3, + //Buffer Done callbacks from the venc component thread context + OMX_COMPONENT_GENERATE_FTB = 0x4, + //Frame Done callbacks from the venc component thread context + OMX_COMPONENT_GENERATE_ETB = 0x5, + //Command + OMX_COMPONENT_GENERATE_COMMAND = 0x6, + //Push-Pending Buffers + OMX_COMPONENT_PUSH_PENDING_BUFS = 0x7, + // Empty Buffer Done callbacks + OMX_COMPONENT_GENERATE_EBD = 0x8, + //Flush Event Callbacks from the venc component thread context + OMX_COMPONENT_GENERATE_EVENT_FLUSH = 0x9, + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH = 0x0A, + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH = 0x0B, + OMX_COMPONENT_GENERATE_FBD = 0xc, + OMX_COMPONENT_GENERATE_START_DONE = 0xD, + OMX_COMPONENT_GENERATE_PAUSE_DONE = 0xE, + OMX_COMPONENT_GENERATE_RESUME_DONE = 0xF, + OMX_COMPONENT_GENERATE_STOP_DONE = 0x10, + OMX_COMPONENT_GENERATE_HARDWARE_ERROR = 0x11, + OMX_COMPONENT_GENERATE_LTRUSE_FAILED = 0x12, + OMX_COMPONENT_GENERATE_ETB_OPQ = 0x13 + }; + + struct omx_event + { + unsigned param1; + unsigned param2; + unsigned id; + }; + + struct omx_cmd_queue + { + omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE]; + unsigned m_read; + unsigned m_write; + unsigned m_size; + + omx_cmd_queue(); + ~omx_cmd_queue(); + bool insert_entry(unsigned p1, unsigned p2, unsigned id); + bool pop_entry(unsigned *p1,unsigned *p2, unsigned *id); + // get msgtype of the first ele from the queue + unsigned get_q_msg_type(); + + }; + + bool allocate_done(void); + bool allocate_input_done(void); + bool allocate_output_done(void); + + OMX_ERRORTYPE free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); + + OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes); +#ifdef _ANDROID_ICS_ + OMX_ERRORTYPE allocate_input_meta_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_PTR appData, + OMX_U32 bytes); +#endif + OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port,OMX_PTR appData, + OMX_U32 bytes); + + OMX_ERRORTYPE use_input_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8 *buffer); + + OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_U32 port, + OMX_PTR appData, + OMX_U32 bytes, + OMX_U8 *buffer); + + bool execute_omx_flush(OMX_U32); + bool execute_output_flush(void); + bool execute_input_flush(void); +#ifdef _MSM8974_ + bool execute_flush_all(void); +#endif + OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE * buffer); + + OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE * buffer); + OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer); + OMX_ERRORTYPE empty_this_buffer_opaque(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer); + OMX_ERRORTYPE push_input_buffer(OMX_HANDLETYPE hComp); + OMX_ERRORTYPE convert_queue_buffer(OMX_HANDLETYPE hComp, + struct pmem &Input_pmem_info,unsigned &index); + OMX_ERRORTYPE queue_meta_buffer(OMX_HANDLETYPE hComp, + struct pmem &Input_pmem_info); + OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE *buffer); + bool release_done(); + + bool release_output_done(); + bool release_input_done(); + + OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp, + OMX_COMMANDTYPE cmd, + OMX_U32 param1, + OMX_PTR cmdData); + bool post_event( unsigned int p1, + unsigned int p2, + unsigned int id + ); + OMX_ERRORTYPE get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); + inline void omx_report_error () + { + if(m_pCallbacks.EventHandler && !m_error_propogated) + { + m_error_propogated = true; + m_pCallbacks.EventHandler(&m_cmp,m_app_data, + OMX_EventError,OMX_ErrorHardware,0,NULL); + } + } + + inline void omx_report_unsupported_setting () + { + if(m_pCallbacks.EventHandler && !m_error_propogated) + { + m_error_propogated = true; + m_pCallbacks.EventHandler(&m_cmp,m_app_data, + OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL); + } + } + + void complete_pending_buffer_done_cbs(); + + //************************************************************* + //*******************MEMBER VARIABLES ************************* + //************************************************************* + + pthread_mutex_t m_lock; + sem_t m_cmd_lock; + bool m_error_propogated; + + //sem to handle the minimum procesing of commands + + + // compression format + //OMX_VIDEO_CODINGTYPE eCompressionFormat; + // OMX State + OMX_STATETYPE m_state; + // Application data + OMX_PTR m_app_data; + OMX_BOOL m_use_input_pmem; + OMX_BOOL m_use_output_pmem; + // Application callbacks + OMX_CALLBACKTYPE m_pCallbacks; + OMX_PORT_PARAM_TYPE m_sPortParam; + OMX_VIDEO_PARAM_PROFILELEVELTYPE m_sParamProfileLevel; + OMX_VIDEO_PARAM_PORTFORMATTYPE m_sInPortFormat; + OMX_VIDEO_PARAM_PORTFORMATTYPE m_sOutPortFormat; + OMX_PARAM_PORTDEFINITIONTYPE m_sInPortDef; + OMX_PARAM_PORTDEFINITIONTYPE m_sOutPortDef; + OMX_VIDEO_PARAM_MPEG4TYPE m_sParamMPEG4; + OMX_VIDEO_PARAM_H263TYPE m_sParamH263; + OMX_VIDEO_PARAM_AVCTYPE m_sParamAVC; + OMX_PORT_PARAM_TYPE m_sPortParam_img; + OMX_PORT_PARAM_TYPE m_sPortParam_audio; + OMX_VIDEO_CONFIG_BITRATETYPE m_sConfigBitrate; + OMX_CONFIG_FRAMERATETYPE m_sConfigFramerate; + OMX_VIDEO_PARAM_BITRATETYPE m_sParamBitrate; + OMX_PRIORITYMGMTTYPE m_sPriorityMgmt; + OMX_PARAM_BUFFERSUPPLIERTYPE m_sInBufSupplier; + OMX_PARAM_BUFFERSUPPLIERTYPE m_sOutBufSupplier; + OMX_CONFIG_ROTATIONTYPE m_sConfigFrameRotation; + OMX_CONFIG_INTRAREFRESHVOPTYPE m_sConfigIntraRefreshVOP; + OMX_VIDEO_PARAM_QUANTIZATIONTYPE m_sSessionQuantization; + OMX_QCOM_VIDEO_PARAM_QPRANGETYPE m_sSessionQPRange; + OMX_VIDEO_PARAM_AVCSLICEFMO m_sAVCSliceFMO; + QOMX_VIDEO_INTRAPERIODTYPE m_sIntraperiod; + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE m_sErrorCorrection; + OMX_VIDEO_PARAM_INTRAREFRESHTYPE m_sIntraRefresh; + QOMX_VIDEO_PARAM_LTRMODE_TYPE m_sParamLTRMode; + QOMX_VIDEO_PARAM_LTRCOUNT_TYPE m_sParamLTRCount; + QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE m_sConfigLTRPeriod; + QOMX_VIDEO_CONFIG_LTRUSE_TYPE m_sConfigLTRUse; + OMX_VIDEO_CONFIG_AVCINTRAPERIOD m_sConfigAVCIDRPeriod; + OMX_U32 m_sExtraData; + OMX_U32 m_input_msg_id; + + // fill this buffer queue + omx_cmd_queue m_ftb_q; + // Command Q for rest of the events + omx_cmd_queue m_cmd_q; + omx_cmd_queue m_etb_q; + // Input memory pointer + OMX_BUFFERHEADERTYPE *m_inp_mem_ptr; + // Output memory pointer + OMX_BUFFERHEADERTYPE *m_out_mem_ptr; + omx_cmd_queue m_opq_meta_q; + omx_cmd_queue m_opq_pmem_q; + OMX_BUFFERHEADERTYPE meta_buffer_hdr[MAX_NUM_INPUT_BUFFERS]; + + bool input_flush_progress; + bool output_flush_progress; + bool input_use_buffer; + bool output_use_buffer; + int pending_input_buffers; + int pending_output_buffers; + + unsigned int m_out_bm_count; + unsigned int m_inp_bm_count; + unsigned int m_flags; + unsigned int m_etb_count; + unsigned int m_fbd_count; +#ifdef _ANDROID_ + // Heap pointer to frame buffers + sp m_heap_ptr; +#endif //_ANDROID_ + // to know whether Event Port Settings change has been triggered or not. + bool m_event_port_settings_sent; + OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE]; + extra_data_handler extra_data_handle; + +}; + +#endif // __OMX_VIDEO_BASE_H__ diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_common.h b/mm-video-v4l2/vidc/venc/inc/omx_video_common.h new file mode 100755 index 00000000..dc4be1d3 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/omx_video_common.h @@ -0,0 +1,85 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#ifndef __OMX_VIDEO_COMMON_H__ +#define __OMX_VIDEO_COMMON_H__ +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// + +#include +#include +#ifdef USE_ION +#include +#endif + +#define OMX_VIDEO_DEC_NUM_INPUT_BUFFERS 2 +#define OMX_VIDEO_DEC_NUM_OUTPUT_BUFFERS 2 + +#ifdef FEATURE_QTV_WVGA_ENABLE +#define OMX_VIDEO_DEC_INPUT_BUFFER_SIZE (256*1024) +#else +#define OMX_VIDEO_DEC_INPUT_BUFFER_SIZE (128*1024) +#endif + +#define OMX_CORE_CONTROL_CMDQ_SIZE 100 +#define OMX_CORE_QCIF_HEIGHT 144 +#define OMX_CORE_QCIF_WIDTH 176 +#define OMX_CORE_VGA_HEIGHT 480 +#define OMX_CORE_VGA_WIDTH 640 +#define OMX_CORE_WVGA_HEIGHT 480 +#define OMX_CORE_WVGA_WIDTH 800 + +enum PortIndexType +{ + PORT_INDEX_IN = 0, + PORT_INDEX_OUT = 1, + PORT_INDEX_BOTH = -1, + PORT_INDEX_NONE = -2 +}; + +struct pmem +{ + void *buffer; + int fd; + unsigned offset; + unsigned size; +}; +#ifdef USE_ION +struct venc_ion +{ + int ion_device_fd; + struct ion_fd_data fd_ion_data; + struct ion_allocation_data ion_alloc_data; +}; +#endif +#endif // __OMX_VIDEO_COMMON_H__ + + + + diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h new file mode 100644 index 00000000..f59c4ab8 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h @@ -0,0 +1,89 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef __OMX_VENC__H +#define __OMX_VENC__H + +#include +#include "omx_video_base.h" +#ifdef _MSM8974_ +#include "video_encoder_device_v4l2.h" +#else +#include "video_encoder_device.h" +#endif + +extern "C" { + OMX_API void * get_omx_component_factory_fn(void); +} + +class omx_venc: public omx_video +{ +public: + omx_venc(); //constructor + ~omx_venc(); //des + static int async_message_process (void *context, void* message); + OMX_ERRORTYPE component_init(OMX_STRING role); + OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE paramIndex, + OMX_PTR paramData); + OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, + OMX_INDEXTYPE configIndex, + OMX_PTR configData); + OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp); + //OMX strucutres + OMX_U32 m_nVenc_format; + class venc_dev *handle; +#ifdef _MSM8974_ + int dev_handle_extradata(void *, int); + int dev_set_format(int); +#endif +private: + OMX_U32 dev_stop(void); + OMX_U32 dev_pause(void); + OMX_U32 dev_start(void); + OMX_U32 dev_flush(unsigned); + OMX_U32 dev_resume(void); + OMX_U32 dev_start_done(void); + OMX_U32 dev_set_message_thread_id(pthread_t); + bool dev_use_buf( void *,unsigned,unsigned); + bool dev_free_buf( void *,unsigned); + bool dev_empty_buf(void *, void *,unsigned,unsigned); + bool dev_fill_buf(void *, void *,unsigned,unsigned); + bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32); + bool dev_set_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32); + bool update_profile_level(); + bool dev_get_seq_hdr(void *, unsigned, unsigned *); + bool dev_loaded_start(void); + bool dev_loaded_stop(void); + bool dev_loaded_start_done(void); + bool dev_loaded_stop_done(void); + bool dev_get_capability_ltrcount(OMX_U32 *, OMX_U32 *, OMX_U32 *); + bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height); +}; + +#endif //__OMX_VENC__H diff --git a/mm-video-v4l2/vidc/venc/inc/queue.h b/mm-video-v4l2/vidc/venc/inc/queue.h new file mode 100755 index 00000000..530b087d --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/queue.h @@ -0,0 +1,80 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef QUEUE_H +#define QUEUE_H + +#include +#include +#include +#include + +/* Message Queue structure */ +struct video_msgq +{ + /* Command to be executed */ + unsigned int cmd; + + unsigned int status; + + /* Client-specific data */ + void *clientdata; +}; + + +/* Thread & Message Queue information */ +struct video_queue_context +{ + /* Message Queue related members */ + pthread_mutex_t mutex; + sem_t sem_message; + int commandq_size; + int dataq_size; + struct video_msgq *ptr_dataq; + struct video_msgq *ptr_cmdq; + int write_dataq ; + int read_dataq; + int write_comq ; + int read_comq ; + +}; + +int check_if_queue_empty ( unsigned int queuetocheck,void* queuecontext ); + +struct video_msgq * queue_get_cmd ( void* queuecontext ); + + + +int queue_post_cmdq ( void *queuecontext, + struct video_msgq *post_msg + ); + +int queue_post_dataq ( void *queuecontext, + struct video_msgq *post_msg + ); + +#endif /* QUEUE_H */ diff --git a/mm-video-v4l2/vidc/venc/inc/venc_util.h b/mm-video-v4l2/vidc/venc/inc/venc_util.h new file mode 100755 index 00000000..cfa590ca --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/venc_util.h @@ -0,0 +1,53 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +/*============================================================================ + V E N C _ U T I L. H + +DESCRIPTION + + +REFERENCES + + +============================================================================*/ + +#ifndef _VENC_UTIL_H +#define _VENC_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +long long GetTimeStamp(); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h new file mode 100644 index 00000000..fb24c767 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h @@ -0,0 +1,172 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef __OMX_VENC_DEV__ +#define __OMX_VENC_DEV__ + +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "qc_omx_component.h" +#include "omx_video_common.h" +#include +#include +#include +#include +#define TIMEOUT 5000 +#define MAX_RECON_BUFFERS 4 + +void* async_venc_message_thread (void *); + +class venc_dev +{ +public: + venc_dev(class omx_venc *venc_class); //constructor + ~venc_dev(); //des + + bool venc_open(OMX_U32); + void venc_close(); + unsigned venc_stop(void); + unsigned venc_pause(void); + unsigned venc_start(void); + unsigned venc_flush(unsigned); +#ifdef _ANDROID_ICS_ + bool venc_set_meta_mode(bool); +#endif + unsigned venc_resume(void); + unsigned venc_start_done(void); + unsigned venc_set_message_thread_id(pthread_t); + bool venc_use_buf(void*, unsigned,unsigned); + bool venc_free_buf(void*, unsigned); + bool venc_empty_buf(void *, void *,unsigned,unsigned); + bool venc_fill_buf(void *, void *,unsigned,unsigned); + + bool venc_get_buf_req(unsigned long *,unsigned long *, + unsigned long *,unsigned long); + bool venc_set_buf_req(unsigned long *,unsigned long *, + unsigned long *,unsigned long); + bool venc_set_param(void *,OMX_INDEXTYPE); + bool venc_set_config(void *configData, OMX_INDEXTYPE index); + bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel); + bool venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate); + bool venc_get_seq_hdr(void *, unsigned, unsigned *); + bool venc_loaded_start(void); + bool venc_loaded_stop(void); + bool venc_loaded_start_done(void); + bool venc_loaded_stop_done(void); + bool venc_get_capability_ltrcount(OMX_U32 *, OMX_U32 *, OMX_U32 *); + OMX_U32 m_nDriver_fd; + bool m_profile_set; + bool m_level_set; + pthread_mutex_t loaded_start_stop_mlock; + pthread_cond_t loaded_start_stop_cond; + + struct recon_buffer { + unsigned char* virtual_address; + int pmem_fd; + int size; + int alignment; + int offset; +#ifdef USE_ION + int ion_device_fd; + struct ion_allocation_data alloc_data; + struct ion_fd_data ion_alloc_fd; +#endif + }; + + recon_buffer recon_buff[MAX_RECON_BUFFERS]; + int recon_buffers_count; + bool m_max_allowed_bitrate_check; + int m_eProfile; + int m_eLevel; + int etb_count; +private: + struct venc_basecfg m_sVenc_cfg; + struct venc_ratectrlcfg rate_ctrl; + struct venc_targetbitrate bitrate; + struct venc_intraperiod intra_period; + struct venc_profile codec_profile; + struct ven_profilelevel profile_level; + struct venc_switch set_param; + struct venc_voptimingcfg time_inc; + struct venc_allocatorproperty m_sInput_buff_property; + struct venc_allocatorproperty m_sOutput_buff_property; + struct venc_sessionqp session_qp; + struct venc_qprange qp_range; + struct venc_multiclicecfg multislice; + struct venc_entropycfg entropy; + struct venc_dbcfg dbkfilter; + struct venc_intrarefresh intra_refresh; + struct venc_headerextension hec; + struct venc_voptimingcfg voptimecfg; + struct venc_seqheader seqhdr; + struct venc_ltrmode ltrmode; + struct venc_ltrcount ltrcount; + struct venc_ltrperiod ltrperiod; + + bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel); + bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames); + bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config); + bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate); + bool venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp); + bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp); + bool venc_set_extradata(OMX_U32 extra_data); + bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config); + bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh); + bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format); + bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel); + bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize); + bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level); + bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter); + bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs); + bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience); + bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes); + void venc_config_print(); + bool venc_set_slice_delivery_mode(OMX_BOOL enable); + bool venc_set_plusptype(OMX_BOOL enable); + bool venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode); + bool venc_set_ltrcount(OMX_U32 count); + bool venc_set_ltrperiod(OMX_U32 period); + bool venc_set_ltruse(OMX_U32 id, OMX_U32 frames); +#ifdef MAX_RES_1080P + OMX_U32 pmem_free(); + OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); + OMX_U32 venc_allocate_recon_buffers(); + inline int clip2(int x) + { + x = x -1; + x = x | x >> 1; + x = x | x >> 2; + x = x | x >> 4; + x = x | x >> 16; + x = x + 1; + return x; + } +#endif +}; + +#endif diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h new file mode 100644 index 00000000..78729b69 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h @@ -0,0 +1,344 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#ifndef __OMX_VENC_DEV__ +#define __OMX_VENC_DEV__ + +#include "OMX_Types.h" +#include "OMX_Core.h" +#include "OMX_QCOMExtns.h" +#include "qc_omx_component.h" +#include "omx_video_common.h" +#include "omx_video_base.h" +#include "omx_video_encoder.h" +#include +#include + +#define TIMEOUT 5*60*1000 + + +struct msm_venc_switch{ + unsigned char status; +}; + +struct msm_venc_allocatorproperty{ + unsigned long mincount; + unsigned long actualcount; + unsigned long datasize; + unsigned long suffixsize; + unsigned long alignment; + unsigned long bufpoolid; +}; + +struct msm_venc_basecfg{ + unsigned long input_width; + unsigned long input_height; + unsigned long dvs_width; + unsigned long dvs_height; + unsigned long codectype; + unsigned long fps_num; + unsigned long fps_den; + unsigned long targetbitrate; + unsigned long inputformat; +}; + +struct msm_venc_profile{ + unsigned long profile; +}; +struct msm_venc_profilelevel{ + unsigned long level; +}; + +struct msm_venc_sessionqp{ + unsigned long iframeqp; + unsigned long pframqp; + unsigned long bframqp; +}; + +struct msm_venc_qprange{ + unsigned long maxqp; + unsigned long minqp; +}; +struct msm_venc_intraperiod{ + unsigned long num_pframes; + unsigned long num_bframes; +}; +struct msm_venc_seqheader{ + unsigned char *hdrbufptr; + unsigned long bufsize; + unsigned long hdrlen; +}; + +struct msm_venc_capability{ + unsigned long codec_types; + unsigned long maxframe_width; + unsigned long maxframe_height; + unsigned long maxtarget_bitrate; + unsigned long maxframe_rate; + unsigned long input_formats; + unsigned char dvs; +}; + +struct msm_venc_entropycfg{ + unsigned longentropysel; + unsigned long cabacmodel; +}; + +struct msm_venc_dbcfg{ + unsigned long db_mode; + unsigned long slicealpha_offset; + unsigned long slicebeta_offset; +}; + +struct msm_venc_intrarefresh{ + unsigned long irmode; + unsigned long mbcount; +}; + +struct msm_venc_multiclicecfg{ + unsigned long mslice_mode; + unsigned long mslice_size; +}; + +struct msm_venc_bufferflush{ + unsigned long flush_mode; +}; + +struct msm_venc_ratectrlcfg{ + unsigned long rcmode; +}; + +struct msm_venc_voptimingcfg{ + unsigned long voptime_resolution; +}; +struct msm_venc_framerate{ + unsigned long fps_denominator; + unsigned long fps_numerator; +}; + +struct msm_venc_targetbitrate{ + unsigned long target_bitrate; +}; + + +struct msm_venc_rotation{ + unsigned long rotation; +}; + +struct msm_venc_timeout{ + unsigned long millisec; +}; + +struct msm_venc_headerextension{ + unsigned long header_extension; +}; + +struct msm_venc_video_capability { + unsigned int min_width; + unsigned int max_width; + unsigned int min_height; + unsigned int max_height; +}; + +struct msm_venc_idrperiod { + unsigned long idrperiod; +}; + +struct msm_venc_slice_delivery { + unsigned long enable; +}; + +enum v4l2_ports { + CAPTURE_PORT, + OUTPUT_PORT, + MAX_PORT +}; + +struct extradata_buffer_info { + int buffer_size; + char* uaddr; + int count; + int size; + int allocated; +#ifdef USE_ION + struct venc_ion ion; +#endif +}; + +class venc_dev +{ +public: + venc_dev(class omx_venc *venc_class); //constructor + ~venc_dev(); //des + + static void* async_venc_message_thread (void *); + bool venc_open(OMX_U32); + void venc_close(); + unsigned venc_stop(void); + unsigned venc_pause(void); + unsigned venc_start(void); + unsigned venc_flush(unsigned); +#ifdef _ANDROID_ICS_ + bool venc_set_meta_mode(bool); +#endif + unsigned venc_resume(void); + unsigned venc_start_done(void); + unsigned venc_stop_done(void); + unsigned venc_set_message_thread_id(pthread_t); + bool venc_use_buf(void*, unsigned,unsigned); + bool venc_free_buf(void*, unsigned); + bool venc_empty_buf(void *, void *,unsigned,unsigned); + bool venc_fill_buf(void *, void *,unsigned,unsigned); + + bool venc_get_buf_req(unsigned long *,unsigned long *, + unsigned long *,unsigned long); + bool venc_set_buf_req(unsigned long *,unsigned long *, + unsigned long *,unsigned long); + bool venc_set_param(void *,OMX_INDEXTYPE); + bool venc_set_config(void *configData, OMX_INDEXTYPE index); + bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel); + bool venc_get_seq_hdr(void *, unsigned, unsigned *); + bool venc_loaded_start(void); + bool venc_loaded_stop(void); + bool venc_loaded_start_done(void); + bool venc_loaded_stop_done(void); + bool venc_is_video_session_supported(unsigned long width, unsigned long height); + OMX_U32 m_nDriver_fd; + bool m_profile_set; + bool m_level_set; + int num_planes; + int etb, ebd, ftb, fbd; + struct recon_buffer { + unsigned char* virtual_address; + int pmem_fd; + int size; + int alignment; + int offset; +#ifdef USE_ION + int ion_device_fd; + struct ion_allocation_data alloc_data; + struct ion_fd_data ion_alloc_fd; +#endif + }; + + int stopped; + bool m_max_allowed_bitrate_check; + pthread_t m_tid; + bool async_thread_created; + class omx_venc *venc_handle; + OMX_ERRORTYPE allocate_extradata(); + void free_extradata(); + bool handle_extradata(void *, int); + int venc_set_format(int); +private: + struct msm_venc_basecfg m_sVenc_cfg; + struct msm_venc_ratectrlcfg rate_ctrl; + struct msm_venc_targetbitrate bitrate; + struct msm_venc_intraperiod intra_period; + struct msm_venc_profile codec_profile; + struct msm_venc_profilelevel profile_level; + struct msm_venc_switch set_param; + struct msm_venc_voptimingcfg time_inc; + struct msm_venc_allocatorproperty m_sInput_buff_property; + struct msm_venc_allocatorproperty m_sOutput_buff_property; + struct msm_venc_sessionqp session_qp; + struct msm_venc_multiclicecfg multislice; + struct msm_venc_entropycfg entropy; + struct msm_venc_dbcfg dbkfilter; + struct msm_venc_intrarefresh intra_refresh; + struct msm_venc_headerextension hec; + struct msm_venc_voptimingcfg voptimecfg; + struct msm_venc_video_capability capability; + struct msm_venc_idrperiod idrperiod; + struct msm_venc_slice_delivery slice_mode; + + bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel); + bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames); + bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config); + bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate); + bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp); + bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config); + bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh); + bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format); + bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel); + bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize); + bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level); + bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter); + bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs); + bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience); + bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes); + void venc_config_print(); + bool venc_set_slice_delivery_mode(OMX_U32 enable); + bool venc_set_extradata(OMX_U32 extra_data); + bool venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod); +#ifdef MAX_RES_1080P + OMX_U32 pmem_free(); + OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); + OMX_U32 venc_allocate_recon_buffers(); + inline int clip2(int x) + { + x = x -1; + x = x | x >> 1; + x = x | x >> 2; + x = x | x >> 4; + x = x | x >> 16; + x = x + 1; + return x; + } +#endif + int metadatamode; + bool streaming[MAX_PORT]; + bool extradata; + struct extradata_buffer_info extradata_info; + + pthread_mutex_t pause_resume_mlock; + pthread_cond_t pause_resume_cond; + bool paused; + int color_format; +}; + +enum instance_state { + MSM_VIDC_CORE_UNINIT_DONE = 0x0001, + MSM_VIDC_CORE_INIT, + MSM_VIDC_CORE_INIT_DONE, + MSM_VIDC_OPEN, + MSM_VIDC_OPEN_DONE, + MSM_VIDC_LOAD_RESOURCES, + MSM_VIDC_LOAD_RESOURCES_DONE, + MSM_VIDC_START, + MSM_VIDC_START_DONE, + MSM_VIDC_STOP, + MSM_VIDC_STOP_DONE, + MSM_VIDC_RELEASE_RESOURCES, + MSM_VIDC_RELEASE_RESOURCES_DONE, + MSM_VIDC_CLOSE, + MSM_VIDC_CLOSE_DONE, + MSM_VIDC_CORE_UNINIT, +}; +#endif + diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_test.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_test.h new file mode 100755 index 00000000..bf1082a5 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_test.h @@ -0,0 +1,76 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include +#include +#include "queue.h" +#include +#include +#include +#include +#include +#include +#include + +#define INPUT_BUFFER 0 +#define OUTPUT_BUFFER 1 + +struct video_encoder_context +{ + unsigned long input_width; + unsigned long input_height; + unsigned long codectype; + unsigned long fps_num; + unsigned long fps_den; + unsigned long targetbitrate; + unsigned long inputformat; + + struct venc_allocatorproperty input_buffer; + struct venc_allocatorproperty output_buffer; + struct venc_bufferpayload **ptr_inputbuffer; + struct venc_bufferpayload **ptr_outputbuffer; + struct video_queue_context queue_context; + int video_driver_fd; + + FILE * inputBufferFile; + FILE * outputBufferFile; + + pthread_t videothread_id; + pthread_t asyncthread_id; + sem_t sem_synchronize; +}; + +int init_encoder ( struct video_encoder_context *init_decode ); +int allocate_buffer ( unsigned int buffer_dir, + struct video_encoder_context *decode_context + ); +int free_buffer ( unsigned int buffer_dir, + struct video_encoder_context *decode_context + ); +int start_encoding (struct video_encoder_context *decode_context); +int stop_encoding (struct video_encoder_context *decode_context); +int deinit_encoder (struct video_encoder_context *init_decode); diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp new file mode 100644 index 00000000..b0e14038 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp @@ -0,0 +1,4983 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +/*============================================================================ + O p e n M A X w r a p p e r s + O p e n M A X C o r e + +*//** @file omx_video_base.cpp + This module contains the implementation of the OpenMAX core & component. + +*//*========================================================================*/ + +////////////////////////////////////////////////////////////////////////////// +// Include Files +////////////////////////////////////////////////////////////////////////////// + +#include +#include "omx_video_base.h" +#include +#include +#include +#include +#include +#ifdef _ANDROID_ICS_ +#include +#include +#endif +#ifndef _ANDROID_ +#include +#define strlcpy g_strlcpy +#endif +#define H264_SUPPORTED_WIDTH (480) +#define H264_SUPPORTED_HEIGHT (368) + +#define MPEG4_SUPPORTED_WIDTH (480) +#define MPEG4_SUPPORTED_HEIGHT (368) + +#define VC1_SP_MP_START_CODE 0xC5000000 +#define VC1_SP_MP_START_CODE_MASK 0xFF000000 +#define VC1_AP_START_CODE 0x00000100 +#define VC1_AP_START_CODE_MASK 0xFFFFFF00 +#define VC1_STRUCT_C_PROFILE_MASK 0xF0 +#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 +#define VC1_SIMPLE_PROFILE 0 +#define VC1_MAIN_PROFILE 1 +#define VC1_ADVANCE_PROFILE 3 +#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 +#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 +#define VC1_STRUCT_C_LEN 4 +#define VC1_STRUCT_C_POS 8 +#define VC1_STRUCT_A_POS 12 +#define VC1_STRUCT_B_POS 24 +#define VC1_SEQ_LAYER_SIZE 36 + +typedef struct OMXComponentCapabilityFlagsType +{ + ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS + OMX_BOOL iIsOMXComponentMultiThreaded; + OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; + OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; + OMX_BOOL iOMXComponentSupportsMovableInputBuffers; + OMX_BOOL iOMXComponentSupportsPartialFrames; + OMX_BOOL iOMXComponentUsesNALStartCodes; + OMX_BOOL iOMXComponentCanHandleIncompleteFrames; + OMX_BOOL iOMXComponentUsesFullAVCFrames; + +} OMXComponentCapabilityFlagsType; +#define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347 +#ifdef OUTPUT_BUFFER_LOG +extern FILE *outputBufferFile1; +#endif + +void* message_thread(void *input) +{ + omx_video* omx = reinterpret_cast(input); + unsigned char id; + int n; + + DEBUG_PRINT_LOW("omx_venc: message thread start\n"); + prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0); + while(1) + { + n = read(omx->m_pipe_in, &id, 1); + if(0 == n) + { + break; + } + + if(1 == n) + { + omx->process_event_cb(omx, id); + } +#ifdef QLE_BUILD + if(n < 0) break; +#else + if((n < 0) && (errno != EINTR)) break; +#endif + } + DEBUG_PRINT_LOW("omx_venc: message thread stop\n"); + return 0; +} + +void post_message(omx_video *omx, unsigned char id) +{ + DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id); + write(omx->m_pipe_out, &id, 1); +} + +// omx_cmd_queue destructor +omx_video::omx_cmd_queue::~omx_cmd_queue() +{ + // Nothing to do +} + +// omx cmd queue constructor +omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) +{ + memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); +} + +// omx cmd queue insert +bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) +{ + bool ret = true; + if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_q[m_write].id = id; + m_q[m_write].param1 = p1; + m_q[m_write].param2 = p2; + m_write++; + m_size ++; + if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_write = 0; + } + } + else + { + ret = false; + DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n"); + } + return ret; +} + +// omx cmd queue pop +bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) +{ + bool ret = true; + if(m_size > 0) + { + *id = m_q[m_read].id; + *p1 = m_q[m_read].param1; + *p2 = m_q[m_read].param2; + // Move the read pointer ahead + ++m_read; + --m_size; + if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) + { + m_read = 0; + } + } + else + { + ret = false; + } + return ret; +} + +// Retrieve the first mesg type in the queue +unsigned omx_video::omx_cmd_queue::get_q_msg_type() +{ + return m_q[m_read].id; +} + + + +#ifdef _ANDROID_ +VideoHeap::VideoHeap(int fd, size_t size, void* base) +{ + // dup file descriptor, map once, use pmem + init(dup(fd), base, size, 0 , MEM_DEVICE); +} +#endif // _ANDROID_ + +/* ====================================================================== +FUNCTION + omx_venc::omx_venc + +DESCRIPTION + Constructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_video::omx_video(): + m_pInput_pmem(NULL), + m_pOutput_pmem(NULL), +#ifdef USE_ION + m_pInput_ion(NULL), + m_pOutput_ion(NULL), +#endif + m_error_propogated(false), + m_state(OMX_StateInvalid), + m_app_data(NULL), + m_use_input_pmem(OMX_FALSE), + m_use_output_pmem(OMX_FALSE), + m_inp_mem_ptr(NULL), + m_out_mem_ptr(NULL), + input_flush_progress (false), + output_flush_progress (false), + input_use_buffer (false), + output_use_buffer (false), + pending_input_buffers(0), + pending_output_buffers(0), + m_out_bm_count(0), + m_inp_bm_count(0), + m_flags(0), + m_etb_count(0), + m_fbd_count(0), + m_event_port_settings_sent(false), + m_input_msg_id(OMX_COMPONENT_GENERATE_ETB), + psource_frame(NULL), + pdest_frame(NULL), + c2d_opened(false) +{ + DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()"); + memset(&m_cmp,0,sizeof(m_cmp)); + memset(&m_pCallbacks,0,sizeof(m_pCallbacks)); + async_thread_created = false; + msg_thread_created = false; + + pthread_mutex_init(&m_lock, NULL); + sem_init(&m_cmd_lock,0,0); +} + + +/* ====================================================================== +FUNCTION + omx_venc::~omx_venc + +DESCRIPTION + Destructor + +PARAMETERS + None + +RETURN VALUE + None. +========================================================================== */ +omx_video::~omx_video() +{ + DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()"); + if(m_pipe_in) close(m_pipe_in); + if(m_pipe_out) close(m_pipe_out); + DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n"); + if (msg_thread_created) + pthread_join(msg_thread_id,NULL); + DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n"); + /*For V4L2 based drivers, pthread_join is done in device_close + * so no need to do it here*/ +#ifndef _MSM8974_ + if (async_thread_created) + pthread_join(async_thread_id,NULL); +#endif + pthread_mutex_destroy(&m_lock); + sem_destroy(&m_cmd_lock); + DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count, + m_fbd_count); + DEBUG_PRINT_HIGH("omx_video: Destructor exit\n"); + DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n"); +} + +/* ====================================================================== +FUNCTION + omx_venc::OMXCntrlProcessMsgCb + +DESCRIPTION + IL Client callbacks are generated through this routine. The decoder + provides the thread context for this routine. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +void omx_video::process_event_cb(void *ctxt, unsigned char id) +{ + unsigned p1; // Parameter - 1 + unsigned p2; // Parameter - 2 + unsigned ident; + unsigned qsize=0; // qsize + omx_video *pThis = (omx_video *) ctxt; + + if(!pThis) + { + DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n"); + return; + } + + // Protect the shared queue data structure + do + { + /*Read the message id's from the queue*/ + + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size; + if(qsize) + { + pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); + } + + if(qsize == 0) + { + qsize = pThis->m_ftb_q.m_size; + if(qsize) + { + pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); + } + } + + if(qsize == 0) + { + qsize = pThis->m_etb_q.m_size; + if(qsize) + { + pThis->m_etb_q.pop_entry(&p1,&p2,&ident); + } + } + + pthread_mutex_unlock(&pThis->m_lock); + + /*process message if we have one*/ + if(qsize > 0) + { + id = ident; + switch(id) + { + case OMX_COMPONENT_GENERATE_EVENT: + if(pThis->m_pCallbacks.EventHandler) + { + switch(p1) + { + case OMX_CommandStateSet: + pThis->m_state = (OMX_STATETYPE) p2; + DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state); + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL); + break; + + case OMX_EventError: + DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2); + if(p2 == OMX_ErrorHardware) + { + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError,OMX_ErrorHardware,0,NULL); + } + else + { + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventError, p2, NULL, NULL ); + + } + break; + + case OMX_CommandPortDisable: + DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \ + "state \n", p2); + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + case OMX_CommandPortEnable: + DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \ + , p2); + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + default: + DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1); + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete, p1, p2, NULL ); + break; + + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n"); + } + break; + case OMX_COMPONENT_GENERATE_ETB_OPQ: + DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n"); + if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); + pThis->omx_report_error (); + } + break; + case OMX_COMPONENT_GENERATE_ETB: + DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n"); + if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FTB: + if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ + (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_COMMAND: + pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ + (OMX_U32)p2,(OMX_PTR)NULL); + break; + + case OMX_COMPONENT_GENERATE_EBD: + if( pThis->empty_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FBD: + if( pThis->fill_buffer_done(&pThis->m_cmp, + (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); + pThis->omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: + + pThis->input_flush_progress = false; + DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count); + m_etb_count = 0; + if(pThis->m_pCallbacks.EventHandler) + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_INPUT_FLUSH_PENDING)) + { + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + PORT_INDEX_IN,NULL ); + } + else if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_IDLE_PENDING)) + { + if(!pThis->output_flush_progress) + { + DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n"); + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n"); + pThis->omx_report_error (); + } + } + } + } + + break; + + case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: + + pThis->output_flush_progress = false; + DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count); + m_fbd_count = 0; + if(pThis->m_pCallbacks.EventHandler) + { + /*Check if we need generate event for Flush done*/ + if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) + { + BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandFlush, + PORT_INDEX_OUT,NULL ); + } + else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n"); + if(!pThis->input_flush_progress) + { + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n"); + pThis->omx_report_error (); + } + } + } + } + break; + + case OMX_COMPONENT_GENERATE_START_DONE: + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg"); + + if(pThis->m_pCallbacks.EventHandler) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \ + executing"); + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting, NULL); + } + else if(BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_PAUSE_PENDING)) + { + if(dev_pause()) + { + DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n"); + pThis->omx_report_error (); + } + } + else if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_LOADED_START_PENDING)) + { + if(dev_loaded_start_done()) + { + DEBUG_PRINT_LOW("successful loaded Start Done!"); + } + else + { + DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!"); + pThis->omx_report_error (); + } + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING); + } + else + { + DEBUG_PRINT_LOW("\nERROR: unknown flags=%x\n",pThis->m_flags); + } + } + else + { + DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); + } + break; + + case OMX_COMPONENT_GENERATE_PAUSE_DONE: + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg"); + if(pThis->m_pCallbacks.EventHandler) + { + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) + { + //Send the callback now + pThis->complete_pending_buffer_done_cbs(); + DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n"); + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); + pThis->m_state = OMX_StatePause; + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StatePause, NULL); + } + } + + break; + + case OMX_COMPONENT_GENERATE_RESUME_DONE: + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg"); + if(pThis->m_pCallbacks.EventHandler) + { + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); + pThis->m_state = OMX_StateExecuting; + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateExecuting,NULL); + } + } + + break; + + case OMX_COMPONENT_GENERATE_STOP_DONE: + DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg"); + if(pThis->m_pCallbacks.EventHandler) + { + pThis->complete_pending_buffer_done_cbs(); + if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); + pThis->m_state = OMX_StateIdle; + pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data, + OMX_EventCmdComplete,OMX_CommandStateSet, + OMX_StateIdle,NULL); + } + else if (BITMASK_PRESENT(&pThis->m_flags, + OMX_COMPONENT_LOADED_STOP_PENDING)) + { + if(dev_loaded_stop_done()) + { + DEBUG_PRINT_LOW("successful loaded Stop Done!"); + } + else + { + DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!"); + pThis->omx_report_error (); + } + BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING); + } + else + { + DEBUG_PRINT_LOW("\nERROR: unknown flags=%x\n",pThis->m_flags); + } + } + + break; + + case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: + DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n"); + pThis->omx_report_error (); + break; +#ifndef _MSM8974_ + case OMX_COMPONENT_GENERATE_LTRUSE_FAILED: + DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_LTRUSE_FAILED!"); + if(pThis->m_pCallbacks.EventHandler) + { + DEBUG_PRINT_ERROR("Sending QOMX_ErrorLTRUseFailed, p2 = 0x%x", p2); + pThis->m_pCallbacks.EventHandler( + &pThis->m_cmp, pThis->m_app_data, + OMX_EventError, QOMX_ErrorLTRUseFailed, NULL, NULL); + } + break; +#endif + default: + DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id); + break; + } + } + + pthread_mutex_lock(&pThis->m_lock); + qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ + pThis->m_etb_q.m_size; + + pthread_mutex_unlock(&pThis->m_lock); + + } + while(qsize>0); + DEBUG_PRINT_LOW("\n exited the while loop\n"); + +} + + + + +/* ====================================================================== +FUNCTION + omx_venc::GetComponentVersion + +DESCRIPTION + Returns the component version. + +PARAMETERS + TBD. + +RETURN VALUE + OMX_ErrorNone. + +========================================================================== */ +OMX_ERRORTYPE omx_video::get_component_version +( +OMX_IN OMX_HANDLETYPE hComp, +OMX_OUT OMX_STRING componentName, +OMX_OUT OMX_VERSIONTYPE* componentVersion, +OMX_OUT OMX_VERSIONTYPE* specVersion, +OMX_OUT OMX_UUIDTYPE* componentUUID +) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n"); + return OMX_ErrorInvalidState; + } + /* TBD -- Return the proper version */ + if (specVersion) + { + specVersion->nVersion = OMX_SPEC_VERSION; + } + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_venc::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) + { + if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH)) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n"); + return OMX_ErrorBadPortIndex; + } + } + if(cmd == OMX_CommandMarkBuffer) + { + if(param1 != PORT_INDEX_IN) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n"); + return OMX_ErrorBadPortIndex; + } + if(!cmdData) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null"); + return OMX_ErrorBadParameter; + } + } + + post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); + sem_wait(&m_cmd_lock); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_venc::SendCommand + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_COMMANDTYPE cmd, + OMX_IN OMX_U32 param1, + OMX_IN OMX_PTR cmdData + ) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_STATETYPE eState = (OMX_STATETYPE) param1; + int bFlag = 1; + + if(cmd == OMX_CommandStateSet) + { + /***************************/ + /* Current State is Loaded */ + /***************************/ + if(m_state == OMX_StateLoaded) + { + if(eState == OMX_StateIdle) + { + //if all buffers are allocated or all ports disabled + if(allocate_done() || + ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) + { + DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n"); + } + else + { + DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Loaded to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Loaded to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n"); + } + /* Requesting transition from Loaded to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Loaded to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\ + eState); + eRet = OMX_ErrorBadParameter; + } + } + + /***************************/ + /* Current State is IDLE */ + /***************************/ + else if(m_state == OMX_StateIdle) + { + if(eState == OMX_StateLoaded) + { + if(release_done()) + { + /* + Since error is None , we will post an event at the end + of this function definition + */ + DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n"); + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded"); + eRet = OMX_ErrorHardware; + } + } + else + { + DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); + // Skip the event notification + bFlag = 0; + } + } + /* Requesting transition from Idle to Executing */ + else if(eState == OMX_StateExecuting) + { + if( dev_start() ) + { + DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); + bFlag = 0; + } + + dev_start_done(); + } + /* Requesting transition from Idle to Idle */ + else if(eState == OMX_StateIdle) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Idle to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Idle to Pause */ + else if(eState == OMX_StatePause) + { + /*To pause the Video core we need to start the driver*/ + if( dev_start() ) + { + DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n"); + omx_report_error (); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n"); + bFlag = 0; + } + } + /* Requesting transition from Idle to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + + /******************************/ + /* Current State is Executing */ + /******************************/ + else if(m_state == OMX_StateExecuting) + { + /* Requesting transition from Executing to Idle */ + if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition + */ + DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n"); + //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + execute_omx_flush(OMX_ALL); + bFlag = 0; + } + /* Requesting transition from Executing to Paused */ + else if(eState == OMX_StatePause) + { + + if(dev_pause()) + { + DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n"); + post_event(OMX_EventError,OMX_ErrorHardware,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n"); + bFlag = 0; + } + } + /* Requesting transition from Executing to Loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Executing to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Executing to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is Pause */ + /***************************/ + else if(m_state == OMX_StatePause) + { + /* Requesting transition from Pause to Executing */ + if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_LOW("\n Pause --> Executing \n"); + if( dev_resume() ) + { + post_event(OMX_EventError,OMX_ErrorHardware,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorHardware; + } + else + { + BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); + DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n"); + post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE); + bFlag = 0; + } + } + /* Requesting transition from Pause to Idle */ + else if(eState == OMX_StateIdle) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("\n Pause --> Idle \n"); + BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); + execute_omx_flush(OMX_ALL); + bFlag = 0; + } + /* Requesting transition from Pause to loaded */ + else if(eState == OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from Pause to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n"); + post_event(OMX_EventError,OMX_ErrorSameState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from Pause to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState); + eRet = OMX_ErrorBadParameter; + } + } + /***************************/ + /* Current State is WaitForResources */ + /***************************/ + else if(m_state == OMX_StateWaitForResources) + { + /* Requesting transition from WaitForResources to Loaded */ + if(eState == OMX_StateLoaded) + { + /* Since error is None , we will post an event + at the end of this function definition */ + DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n"); + } + /* Requesting transition from WaitForResources to WaitForResources */ + else if(eState == OMX_StateWaitForResources) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n"); + post_event(OMX_EventError,OMX_ErrorSameState, + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorSameState; + } + /* Requesting transition from WaitForResources to Executing */ + else if(eState == OMX_StateExecuting) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Pause */ + else if(eState == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n"); + post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorIncorrectStateTransition; + } + /* Requesting transition from WaitForResources to Invalid */ + else if(eState == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n"); + post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + /* Requesting transition from WaitForResources to Loaded - + is NOT tested by Khronos TS */ + + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState); + eRet = OMX_ErrorBadParameter; + } + } + /********************************/ + /* Current State is Invalid */ + /*******************************/ + else if(m_state == OMX_StateInvalid) + { + /* State Transition from Inavlid to any state */ + if(eState == (OMX_StateLoaded || OMX_StateWaitForResources + || OMX_StateIdle || OMX_StateExecuting + || OMX_StatePause || OMX_StateInvalid)) + { + DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n"); + post_event(OMX_EventError,OMX_ErrorInvalidState,\ + OMX_COMPONENT_GENERATE_EVENT); + eRet = OMX_ErrorInvalidState; + } + } + else if(cmd == OMX_CommandFlush) + { + if(0 == param1 || OMX_ALL == param1) + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); + } + if(1 == param1 || OMX_ALL == param1) + { + //generate output flush event only. + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); + } + + execute_omx_flush(param1); + bFlag = 0; + } + else if( cmd == OMX_CommandPortEnable) + { + if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) + { + m_sInPortDef.bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || allocate_input_done()) + { + post_event(OMX_CommandPortEnable,PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) + { + m_sOutPortDef.bEnabled = OMX_TRUE; + + if( (m_state == OMX_StateLoaded && + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + || (allocate_output_done())) + { + post_event(OMX_CommandPortEnable,PORT_INDEX_OUT, + OMX_COMPONENT_GENERATE_EVENT); + + } + else + { + DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + // Skip the event notification + bFlag = 0; + } + } + } + else if(cmd == OMX_CommandPortDisable) + { + if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) + { + m_sInPortDef.bEnabled = OMX_FALSE; + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_input_done()) + { + post_event(OMX_CommandPortDisable,PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + execute_omx_flush(PORT_INDEX_IN); + } + + // Skip the event notification + bFlag = 0; + } + } + if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) + { + m_sOutPortDef.bEnabled = OMX_FALSE; + + if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) + && release_output_done()) + { + post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\ + OMX_COMPONENT_GENERATE_EVENT); + } + else + { + BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); + if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) + { + execute_omx_flush(PORT_INDEX_OUT); + } + // Skip the event notification + bFlag = 0; + + } + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd); + eRet = OMX_ErrorNotImplemented; + } + if(eRet == OMX_ErrorNone && bFlag) + { + post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); + } + sem_post(&m_cmd_lock); + return eRet; +} + +/* ====================================================================== +FUNCTION + omx_venc::ExecuteOmxFlush + +DESCRIPTION + Executes the OMX flush. + +PARAMETERS + flushtype - input flush(1)/output flush(0)/ both. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_video::execute_omx_flush(OMX_U32 flushType) +{ + bool bRet = false; + DEBUG_PRINT_LOW("\n execute_omx_flush - %d\n", flushType); +#ifdef _MSM8974_ + /* XXX: The driver/hardware does not support flushing of individual ports + * in all states. So we pretty much need to flush both ports internally, + * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it + * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, + * we automatically omit sending the FLUSH done for the "opposite" port. */ + + input_flush_progress = true; + output_flush_progress = true; + bRet = execute_flush_all(); +#else + if(flushType == 0 || flushType == OMX_ALL) + { + input_flush_progress = true; + //flush input only + bRet = execute_input_flush(); + } + if(flushType == 1 || flushType == OMX_ALL) + { + //flush output only + output_flush_progress = true; + bRet = execute_output_flush(); + } +#endif + return bRet; +} +/*========================================================================= +FUNCTION : execute_output_flush + +DESCRIPTION + Executes the OMX flush at OUTPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_video::execute_output_flush(void) +{ + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate FBD for all Buffers in the FTBq*/ + DEBUG_PRINT_LOW("\n execute_output_flush\n"); + pthread_mutex_lock(&m_lock); + while(m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + + if(ident == OMX_COMPONENT_GENERATE_FTB ) + { + pending_output_buffers++; + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_FBD) + { + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + + pthread_mutex_unlock(&m_lock); + /*Check if there are buffers with the Driver*/ + if(dev_flush(PORT_INDEX_OUT)) + { + DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed"); + return false; + } + + return bRet; +} +/*========================================================================= +FUNCTION : execute_input_flush + +DESCRIPTION + Executes the OMX flush at INPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +bool omx_video::execute_input_flush(void) +{ + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + /*Generate EBD for all Buffers in the ETBq*/ + DEBUG_PRINT_LOW("\n execute_input_flush\n"); + + pthread_mutex_lock(&m_lock); + while(m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_ETB) + { + pending_input_buffers++; + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_EBD) + { + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) + { + m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2); + } + } + if(mUseProxyColorFormat) { + if(psource_frame) { + m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame); + psource_frame = NULL; + } + while(m_opq_meta_q.m_size) { + unsigned p1,p2,id; + m_opq_meta_q.pop_entry(&p1,&p2,&id); + m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data, + (OMX_BUFFERHEADERTYPE *)p1); + } + if(pdest_frame){ + m_opq_pmem_q.insert_entry((unsigned int)pdest_frame,0,0); + pdest_frame = NULL; + } + } + pthread_mutex_unlock(&m_lock); + /*Check if there are buffers with the Driver*/ + if(dev_flush(PORT_INDEX_IN)) + { + DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed"); + return false; + } + + return bRet; +} + + +/*========================================================================= +FUNCTION : execute_flush + +DESCRIPTION + Executes the OMX flush at INPUT & OUTPUT PORT. + +PARAMETERS + None. + +RETURN VALUE + true/false +==========================================================================*/ +#ifdef _MSM8974_ +bool omx_video::execute_flush_all(void) +{ + unsigned p1 = 0; // Parameter - 1 + unsigned p2 = 0; // Parameter - 2 + unsigned ident = 0; + bool bRet = true; + + DEBUG_PRINT_LOW("\n execute_flush_all\n"); + + /*Generate EBD for all Buffers in the ETBq*/ + pthread_mutex_lock(&m_lock); + while(m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_ETB) + { + pending_input_buffers++; + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_EBD) + { + empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + + /*Generate FBD for all Buffers in the FTBq*/ + DEBUG_PRINT_LOW("\n execute_output_flush\n"); + while(m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + + if(ident == OMX_COMPONENT_GENERATE_FTB ) + { + pending_output_buffers++; + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); + } + else if(ident == OMX_COMPONENT_GENERATE_FBD) + { + fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); + } + } + + pthread_mutex_unlock(&m_lock); + + /*Check if there are buffers with the Driver*/ + if(dev_flush(PORT_INDEX_BOTH)) + { + DEBUG_PRINT_ERROR("\nERROR: dev_flush() Failed"); + return false; + } + return bRet; +} + +#endif + +/* ====================================================================== +FUNCTION + omx_venc::SendCommandEvent + +DESCRIPTION + Send the event to decoder pipe. This is needed to generate the callbacks + in decoder thread context. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +bool omx_video::post_event(unsigned int p1, + unsigned int p2, + unsigned int id) +{ + bool bRet = false; + + + pthread_mutex_lock(&m_lock); + + if ((id == OMX_COMPONENT_GENERATE_FTB) || + (id == OMX_COMPONENT_GENERATE_FBD) || + (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH)) + { + m_ftb_q.insert_entry(p1,p2,id); + } + else if ((id == OMX_COMPONENT_GENERATE_ETB) || + (id == OMX_COMPONENT_GENERATE_EBD) || + (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH)) + { + m_etb_q.insert_entry(p1,p2,id); + } + else + { + m_cmd_q.insert_entry(p1,p2,id); + } + + bRet = true; + DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); + post_message(this, id); + pthread_mutex_unlock(&m_lock); + + return bRet; +} + +/* ====================================================================== +FUNCTION + omx_venc::GetParameter + +DESCRIPTION + OMX Get Parameter method implementation + +PARAMETERS + . + +RETURN VALUE + Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_INOUT OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int height=0,width = 0; + + DEBUG_PRINT_LOW("get_parameter: \n"); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + switch(paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); + if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) + { + DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d", + m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin, + m_sInPortDef.nBufferCountActual); + memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); +#ifdef _ANDROID_ICS_ + if(meta_mode_enable) + { + portDefn->nBufferSize = sizeof(encoder_media_buffer_type); + } + if (mUseProxyColorFormat) { + portDefn->format.video.eColorFormat = + (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; + } +#endif + } + else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d", + m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin, + m_sOutPortDef.nBufferCountActual); + memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); + } + else + { + DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexParamVideoInit: + { + OMX_PORT_PARAM_TYPE *portParamType = + (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); + + memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam)); + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); + + if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) + { + int index = portFmt->nIndex; + if(index > 1) + eRet = OMX_ErrorNoMore; + else { + memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); +#ifdef _ANDROID_ICS_ + if (index == 1) { + //we support two formats + //index 0 - YUV420SP + //index 1 - opaque which internally maps to YUV420SP. + //this can be extended in the future + portFmt->nIndex = index; //restore index set from client + portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; + } +#endif + } + } + else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat)); + } + else + { + DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n"); + + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate)); + } + else + { + DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); + eRet = OMX_ErrorBadPortIndex; + } + + break; + } + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n"); + memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); + break; + } + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n"); + memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); + break; + } + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n"); + memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); + break; + } + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n"); + eRet = get_supported_profile_level(pParam); + if(eRet) + DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %lu, %lu", + pParam->eProfile, pParam->eLevel); + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n"); + memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamAudioInit: + { + OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); + memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); + break; + } + /*Component should support this port definition*/ + case OMX_IndexParamImageInit: + { + OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); + memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img)); + break; + + } + /*Component should support this port definition*/ + case OMX_IndexParamOtherInit: + { + DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + break; + } + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + comp_role->nVersion.nVersion = OMX_SPEC_VERSION; + comp_role->nSize = sizeof(*comp_role); + + DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex); + if(NULL != comp_role->cRole) + { + strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex); + eRet =OMX_ErrorBadParameter; + } + break; + } + /* Added for parameter test */ + case OMX_IndexParamPriorityMgmt: + { + + OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); + memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); + break; + } + /* Added for parameter test */ + case OMX_IndexParamCompBufferSupplier: + { + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); + if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) + { + memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier)); + } + else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) + { + memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier)); + } + else + { + DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + + case OMX_IndexParamVideoQuantization: + { + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n"); + memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); + break; + } + + case OMX_QcomIndexParamVideoQPRange: + { + OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; + DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange\n"); + memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange)); + break; + } + + case OMX_IndexParamVideoErrorCorrection: + { + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; + DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); + errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC; + errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync; + errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing; + break; + } + case OMX_IndexParamVideoIntraRefresh: + { + OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; + DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n"); + DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n"); + intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode; + intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs; + break; + } + case OMX_QcomIndexPortDefn: + //TODO + break; + case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: + { + OMXComponentCapabilityFlagsType *pParam = reinterpret_cast(paramData); + DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n"); + pParam->iIsOMXComponentMultiThreaded = OMX_TRUE; + pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE; + pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; + pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE; + pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE; + pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE; + pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE; + pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE; + m_use_input_pmem = OMX_TRUE; + DEBUG_PRINT_LOW("Supporting capability index in encoder node"); + break; + } +#if !defined(MAX_RES_720P) || defined(_MSM8974_) + case OMX_QcomIndexParamIndexExtraDataType: + { + DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType"); + QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; + if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) + { + if (pParam->nPortIndex == PORT_INDEX_OUT) + { + pParam->bEnabled = + (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0); + DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled); + } + else + { + DEBUG_PRINT_ERROR("get_parameter: slice information is " + "valid for output port only"); + eRet =OMX_ErrorUnsupportedIndex; + } + } +#ifndef _MSM8974_ + else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) + { + if (pParam->nPortIndex == PORT_INDEX_OUT) + { + pParam->bEnabled = + (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_LTRINFO) ? 1 : 0); + DEBUG_PRINT_HIGH("LTR Info extradata %d", pParam->bEnabled); + } + else + { + DEBUG_PRINT_ERROR("get_parameter: LTR information is " + "valid for output port only"); + eRet = OMX_ErrorUnsupportedIndex; + } + } +#endif + else + { + DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)", + pParam->nIndex); + eRet = OMX_ErrorUnsupportedIndex; + } + break; + } + case QOMX_IndexParamVideoLTRCountRangeSupported: + { + DEBUG_PRINT_HIGH("get_parameter: QOMX_IndexParamVideoLTRCountRangeSupported"); + QOMX_EXTNINDEX_RANGETYPE *pParam = (QOMX_EXTNINDEX_RANGETYPE *)paramData; + if (pParam->nPortIndex == PORT_INDEX_OUT) + { + OMX_U32 min = 0, max = 0, step_size = 0; + if (dev_get_capability_ltrcount(&min, &max, &step_size)) + { + pParam->nMin = min; + pParam->nMax = max; + pParam->nStepSize = step_size; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: get_capability_ltrcount failed"); + eRet = OMX_ErrorUndefined; + } + } + else + { + DEBUG_PRINT_ERROR("LTR count range is valid for output port only"); + eRet = OMX_ErrorUnsupportedIndex; + } + } + break; +#endif + case QOMX_IndexParamVideoSyntaxHdr: + { + DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr"); + QOMX_EXTNINDEX_PARAMTYPE* pParam = + reinterpret_cast(paramData); + if (pParam->pData == NULL) + { + DEBUG_PRINT_ERROR("Error: Data buffer is NULL"); + eRet = OMX_ErrorBadParameter; + break; + } + if (get_syntaxhdr_enable == false) + { + DEBUG_PRINT_ERROR("ERROR: get_parameter: Get syntax header disabled"); + eRet = OMX_ErrorUnsupportedIndex; + break; + } + BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); + if(dev_loaded_start()) + { + DEBUG_PRINT_LOW("device start successful"); + } + else + { + DEBUG_PRINT_ERROR("device start failed"); + BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); + return OMX_ErrorHardware; + } + if(dev_get_seq_hdr(pParam->pData, + (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)), + (unsigned *)&pParam->nDataSize)) + { + DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %lu)", + pParam->nDataSize); + for (unsigned i = 0; i < pParam->nDataSize; i++) { + DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i)); + } + } + else + { + DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()"); + eRet = OMX_ErrorHardware; + } + BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); + if(dev_loaded_stop()) + { + DEBUG_PRINT_LOW("device stop successful"); + } + else + { + DEBUG_PRINT_ERROR("device stop failed"); + BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); + eRet = OMX_ErrorHardware; + } + break; + } + case OMX_IndexParamVideoSliceFMO: + default: + { + DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x\n", paramIndex); + eRet =OMX_ErrorUnsupportedIndex; + break; + } + + } + + return eRet; + +} +/* ====================================================================== +FUNCTION + omx_video::GetConfig + +DESCRIPTION + OMX Get Config Method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_INOUT OMX_PTR configData) +{ + //////////////////////////////////////////////////////////////// + // Supported Config Index Type + // ============================================================= + // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE + // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE + // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE + //////////////////////////////////////////////////////////////// + + if(configData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: param is null"); + return OMX_ErrorBadParameter; + } + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); + return OMX_ErrorIncorrectStateOperation; + } + + //@todo need to validate params + switch(configIndex) + { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); + break; + } + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); + break; + } + case OMX_IndexConfigCommonRotate: + { + OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); + break; + } + case QOMX_IndexConfigVideoIntraperiod: + { + DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n"); + QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast(configData); + memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); + break; + } + case OMX_IndexConfigVideoAVCIntraPeriod: + { + OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam = + reinterpret_cast(configData); + DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod"); + memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod)); + break; + } + default: + DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); + return OMX_ErrorUnsupportedIndex; + } + return OMX_ErrorNone; + +} + +/* ====================================================================== +FUNCTION + omx_video::GetExtensionIndex + +DESCRIPTION + OMX GetExtensionIndex method implementaion. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_STRING paramName, + OMX_OUT OMX_INDEXTYPE* indexType) +{ + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n"); + return OMX_ErrorInvalidState; + } +#ifdef MAX_RES_1080P + if (!strncmp(paramName, "OMX.QCOM.index.param.SliceDeliveryMode", + sizeof("OMX.QCOM.index.param.SliceDeliveryMode") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; + return OMX_ErrorNone; + } +#endif +#ifdef _ANDROID_ICS_ + if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers",sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) { + *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoEncodeMetaBufferMode; + return OMX_ErrorNone; + } +#endif + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_video::GetState + +DESCRIPTION + Returns the state information back to the caller. + +PARAMETERS + . + +RETURN VALUE + Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_STATETYPE* state) +{ + *state = m_state; + DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_video::ComponentTunnelRequest + +DESCRIPTION + OMX Component Tunnel Request method implementation. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_HANDLETYPE peerComponent, + OMX_IN OMX_U32 peerPort, + OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) +{ + DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n"); + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_video::UseInputBuffer + +DESCRIPTION + Helper function for Use buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::use_input_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + unsigned i = 0; + unsigned char *buf_addr = NULL; + + DEBUG_PRINT_HIGH("use_input_buffer: port = %lu appData = %p bytes = %lu buffer = %p",port,appData,bytes,buffer); + if(bytes != m_sInPortDef.nBufferSize) + { + DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! " + "bytes[%lu] != Port.nBufferSize[%lu]", bytes, m_sInPortDef.nBufferSize); + return OMX_ErrorBadParameter; + } + + if(!m_inp_mem_ptr) + { + input_use_buffer = true; + m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); + if(m_inp_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); + return OMX_ErrorInsufficientResources; + } + + + m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); + if(m_pInput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); + return OMX_ErrorInsufficientResources; + } +#ifdef USE_ION + m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); + if(m_pInput_ion == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion"); + return OMX_ErrorInsufficientResources; + } +#endif + + for(i=0; i< m_sInPortDef.nBufferCountActual; i++) + { + m_pInput_pmem[i].fd = -1; +#ifdef USE_ION + m_pInput_ion[i].ion_device_fd =-1; + m_pInput_ion[i].fd_ion_data.fd =-1; + m_pInput_ion[i].ion_alloc_data.handle=NULL; +#endif + } + + } + + for(i=0; i< m_sInPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT(&m_inp_bm_count,i)) + { + break; + } + } + + if(i < m_sInPortDef.nBufferCountActual) + { + + *bufferHdr = (m_inp_mem_ptr + i); + BITMASK_SET(&m_inp_bm_count,i); + + (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; + (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); + (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; + (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; + (*bufferHdr)->pAppPrivate = appData; + (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; + + if(!m_use_input_pmem) + { +#ifdef USE_ION +#ifdef _MSM8974_ + m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, + &m_pInput_ion[i].ion_alloc_data, + &m_pInput_ion[i].fd_ion_data,0); +#else + m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, + &m_pInput_ion[i].ion_alloc_data, + &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); +#endif + if(m_pInput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); + return OMX_ErrorInsufficientResources; + } + m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; +#else + m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + if(m_pInput_pmem[i].fd == 0) + { + m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + } + + if(m_pInput_pmem[i] .fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; + m_pInput_pmem[i].offset = 0; + m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pInput_pmem[i].fd,0); + + if(m_pInput_pmem[i].buffer == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); + close(m_pInput_pmem[i].fd); +#ifdef USE_ION + free_ion_memory(&m_pInput_ion[i]); +#endif + return OMX_ErrorInsufficientResources; + } + } + else + { + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); + DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); + + if(pParam) + { + m_pInput_pmem[i].fd = pParam->pmem_fd; + m_pInput_pmem[i].offset = pParam->offset; + m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; + m_pInput_pmem[i].buffer = (unsigned char *)buffer; + DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u", + pParam->pmem_fd, pParam->offset); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); + return OMX_ErrorBadParameter; + } + } + + DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", + (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); + if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for " + "index = %u", i); + eRet = OMX_ErrorInsufficientResources; + } + + return eRet; +} + + + +/* ====================================================================== +FUNCTION + omx_video::UseOutputBuffer + +DESCRIPTION + Helper function for Use buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::use_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter + unsigned char *buf_addr = NULL; +#ifdef _MSM8974_ + int align_size; +#endif + + DEBUG_PRINT_HIGH("\n Inside use_output_buffer()"); + if(bytes != m_sOutPortDef.nBufferSize) + { + DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! " + "bytes[%lu] != Port.nBufferSize[%lu]", bytes, m_sOutPortDef.nBufferSize); + return OMX_ErrorBadParameter; + } + + if(!m_out_mem_ptr) + { + output_use_buffer = true; + int nBufHdrSize = 0; + + DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual); + nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); + /* + * Memory for output side involves the following: + * 1. Array of Buffer Headers + * 2. Bitmask array to hold the buffer allocation details + * In order to minimize the memory management entire allocation + * is done in one step. + */ + //OMX Buffer header + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + if(m_out_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr"); + return OMX_ErrorInsufficientResources; + } + + m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); + return OMX_ErrorInsufficientResources; + } +#ifdef USE_ION + m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_ion == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); + return OMX_ErrorInsufficientResources; + } +#endif + if(m_out_mem_ptr) + { + bufHdr = m_out_mem_ptr; + DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); + // Settting the entire storage nicely + for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + bufHdr->nAllocLen = bytes; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = appData; + bufHdr->nOutputPortIndex = PORT_INDEX_OUT; + bufHdr->pBuffer = NULL; + bufHdr++; + m_pOutput_pmem[i].fd = -1; +#ifdef USE_ION + m_pOutput_ion[i].ion_device_fd =-1; + m_pOutput_ion[i].fd_ion_data.fd=-1; + m_pOutput_ion[i].ion_alloc_data.handle =NULL; +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]\n",m_out_mem_ptr); + eRet = OMX_ErrorInsufficientResources; + } + } + + for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + break; + } + } + + if(eRet == OMX_ErrorNone) + { + if(i < m_sOutPortDef.nBufferCountActual) + { + *bufferHdr = (m_out_mem_ptr + i ); + (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; + (*bufferHdr)->pAppPrivate = appData; + BITMASK_SET(&m_out_bm_count,i); + + if(!m_use_output_pmem) + { +#ifdef USE_ION +#ifdef _MSM8974_ + align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; + m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, + &m_pOutput_ion[i].ion_alloc_data, + &m_pOutput_ion[i].fd_ion_data,0); +#else + m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory( + m_sOutPortDef.nBufferSize, + &m_pOutput_ion[i].ion_alloc_data, + &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); +#endif + if(m_pOutput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); + return OMX_ErrorInsufficientResources; + } + m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; +#else + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + + if(m_pOutput_pmem[i].fd == 0) + { + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + } + + if(m_pOutput_pmem[i].fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; + m_pOutput_pmem[i].offset = 0; +#ifdef _MSM8974_ + m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,align_size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pOutput_pmem[i].fd,0); +#else + m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pOutput_pmem[i].fd,0); +#endif + if(m_pOutput_pmem[i].buffer == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); + close(m_pOutput_pmem[i].fd); +#ifdef USE_ION + free_ion_memory(&m_pOutput_ion[i]); +#endif + return OMX_ErrorInsufficientResources; + } + } + else + { + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); + DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam); + + if(pParam) + { + DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); + m_pOutput_pmem[i].fd = pParam->pmem_fd; + m_pOutput_pmem[i].offset = pParam->offset; + m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; + m_pOutput_pmem[i].buffer = (unsigned char *)buffer; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); + return OMX_ErrorBadParameter; + } + buf_addr = (unsigned char *)buffer; + } + + DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", + (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); + if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) + { + DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " + "index = %u", i); + eRet = OMX_ErrorInsufficientResources; + } + } + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_video::UseBuffer + +DESCRIPTION + OMX Use Buffer method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None , if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::use_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes, + OMX_IN OMX_U8* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(port == PORT_INDEX_IN) + { + eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); + } + else if(port == PORT_INDEX_OUT) + { + eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); + eRet = OMX_ErrorBadPortIndex; + } + + if(eRet == OMX_ErrorNone) + { + if(allocate_done()) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + + } + else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_OUT, + OMX_COMPONENT_GENERATE_EVENT); + m_event_port_settings_sent = false; + } + } + } + return eRet; +} + +OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + OMX_U8 *temp_buff ; + + if(bufferHdr == NULL || m_inp_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", + bufferHdr, m_inp_mem_ptr); + return OMX_ErrorBadParameter; + } + + index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); +#ifdef _ANDROID_ICS_ + if(meta_mode_enable) + { + if(index < m_sInPortDef.nBufferCountActual) + { + memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); + memset(&meta_buffers[index], 0, sizeof(meta_buffers[index])); + } + if(!mUseProxyColorFormat) + return OMX_ErrorNone; + else + c2d_conv.close(); + } +#endif + if(index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat && + dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) + { + DEBUG_PRINT_LOW("\nERROR: dev_free_buf() Failed for i/p buf"); + } + + if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) + { + if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case"); + munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); + close (m_pInput_pmem[index].fd); +#ifdef USE_ION + free_ion_memory(&m_pInput_ion[index]); +#endif + m_pInput_pmem[index].fd = -1; + } + else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && + m_use_input_pmem == OMX_FALSE)) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case"); + if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); + } + munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); + close (m_pInput_pmem[index].fd); +#ifdef USE_ION + free_ion_memory(&m_pInput_ion[index]); +#endif + m_pInput_pmem[index].fd = -1; + } + else + { + DEBUG_PRINT_ERROR("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); + } + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) +{ + unsigned int index = 0; + OMX_U8 *temp_buff ; + + if(bufferHdr == NULL || m_out_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", + bufferHdr, m_out_mem_ptr); + return OMX_ErrorBadParameter; + } + index = bufferHdr - m_out_mem_ptr; + + if(index < m_sOutPortDef.nBufferCountActual && + dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) + { + DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); + } + + if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) + { + if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case"); + munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); + close (m_pOutput_pmem[index].fd); +#ifdef USE_ION + free_ion_memory(&m_pOutput_ion[index]); +#endif + m_pOutput_pmem[index].fd = -1; + } + else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true + && m_use_output_pmem == OMX_FALSE)) + { + DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case"); + if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) + { + DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); + } + munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); + close (m_pOutput_pmem[index].fd); +#ifdef USE_ION + free_ion_memory(&m_pOutput_ion[index]); +#endif + m_pOutput_pmem[index].fd = -1; + } + else + { + DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); + } + } + return OMX_ErrorNone; +} +#ifdef _ANDROID_ICS_ +OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( + OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE **bufferHdr, + OMX_PTR appData, + OMX_U32 bytes) +{ + unsigned index = 0; + if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type)) + { + DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %lu", + bufferHdr,bytes); + return OMX_ErrorBadParameter; + } + + if(!m_inp_mem_ptr && !mUseProxyColorFormat) + m_inp_mem_ptr = meta_buffer_hdr; + for(index = 0;((index < m_sInPortDef.nBufferCountActual) && + meta_buffer_hdr[index].pBuffer); index++); + if(index == m_sInPortDef.nBufferCountActual) + { + DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer"); + return OMX_ErrorBadParameter; + } + if(mUseProxyColorFormat){ + if(opaque_buffer_hdr[index]){ + DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); + return OMX_ErrorBadParameter; + } + if(allocate_input_buffer(hComp,&opaque_buffer_hdr[index], + PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) { + DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); + return OMX_ErrorBadParameter; + } + } + BITMASK_SET(&m_inp_bm_count,index); + *bufferHdr = &meta_buffer_hdr[index]; + memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); + meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]); + meta_buffer_hdr[index].nAllocLen = bytes; + meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION; + meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN; + meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index]; + meta_buffer_hdr[index].pAppPrivate = appData; + if(mUseProxyColorFormat) { + m_opq_pmem_q.insert_entry((unsigned int)opaque_buffer_hdr[index],0,0); + DEBUG_PRINT_HIGH("\n opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]); + } + return OMX_ErrorNone; +} +#endif +/* ====================================================================== +FUNCTION + omx_venc::AllocateInputBuffer + +DESCRIPTION + Helper function for allocate buffer in the input pin + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::allocate_input_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned i = 0; + + DEBUG_PRINT_HIGH("\n allocate_input_buffer()::"); + if(bytes != m_sInPortDef.nBufferSize) + { + DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%lu] != nBufferSize[%lu]\n", + bytes, m_sInPortDef.nBufferSize); + return OMX_ErrorBadParameter; + } + + if(!m_inp_mem_ptr) + { + DEBUG_PRINT_HIGH("%s: size = %lu, actual cnt %lu", __FUNCTION__, + m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual); + m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ + calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); + if(m_inp_mem_ptr == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); + return OMX_ErrorInsufficientResources; + } + + m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); + + if(m_pInput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); + return OMX_ErrorInsufficientResources; + } +#ifdef USE_ION + m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); + if(m_pInput_ion == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion"); + return OMX_ErrorInsufficientResources; + } +#endif + for(i=0; i< m_sInPortDef.nBufferCountActual; i++) + { + m_pInput_pmem[i].fd = -1; +#ifdef USE_ION + m_pInput_ion[i].ion_device_fd =-1; + m_pInput_ion[i].fd_ion_data.fd =-1; + m_pInput_ion[i].ion_alloc_data.handle=NULL; +#endif + } + } + + for(i=0; i< m_sInPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT(&m_inp_bm_count,i)) + { + break; + } + } + if(i < m_sInPortDef.nBufferCountActual) + { + + *bufferHdr = (m_inp_mem_ptr + i); + (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); + (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; + (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; + (*bufferHdr)->pAppPrivate = appData; + (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; + +#ifdef USE_ION +#ifdef _MSM8974_ + m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, + &m_pInput_ion[i].ion_alloc_data, + &m_pInput_ion[i].fd_ion_data,0); +#else + m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, + &m_pInput_ion[i].ion_alloc_data, + &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); +#endif + if(m_pInput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); + return OMX_ErrorInsufficientResources; + } + + m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; +#else + m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + + if(m_pInput_pmem[i].fd == 0) + { + m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + } + + if(m_pInput_pmem[i].fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; + m_pInput_pmem[i].offset = 0; + + m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pInput_pmem[i].fd,0); + if(m_pInput_pmem[i].buffer == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\nERROR: mmap FAILED= %d\n", errno); + close(m_pInput_pmem[i].fd); +#ifdef USE_ION + free_ion_memory(&m_pInput_ion[i]); +#endif + return OMX_ErrorInsufficientResources; + } + + (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; + DEBUG_PRINT_LOW("\n Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer); + BITMASK_SET(&m_inp_bm_count,i); + //here change the I/P param here from buf_adr to pmem + if(!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) + { + DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call" + "for index [%d]\n", i); + eRet = OMX_ErrorInsufficientResources; + } + + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_venc::AllocateOutputBuffer + +DESCRIPTION + Helper fn for AllocateBuffer in the output pin + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything went well. + +========================================================================== */ +OMX_ERRORTYPE omx_video::allocate_output_buffer( + OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header + unsigned i= 0; // Temporary counter +#ifdef _MSM8974_ + int align_size; +#endif + DEBUG_PRINT_HIGH("\n allocate_output_buffer()for %lu bytes", bytes); + if(!m_out_mem_ptr) + { + int nBufHdrSize = 0; + DEBUG_PRINT_HIGH("%s: size = %lu, actual cnt %lu", __FUNCTION__, + m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual); + nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); + + /* + * Memory for output side involves the following: + * 1. Array of Buffer Headers + * 2. Bitmask array to hold the buffer allocation details + * In order to minimize the memory management entire allocation + * is done in one step. + */ + m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); + +#ifdef USE_ION + m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_ion == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual); + if(m_pOutput_pmem == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); + return OMX_ErrorInsufficientResources; + } + if(m_out_mem_ptr && m_pOutput_pmem) + { + bufHdr = m_out_mem_ptr; + + for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) + { + bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); + bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; + // Set the values when we determine the right HxW param + bufHdr->nAllocLen = bytes; + bufHdr->nFilledLen = 0; + bufHdr->pAppPrivate = appData; + bufHdr->nOutputPortIndex = PORT_INDEX_OUT; + bufHdr->pBuffer = NULL; + bufHdr++; + m_pOutput_pmem[i].fd = -1; +#ifdef USE_ION + m_pOutput_ion[i].ion_device_fd =-1; + m_pOutput_ion[i].fd_ion_data.fd=-1; + m_pOutput_ion[i].ion_alloc_data.handle =NULL; +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem"); + eRet = OMX_ErrorInsufficientResources; + } + } + + DEBUG_PRINT_HIGH("\n actual cnt = %lu", m_sOutPortDef.nBufferCountActual); + for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) + { + if(BITMASK_ABSENT(&m_out_bm_count,i)) + { + DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); + break; + } + } + if(eRet == OMX_ErrorNone) + { + if(i < m_sOutPortDef.nBufferCountActual) + { +#ifdef USE_ION +#ifdef _MSM8974_ + align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; + m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, + &m_pOutput_ion[i].ion_alloc_data, + &m_pOutput_ion[i].fd_ion_data,0); +#else + m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize, + &m_pOutput_ion[i].ion_alloc_data, + &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); +#endif + if(m_pOutput_ion[i].ion_device_fd < 0) { + DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); + return OMX_ErrorInsufficientResources; + } + + m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; +#else + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + if(m_pOutput_pmem[i].fd == 0) + { + m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); + } + + if(m_pOutput_pmem[i].fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed"); + return OMX_ErrorInsufficientResources; + } +#endif + m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; + m_pOutput_pmem[i].offset = 0; +#ifdef _MSM8974_ + m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,align_size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pOutput_pmem[i].fd,0); +#else + m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, + MAP_SHARED,m_pOutput_pmem[i].fd,0); +#endif + if(m_pOutput_pmem[i].buffer == MAP_FAILED) + { + DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer"); + close (m_pOutput_pmem[i].fd); +#ifdef USE_ION + free_ion_memory(&m_pOutput_ion[i]); +#endif + return OMX_ErrorInsufficientResources; + } + + *bufferHdr = (m_out_mem_ptr + i ); + (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer; + (*bufferHdr)->pAppPrivate = appData; + + BITMASK_SET(&m_out_bm_count,i); + + if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf"); + return OMX_ErrorInsufficientResources; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call" + "for index [%d] actual: %lu\n", i, m_sOutPortDef.nBufferCountActual); + } + } + + return eRet; +} + + +// AllocateBuffer -- API Call +/* ====================================================================== +FUNCTION + omx_video::AllocateBuffer + +DESCRIPTION + Returns zero if all the buffers released.. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN OMX_U32 bytes) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type + + DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + // What if the client calls again. + if(port == PORT_INDEX_IN) + { +#ifdef _ANDROID_ICS_ + if(meta_mode_enable) + eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes); + else +#endif + eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); + } + else if(port == PORT_INDEX_OUT) + { + eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); + if(eRet == OMX_ErrorNone) + { + if(allocate_done()) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); + post_event(OMX_CommandStateSet,OMX_StateIdle, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + } + if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) + { + if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) + { + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); + post_event(OMX_CommandPortEnable, + PORT_INDEX_OUT, + OMX_COMPONENT_GENERATE_EVENT); + m_event_port_settings_sent = false; + } + } + } + DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); + return eRet; +} + + +// Free Buffer - API call +/* ====================================================================== +FUNCTION + omx_video::FreeBuffer + +DESCRIPTION + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_U32 port, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + unsigned int nPortIndex; + + DEBUG_PRINT_LOW("In for encoder free_buffer \n"); + + if(m_state == OMX_StateIdle && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); + } + else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)|| + (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) + { + DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); + } + else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) + { + DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + return eRet; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n"); + post_event(OMX_EventError, + OMX_ErrorPortUnpopulated, + OMX_COMPONENT_GENERATE_EVENT); + } + + if(port == PORT_INDEX_IN) + { + // check if the buffer is valid + nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); + + DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n", + nPortIndex, m_sInPortDef.nBufferCountActual); + if(nPortIndex < m_sInPortDef.nBufferCountActual) + { + // Clear the bit associated with it. + BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); + free_input_buffer (buffer); + m_sInPortDef.bPopulated = OMX_FALSE; + + /*Free the Buffer Header*/ + if(release_input_done() +#ifdef _ANDROID_ICS_ + && !meta_mode_enable +#endif + ) + { + input_use_buffer = false; + if(m_inp_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n"); + free (m_inp_mem_ptr); + m_inp_mem_ptr = NULL; + } + if(m_pInput_pmem) + { + DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n"); + free(m_pInput_pmem); + m_pInput_pmem = NULL; + } +#ifdef USE_ION + if(m_pInput_ion) + { + DEBUG_PRINT_LOW("Freeing m_pInput_ion\n"); + free(m_pInput_ion); + m_pInput_ion = NULL; + } +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) + && release_input_done()) + { + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); + post_event(OMX_CommandPortDisable, + PORT_INDEX_IN, + OMX_COMPONENT_GENERATE_EVENT); + } + } + else if(port == PORT_INDEX_OUT) + { + // check if the buffer is valid + nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; + + DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n", + nPortIndex, m_sOutPortDef.nBufferCountActual); + if(nPortIndex < m_sOutPortDef.nBufferCountActual) + { + // Clear the bit associated with it. + BITMASK_CLEAR(&m_out_bm_count,nPortIndex); + m_sOutPortDef.bPopulated = OMX_FALSE; + free_output_buffer (buffer); + + if(release_output_done()) + { + output_use_buffer = false; + if(m_out_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n"); + free (m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + if(m_pOutput_pmem) + { + DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n"); + free(m_pOutput_pmem); + m_pOutput_pmem = NULL; + } +#ifdef USE_ION + if(m_pOutput_ion) + { + DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n"); + free(m_pOutput_ion); + m_pOutput_ion = NULL; + } +#endif + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n"); + eRet = OMX_ErrorBadPortIndex; + } + if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) + && release_output_done() ) + { + DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); + + DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); + post_event(OMX_CommandPortDisable, + PORT_INDEX_OUT, + OMX_COMPONENT_GENERATE_EVENT); + + } + } + else + { + eRet = OMX_ErrorBadPortIndex; + } + if((eRet == OMX_ErrorNone) && + (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) + { + if(release_done()) + { + if(dev_stop() != 0) + { + DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n"); + eRet = OMX_ErrorHardware; + } + // Send the callback now + BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); + post_event(OMX_CommandStateSet, OMX_StateLoaded, + OMX_COMPONENT_GENERATE_EVENT); + } else { + DEBUG_PRINT_ERROR("in free buffer, release not done, need to free more buffers input 0x%x output 0x%x", + m_out_bm_count, m_inp_bm_count); + } + } + + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_video::EmptyThisBuffer + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_ERRORTYPE ret1 = OMX_ErrorNone; + unsigned int nBufferIndex ; + + DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) + { + DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid"); + return OMX_ErrorBadParameter; + } + + if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) + { + DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid"); + return OMX_ErrorVersionMismatch; + } + + if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) + { + DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer"); + return OMX_ErrorBadPortIndex; + } + if(!m_sInPortDef.bEnabled) + { + DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled"); + return OMX_ErrorIncorrectStateOperation; + } + + nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); + + if(nBufferIndex > m_sInPortDef.nBufferCountActual ) + { + DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex); + return OMX_ErrorBadParameter; + } + + m_etb_count++; + DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp); + post_event ((unsigned)hComp,(unsigned)buffer,m_input_msg_id); + return OMX_ErrorNone; +} +/* ====================================================================== +FUNCTION + omx_video::empty_this_buffer_proxy + +DESCRIPTION + This routine is used to push the encoded video frames to + the video decoder. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything went successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + OMX_U8 *pmem_data_buf = NULL; + int push_cnt = 0; + unsigned nBufIndex = 0, nBufIndex_meta = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + encoder_media_buffer_type *media_buffer; + +#ifdef _MSM8974_ + int fd = 0; +#endif + DEBUG_PRINT_LOW("\n ETBProxy: buffer->pBuffer[%p]\n", buffer->pBuffer); + if(buffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer); + return OMX_ErrorBadParameter; + } + nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); + nBufIndex_meta = buffer - meta_buffer_hdr; + media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer; + if(nBufIndex >= m_sInPortDef.nBufferCountActual && + nBufIndex_meta >= m_sInPortDef.nBufferCountActual) + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex); + return OMX_ErrorBadParameter; + } + pending_input_buffers++; + if(input_flush_progress == true) + { + post_event ((unsigned int)buffer,0, + OMX_COMPONENT_GENERATE_EBD); + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress"); + return OMX_ErrorNone; + } +#ifdef _MSM8974_ + if(!meta_mode_enable || + (media_buffer && media_buffer->buffer_type == kMetadataBufferTypeGrallocSource)) { + fd = m_pInput_pmem[nBufIndex].fd; + } +#endif +#ifdef _ANDROID_ICS_ + if(meta_mode_enable && !mUseProxyColorFormat) + { + bool met_error = false; + if(media_buffer) + { + if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource && + media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) + met_error = true; + else { + if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) + { + if(media_buffer->meta_handle == NULL) + met_error = true; + else if((media_buffer->meta_handle->numFds != 1 && + media_buffer->meta_handle->numInts != 2)) + met_error = true; + } + } + } else + met_error = true; + if(met_error) + { + DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call"); + post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorBadParameter; + } + struct pmem Input_pmem_info; + if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) + { + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = media_buffer->meta_handle->data[0]; +#ifdef _MSM8974_ + fd = Input_pmem_info.fd; +#endif + Input_pmem_info.offset = media_buffer->meta_handle->data[1]; + Input_pmem_info.size = media_buffer->meta_handle->data[2]; + DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, + Input_pmem_info.offset, + Input_pmem_info.size); + } else { + private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = handle->fd; +#ifdef _MSM8974_ + fd = Input_pmem_info.fd; +#endif + Input_pmem_info.offset = 0; + Input_pmem_info.size = handle->size; + } + if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { + DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); + post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); + return OMX_ErrorBadParameter; + } + } + else if(input_use_buffer && !m_use_input_pmem) +#else + if(input_use_buffer && !m_use_input_pmem) +#endif + { + DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data"); + pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; + memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), + buffer->nFilledLen); + DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); + } +#ifdef _MSM8974_ + if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true) +#else + if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true) +#endif + { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed"); +#ifdef _ANDROID_ICS_ + omx_release_meta_buffer(buffer); +#endif + post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); + /*Generate an async error and move to invalid state*/ + pending_input_buffers--; + return OMX_ErrorBadParameter; + } + return ret; +} + +/* ====================================================================== +FUNCTION + omx_video::FillThisBuffer + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer); + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n"); + return OMX_ErrorInvalidState; + } + + if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n"); + return OMX_ErrorBadParameter; + } + + if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n"); + return OMX_ErrorVersionMismatch; + } + + if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n"); + return OMX_ErrorBadPortIndex; + } + + if(!m_sOutPortDef.bEnabled) + { + DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n"); + return OMX_ErrorIncorrectStateOperation; + } + + post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB); + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_video::fill_this_buffer_proxy + +DESCRIPTION + IL client uses this method to release the frame buffer + after displaying them. + +PARAMETERS + None. + +RETURN VALUE + true/false + +========================================================================== */ +OMX_ERRORTYPE omx_video::fill_this_buffer_proxy( + OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) +{ + OMX_U8 *pmem_data_buf = NULL; + OMX_ERRORTYPE nRet = OMX_ErrorNone; + + DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer); + + if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) ) + { + DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n"); + return OMX_ErrorBadParameter; + } + + pending_output_buffers++; + /*Return back the output buffer to client*/ + if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) + { + DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress"); + post_event ((unsigned int)bufferAdd,0, + OMX_COMPONENT_GENERATE_FBD); + return OMX_ErrorNone; + } + + if(output_use_buffer && !m_use_output_pmem) + { + DEBUG_PRINT_LOW("\n Heap UseBuffer case"); + pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer; + } + + if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) + { + DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed"); + post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD); + pending_output_buffers--; + return OMX_ErrorBadParameter; + } + + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_video::SetCallbacks + +DESCRIPTION + Set the callbacks. + +PARAMETERS + None. + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_CALLBACKTYPE* callbacks, + OMX_IN OMX_PTR appData) +{ + + m_pCallbacks = *callbacks; + DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\ + m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone); + m_app_data = appData; + return OMX_ErrorNotImplemented; +} + + +/* ====================================================================== +FUNCTION + omx_venc::UseEGLImage + +DESCRIPTION + OMX Use EGL Image method implementation . + +PARAMETERS + . + +RETURN VALUE + Not Implemented error. + +========================================================================== */ +OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, + OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, + OMX_IN OMX_U32 port, + OMX_IN OMX_PTR appData, + OMX_IN void* eglImage) +{ + DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n"); + return OMX_ErrorNotImplemented; +} + +/* ====================================================================== +FUNCTION + omx_venc::ComponentRoleEnum + +DESCRIPTION + OMX Component Role Enum method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything is successful. +========================================================================== */ +OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, + OMX_OUT OMX_U8* role, + OMX_IN OMX_U32 index) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } +#ifdef _MSM8974_ + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + if((0 == index) && role) + { + strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); + DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); + eRet = OMX_ErrorNoMore; + } + } +#endif + else + { + DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } + return eRet; +} + + + + +/* ====================================================================== +FUNCTION + omx_venc::AllocateDone + +DESCRIPTION + Checks if entire buffer pool is allocated by IL Client or not. + Need this to move to IDLE state. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_video::allocate_done(void) +{ + bool bRet = false; + bool bRet_In = false; + bool bRet_Out = false; + + bRet_In = allocate_input_done(); + bRet_Out = allocate_output_done(); + + if(bRet_In && bRet_Out) + { + bRet = true; + } + + return bRet; +} +/* ====================================================================== +FUNCTION + omx_venc::AllocateInputDone + +DESCRIPTION + Checks if I/P buffer pool is allocated by IL Client or not. + +PARAMETERS + None. + +RETURN VALUE + true/false. + +========================================================================== */ +bool omx_video::allocate_input_done(void) +{ + bool bRet = false; + unsigned i=0; + + if(m_inp_mem_ptr == NULL) + { + return bRet; + } + if(m_inp_mem_ptr ) + { + for(;ipBuffer[%p], flags=0x%x size = %d", + buffer->pBuffer, buffer->nFlags,buffer->nFilledLen); + if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual)) + { + return OMX_ErrorBadParameter; + } + + pending_output_buffers--; + + extra_data_handle.create_extra_data(buffer); +#ifndef _MSM8974_ + if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { + DEBUG_PRINT_LOW("parsing extradata"); + extra_data_handle.parse_extra_data(buffer); + } +#endif + /* For use buffer we need to copy the data */ + if(m_pCallbacks.FillBufferDone) + { + if(buffer->nFilledLen > 0) + { + m_fbd_count++; + +#ifdef OUTPUT_BUFFER_LOG + if(outputBufferFile1) + { + fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1); + } +#endif + } +#ifdef _MSM8974_ + if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { + if(!dev_handle_extradata((void *)buffer, index)) + DEBUG_PRINT_ERROR("Failed to parse extradata\n"); + } +#endif + m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer); + } + else + { + return OMX_ErrorBadParameter; + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, + OMX_BUFFERHEADERTYPE* buffer) +{ + int buffer_index = -1; + int buffer_index_meta = -1; + + buffer_index = (buffer - m_inp_mem_ptr); + buffer_index_meta = (buffer - meta_buffer_hdr); + DEBUG_PRINT_LOW("\n empty_buffer_done: buffer[%p]", buffer); + if(buffer == NULL || + ((buffer_index > m_sInPortDef.nBufferCountActual) && + (buffer_index_meta > m_sInPortDef.nBufferCountActual))) + { + DEBUG_PRINT_ERROR("\n ERROR in empty_buffer_done due to index buffer"); + return OMX_ErrorBadParameter; + } + + pending_input_buffers--; + + if(mUseProxyColorFormat && (buffer_index < m_sInPortDef.nBufferCountActual)) { + if(!pdest_frame) { + pdest_frame = buffer; + DEBUG_PRINT_LOW("\n empty_buffer_done pdest_frame address is %p",pdest_frame); + return push_input_buffer(hComp); + + } else { + DEBUG_PRINT_LOW("\n empty_buffer_done insert address is %p",buffer); + if (!m_opq_pmem_q.insert_entry((unsigned int)buffer, 0, 0)) { + DEBUG_PRINT_ERROR("\n empty_buffer_done: pmem queue is full"); + return OMX_ErrorBadParameter; + } + } + } else if(m_pCallbacks.EmptyBufferDone) { + m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer); + } + return OMX_ErrorNone; +} + +void omx_video::complete_pending_buffer_done_cbs() +{ + unsigned p1; + unsigned p2; + unsigned ident; + omx_cmd_queue tmp_q, pending_bd_q; + pthread_mutex_lock(&m_lock); + // pop all pending GENERATE FDB from ftb queue + while (m_ftb_q.m_size) + { + m_ftb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_FBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to ftb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_ftb_q.insert_entry(p1,p2,ident); + } + // pop all pending GENERATE EDB from etb queue + while (m_etb_q.m_size) + { + m_etb_q.pop_entry(&p1,&p2,&ident); + if(ident == OMX_COMPONENT_GENERATE_EBD) + { + pending_bd_q.insert_entry(p1,p2,ident); + } + else + { + tmp_q.insert_entry(p1,p2,ident); + } + } + //return all non GENERATE FDB to etb queue + while(tmp_q.m_size) + { + tmp_q.pop_entry(&p1,&p2,&ident); + m_etb_q.insert_entry(p1,p2,ident); + } + pthread_mutex_unlock(&m_lock); + // process all pending buffer dones + while(pending_bd_q.m_size) + { + pending_bd_q.pop_entry(&p1,&p2,&ident); + switch(ident) + { + case OMX_COMPONENT_GENERATE_EBD: + if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) + { + DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); + omx_report_error (); + } + break; + + case OMX_COMPONENT_GENERATE_FBD: + if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) + { + DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); + omx_report_error (); + } + break; + } + } +} + +#ifdef MAX_RES_720P +OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 1) { + if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", + profileLevelType->eProfile,profileLevelType->eLevel); + return eRet; +} +#endif + +#ifdef MAX_RES_1080P +OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + if(!profileLevelType) + return OMX_ErrorBadParameter; + + if(profileLevelType->nPortIndex == 1) { + if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) + { +#ifdef _MSM8974_ + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; + + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } +#else + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + + } + else if (profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else if(profileLevelType->nProfileIndex == 2) + { + profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; + profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; + } + else + { + DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", + profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } +#endif + } + else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; + profileLevelType->eLevel = OMX_VIDEO_H263Level70; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) + { + if (profileLevelType->nProfileIndex == 0) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else if(profileLevelType->nProfileIndex == 1) + { + profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore\n"); + eRet = OMX_ErrorNoMore; + } + } + else + { + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%lu, Level:%lu\n", + profileLevelType->eProfile,profileLevelType->eLevel); + return eRet; +} +#endif + +#ifdef USE_ION +int alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data, + struct ion_fd_data *fd_data,int flag) +{ + struct venc_ion buf_ion_info; + int ion_device_fd =-1,rc=0,ion_dev_flags = 0; + if (size <=0 || !alloc_data || !fd_data) { + DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory"); + return -EINVAL; + } + + ion_dev_flags = O_RDONLY; + ion_device_fd = open (MEM_DEVICE,ion_dev_flags); + if(ion_device_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed"); + return ion_device_fd; + } + alloc_data->len = size; + alloc_data->align = 4096; + alloc_data->flags = flag; +#ifdef MAX_RES_720P + alloc_data->len = (size + (alloc_data->align - 1)) & ~(alloc_data->align - 1); + alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); +#else + alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | + ION_HEAP(ION_IOMMU_HEAP_ID)); +#endif + rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data); + if(rc || !alloc_data->handle) { + DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); + alloc_data->handle =NULL; + close(ion_device_fd); + ion_device_fd = -1; + return ion_device_fd; + } + fd_data->handle = alloc_data->handle; + rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data); + if(rc) { + DEBUG_PRINT_ERROR("\n ION MAP failed "); + buf_ion_info.ion_alloc_data = *alloc_data; + buf_ion_info.ion_device_fd = ion_device_fd; + buf_ion_info.fd_ion_data = *fd_data; + free_ion_memory(&buf_ion_info); + fd_data->fd =-1; + ion_device_fd =-1; + } + return ion_device_fd; +} + +void free_ion_memory(struct venc_ion *buf_ion_info) +{ + if (!buf_ion_info) { + DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory"); + return; + } + if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, + &buf_ion_info->ion_alloc_data.handle)) { + DEBUG_PRINT_ERROR("\n ION free failed "); + return; + } + close(buf_ion_info->ion_device_fd); + buf_ion_info->ion_alloc_data.handle = NULL; + buf_ion_info->ion_device_fd = -1; + buf_ion_info->fd_ion_data.fd = -1; +} +#endif + +#ifdef _ANDROID_ICS_ +void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer) +{ + if(buffer && meta_mode_enable) + { + encoder_media_buffer_type *media_ptr; + struct pmem Input_pmem; + unsigned int index_pmem = 0; + bool meta_error = false; + + index_pmem = (buffer - m_inp_mem_ptr); + if(mUseProxyColorFormat && + (index_pmem < m_sInPortDef.nBufferCountActual)) { + if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){ + DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed"); + } + } else { + media_ptr = (encoder_media_buffer_type *) buffer->pBuffer; + if(media_ptr && media_ptr->meta_handle) + { + if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource && + media_ptr->meta_handle->numFds == 1 && + media_ptr->meta_handle->numInts == 2) { + Input_pmem.fd = media_ptr->meta_handle->data[0]; + Input_pmem.buffer = media_ptr; + Input_pmem.size = media_ptr->meta_handle->data[2]; + Input_pmem.offset = media_ptr->meta_handle->data[1]; + DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd, + Input_pmem.offset, + Input_pmem.size); + } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) { + private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle; + Input_pmem.buffer = media_ptr; + Input_pmem.fd = handle->fd; + Input_pmem.offset = 0; + Input_pmem.size = handle->size; + } else { + meta_error = true; + DEBUG_PRINT_ERROR(" Meta Error set in EBD"); + } + if(!meta_error) + meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN); + if(meta_error) + { + DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d", + input_flush_progress); + } + } + } + } +} +#endif +omx_video::omx_c2d_conv::omx_c2d_conv() +{ + c2dcc = NULL; + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; + src_format = NV12_128m; + pthread_mutex_init(&c_lock, NULL); +} + +bool omx_video::omx_c2d_conv::init() { + bool status = true; + if(mLibHandle || mConvertOpen || mConvertClose) { + DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice"); + status = false; + } + if(status) { + mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); + if(mLibHandle){ + mConvertOpen = (createC2DColorConverter_t *) + dlsym(mLibHandle,"createC2DColorConverter"); + mConvertClose = (destroyC2DColorConverter_t *) + dlsym(mLibHandle,"destroyC2DColorConverter"); + if(!mConvertOpen || !mConvertClose) + status = false; + } else + status = false; + } + if(!status && mLibHandle){ + dlclose(mLibHandle); + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; + } + return status; +} + +bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, + int dest_fd, void *dest_base, void *dest_viraddr) +{ + int result; + if(!src_viraddr || !dest_viraddr || !c2dcc || !src_base || !dest_base){ + DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); + return false; + } + pthread_mutex_lock(&c_lock); + result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, + dest_fd, dest_base, dest_viraddr); + pthread_mutex_unlock(&c_lock); + DEBUG_PRINT_LOW("\n Color convert status %d",result); + return ((result < 0)?false:true); +} + +bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width, + ColorConvertFormat src, ColorConvertFormat dest,unsigned int src_stride) +{ + bool status = false; + pthread_mutex_lock(&c_lock); + if(!c2dcc) { + c2dcc = mConvertOpen(width, height, width, height, + src,dest,0,src_stride); + if(c2dcc) { + src_format = src; + status = true; + } else + DEBUG_PRINT_ERROR("\n mConvertOpen failed"); + } + pthread_mutex_unlock(&c_lock); + return status; +} + +void omx_video::omx_c2d_conv::close() +{ + if(mLibHandle) { + pthread_mutex_lock(&c_lock); + if(mConvertClose && c2dcc) + mConvertClose(c2dcc); + pthread_mutex_unlock(&c_lock); + c2dcc = NULL; + } +} +omx_video::omx_c2d_conv::~omx_c2d_conv() +{ + DEBUG_PRINT_ERROR("\n Destroy C2D instance"); + if(mLibHandle) { + if(mConvertClose && c2dcc) { + pthread_mutex_lock(&c_lock); + mConvertClose(c2dcc); + pthread_mutex_unlock(&c_lock); + } + dlclose(mLibHandle); + } + c2dcc = NULL; + mLibHandle = NULL; + mConvertOpen = NULL; + mConvertClose = NULL; + pthread_mutex_destroy(&c_lock); +} + +int omx_video::omx_c2d_conv::get_src_format() +{ + int format = -1; + if(src_format == NV12_128m) { + format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; + } else if(src_format == RGBA8888) { + format = HAL_PIXEL_FORMAT_RGBA_8888; + } + return format; +} + +bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) +{ + int cret = 0; + bool ret = false; + C2DBuffReq bufferreq; + if(c2dcc){ + bufferreq.size = 0; + pthread_mutex_lock(&c_lock); + cret = c2dcc->getBuffReq(port,&bufferreq); + pthread_mutex_unlock(&c_lock); + DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret); + ret = (cret)?false:true; + buf_size = bufferreq.size; + } + return ret; +} + +OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_BUFFERHEADERTYPE* buffer) +{ + unsigned nBufIndex = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + encoder_media_buffer_type *media_buffer; + DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer); + + if(buffer == NULL) { + DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer); + return OMX_ErrorBadParameter; + } + nBufIndex = buffer - meta_buffer_hdr; + if(nBufIndex >= m_sInPortDef.nBufferCountActual) { + DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n", + nBufIndex); + return OMX_ErrorBadParameter; + } + media_buffer = (encoder_media_buffer_type *)buffer->pBuffer; + private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; + /*Enable following code once private handle color format is + updated correctly*/ + + if(c2d_opened && handle->format != c2d_conv.get_src_format()) { + c2d_conv.close(); + c2d_opened = false; + } + if (!c2d_opened) { + if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) { + DEBUG_PRINT_ERROR("\n open Color conv for RGBA888 W: %d, H: %d\n", + m_sInPortDef.format.video.nFrameWidth, + m_sInPortDef.format.video.nFrameHeight); + if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight, + m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_128m,handle->width)){ + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + DEBUG_PRINT_ERROR("\n Color conv open failed"); + return OMX_ErrorBadParameter; + } + c2d_opened = true; +#ifdef _MSM8974_ + if(!dev_set_format(handle->format)) + DEBUG_PRINT_ERROR("cannot set color format for RGBA8888\n"); +#endif + } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { + DEBUG_PRINT_ERROR("\n Incorrect color format"); + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + return OMX_ErrorBadParameter; + } + } + if(input_flush_progress == true) + { + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress"); + return OMX_ErrorNone; + } + + if(!psource_frame) { + psource_frame = buffer; + ret = push_input_buffer(hComp); + } else { + if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) { + DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full"); + ret = OMX_ErrorBadParameter; + } + } + if(ret != OMX_ErrorNone) { + m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); + DEBUG_PRINT_LOW("\nERROR: ETBOpaque failed:"); + } + return ret; +} + +OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp, + struct pmem &Input_pmem_info) { + + OMX_ERRORTYPE ret = OMX_ErrorNone; + unsigned address = 0,p2,id; + + DEBUG_PRINT_LOW("\n In queue Meta Buffer"); + if(!psource_frame || !pdest_frame) { + DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); + return OMX_ErrorBadParameter; + } + + if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { + DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); + post_event ((unsigned int)psource_frame,0,OMX_COMPONENT_GENERATE_EBD); + ret = OMX_ErrorBadParameter; + } + + if(ret == OMX_ErrorNone) + ret = empty_this_buffer_proxy(hComp,psource_frame); + + if(ret == OMX_ErrorNone) { + psource_frame = NULL; + if(!psource_frame && m_opq_meta_q.m_size) { + m_opq_meta_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + } + return ret; +} + +OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp, + struct pmem &Input_pmem_info,unsigned &index){ + + unsigned char *uva; + OMX_ERRORTYPE ret = OMX_ErrorNone; + unsigned address = 0,p2,id; + + DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer"); + if(!psource_frame || !pdest_frame) { + DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); + return OMX_ErrorBadParameter; + } + + if(!psource_frame->nFilledLen){ + pdest_frame->nOffset = 0; + pdest_frame->nFilledLen = 0; + pdest_frame->nTimeStamp = psource_frame->nTimeStamp; + pdest_frame->nFlags = psource_frame->nFlags; + DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", + pdest_frame,pdest_frame->nFilledLen); + } else { + uva = (unsigned char *)mmap(NULL, Input_pmem_info.size, + PROT_READ|PROT_WRITE, + MAP_SHARED,Input_pmem_info.fd,0); + if(uva == MAP_FAILED) { + ret = OMX_ErrorBadParameter; + } else { + if(!c2d_conv.convert(Input_pmem_info.fd, uva, uva, + m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) { + DEBUG_PRINT_ERROR("\n Color Conversion failed"); + ret = OMX_ErrorBadParameter; + } else { + unsigned int buf_size = 0; + if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size)) + ret = OMX_ErrorBadParameter; + else { + pdest_frame->nOffset = 0; + pdest_frame->nFilledLen = buf_size; + pdest_frame->nTimeStamp = psource_frame->nTimeStamp; + pdest_frame->nFlags = psource_frame->nFlags; + DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", + pdest_frame,pdest_frame->nFilledLen); + } + } + munmap(uva,Input_pmem_info.size); + } + } + if(dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) { + DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); + post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD); + ret = OMX_ErrorBadParameter; + } + if(ret == OMX_ErrorNone) + ret = empty_this_buffer_proxy(hComp,pdest_frame); + if(ret == OMX_ErrorNone) { + m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame); + psource_frame = NULL; + pdest_frame = NULL; + if(!psource_frame && m_opq_meta_q.m_size) { + m_opq_meta_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + if(!pdest_frame && m_opq_pmem_q.m_size) { + m_opq_pmem_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; + DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame); + } + } + return ret; +} + +OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp) +{ + unsigned address = 0,p2,id, index = 0; + OMX_ERRORTYPE ret = OMX_ErrorNone; + + if(!psource_frame && m_opq_meta_q.m_size) { + m_opq_meta_q.pop_entry(&address,&p2,&id); + psource_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + if(!pdest_frame && m_opq_pmem_q.m_size) { + m_opq_pmem_q.pop_entry(&address,&p2,&id); + pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; + } + while(psource_frame != NULL && pdest_frame != NULL && + ret == OMX_ErrorNone) { + struct pmem Input_pmem_info; + encoder_media_buffer_type *media_buffer; + index = pdest_frame - m_inp_mem_ptr; + if(index >= m_sInPortDef.nBufferCountActual){ + DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d", + index,m_sInPortDef.nBufferCountActual); + return OMX_ErrorBadParameter; + } + media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer; + /*Will enable to verify camcorder in current TIPS can be removed*/ + if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = media_buffer->meta_handle->data[0]; + Input_pmem_info.offset = media_buffer->meta_handle->data[1]; + Input_pmem_info.size = media_buffer->meta_handle->data[2]; + DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, + Input_pmem_info.offset, + Input_pmem_info.size); + ret = queue_meta_buffer(hComp,Input_pmem_info); + } else { + private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; + Input_pmem_info.buffer = media_buffer; + Input_pmem_info.fd = handle->fd; + Input_pmem_info.offset = 0; + Input_pmem_info.size = handle->size; + if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888) + ret = convert_queue_buffer(hComp,Input_pmem_info,index); + else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) + ret = queue_meta_buffer(hComp,Input_pmem_info); + else + ret = OMX_ErrorBadParameter; + } + } + return ret; +} diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp new file mode 100644 index 00000000..e47db8f3 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp @@ -0,0 +1,1933 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "omx_video_encoder.h" +#include +#include "video_encoder_device.h" +#include +#ifdef _ANDROID_ICS_ +#include +#endif +#ifdef _ANDROID_ +#include +#endif +#ifndef _ANDROID_ +#include +#define strlcpy g_strlcpy +#endif +/*---------------------------------------------------------------------------- +* Preprocessor Definitions and Constants +* -------------------------------------------------------------------------*/ + +#define OMX_SPEC_VERSION 0x00000101 +#define OMX_INIT_STRUCT(_s_, _name_) \ + memset((_s_), 0x0, sizeof(_name_)); \ + (_s_)->nSize = sizeof(_name_); \ + (_s_)->nVersion.nVersion = OMX_SPEC_VERSION + +extern int m_pipe; + +// factory function executed by the core to create instances +void *get_omx_component_factory_fn(void) +{ + return(new omx_venc); +} + +//constructor + +omx_venc::omx_venc() +{ +#ifdef _ANDROID_ICS_ + meta_mode_enable = false; + memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr)); + memset(meta_buffers,0,sizeof(meta_buffers)); + memset(opaque_buffer_hdr,0,sizeof(opaque_buffer_hdr)); + mUseProxyColorFormat = false; + get_syntaxhdr_enable = false; +#endif +} + +omx_venc::~omx_venc() +{ + get_syntaxhdr_enable = false; + //nothing to do +} + +/* ====================================================================== +FUNCTION + omx_venc::ComponentInit + +DESCRIPTION + Initialize the component. + +PARAMETERS + ctxt -- Context information related to the self. + id -- Event identifier. This could be any of the following: + 1. Command completion event + 2. Buffer done callback event + 3. Frame done callback event + +RETURN VALUE + None. + +========================================================================== */ +OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) +{ + + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + int fds[2]; + int r; + + OMX_VIDEO_CODINGTYPE codec_type; + + DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_init()"); + // Copy the role information which provides the decoder m_nkind + strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE); + + if(!strncmp((char *)m_nkind,"OMX.qcom.video.encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingMPEG4; + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingH263; + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingAVC; + } +#ifdef _MSM8974_ + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.vp8", \ + OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char *)m_cRole, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); + codec_type = OMX_VIDEO_CodingVPX; + } +#endif + else + { + DEBUG_PRINT_ERROR("\nERROR: Unknown Component\n"); + eRet = OMX_ErrorInvalidComponentName; + } + + + if(eRet != OMX_ErrorNone) + { + return eRet; + } +#ifdef ENABLE_GET_SYNTAX_HDR + get_syntaxhdr_enable = true; + DEBUG_PRINT_HIGH("Get syntax header enabled"); +#endif + + handle = new venc_dev(this); + + if(handle == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: handle is NULL"); + return OMX_ErrorInsufficientResources; + } + + if(handle->venc_open(codec_type) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_open failed"); + return OMX_ErrorInsufficientResources; + } + + //Intialise the OMX layer variables + memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE)); + + OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE); + m_sPortParam.nPorts = 0x2; + m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN; + + OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE); + m_sPortParam_audio.nPorts = 0; + m_sPortParam_audio.nStartPortNumber = 0; + + OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE); + m_sPortParam_img.nPorts = 0; + m_sPortParam_img.nStartPortNumber = 0; + + OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE); + m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames; + m_sParamBitrate.nTargetBitrate = 64000; + + OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE); + m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sConfigBitrate.nEncodeBitrate = 64000; + + OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE); + m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sConfigFramerate.xEncodeFramerate = 30 << 16; + + OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE); + m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE; + + OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE); + m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN; + m_sConfigFrameRotation.nRotation = 0; + + OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE); + m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sSessionQuantization.nQpI = 9; + m_sSessionQuantization.nQpP = 6; + m_sSessionQuantization.nQpB = 2; + + OMX_INIT_STRUCT(&m_sSessionQPRange, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE); + m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sSessionQPRange.minQP = 2; + if(codec_type == OMX_VIDEO_CodingAVC) + m_sSessionQPRange.maxQP = 51; + else + m_sSessionQPRange.maxQP = 31; + + OMX_INIT_STRUCT(&m_sAVCSliceFMO, OMX_VIDEO_PARAM_AVCSLICEFMO); + m_sAVCSliceFMO.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sAVCSliceFMO.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; + m_sAVCSliceFMO.nNumSliceGroups = 0; + m_sAVCSliceFMO.nSliceGroupMapType = 0; + OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE); + m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + + OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE); + m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1; + + OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE); + m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE; + m_sErrorCorrection.bEnableHEC = OMX_FALSE; + m_sErrorCorrection.bEnableResync = OMX_FALSE; + m_sErrorCorrection.bEnableRVLC = OMX_FALSE; + m_sErrorCorrection.nResynchMarkerSpacing = 0; + + OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE); + m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax; + + if(codec_type == OMX_VIDEO_CodingMPEG4) + { + m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple; + m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0; + } + else if(codec_type == OMX_VIDEO_CodingH263) + { + m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline; + m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10; + } + else if(codec_type == OMX_VIDEO_CodingAVC) + { + m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_AVCProfileBaseline; + m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_AVCLevel1; + } + + // Initialize the video parameters for input port + OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE); + m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN; + m_sInPortDef.bEnabled = OMX_TRUE; + m_sInPortDef.bPopulated = OMX_FALSE; + m_sInPortDef.eDomain = OMX_PortDomainVideo; + m_sInPortDef.eDir = OMX_DirInput; + m_sInPortDef.format.video.cMIMEType = "YUV420"; + m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; + m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; + m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH; + m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT; + m_sInPortDef.format.video.nBitrate = 64000; + m_sInPortDef.format.video.xFramerate = 15 << 16; + m_sInPortDef.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + m_sInPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + + if(dev_get_buf_req(&m_sInPortDef.nBufferCountMin, + &m_sInPortDef.nBufferCountActual, + &m_sInPortDef.nBufferSize, + m_sInPortDef.nPortIndex) != true) + { + eRet = OMX_ErrorUndefined; + + } + + // Initialize the video parameters for output port + OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE); + m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sOutPortDef.bEnabled = OMX_TRUE; + m_sOutPortDef.bPopulated = OMX_FALSE; + m_sOutPortDef.eDomain = OMX_PortDomainVideo; + m_sOutPortDef.eDir = OMX_DirOutput; + m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; + m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; + m_sOutPortDef.format.video.nBitrate = 64000; + m_sOutPortDef.format.video.xFramerate = 15 << 16; + m_sOutPortDef.format.video.eColorFormat = OMX_COLOR_FormatUnused; + if(codec_type == OMX_VIDEO_CodingMPEG4) + { + m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + } + else if(codec_type == OMX_VIDEO_CodingH263) + { + m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; + } + else + { + m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; + } + if(dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex) != true) + { + eRet = OMX_ErrorUndefined; + } + + // Initialize the video color format for input port + OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); + m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN; + m_sInPortFormat.nIndex = 0; + m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused; + + + // Initialize the compression format for output port + OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); + m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sOutPortFormat.nIndex = 0; + m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused; + if(codec_type == OMX_VIDEO_CodingMPEG4) + { + m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingMPEG4; + } + else if(codec_type == OMX_VIDEO_CodingH263) + { + m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingH263; + } + else + { + m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC; + } + + // mandatory Indices for kronos test suite + OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE); + + OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); + m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN; + + OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); + m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + + + // mp4 specific init + OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE); + m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple; + m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0; + m_sParamMPEG4.nSliceHeaderSpacing = 0; + m_sParamMPEG4.bSVH = OMX_FALSE; + m_sParamMPEG4.bGov = OMX_FALSE; + m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps + m_sParamMPEG4.bACPred = OMX_TRUE; + m_sParamMPEG4.nTimeIncRes = 30; // delta = 2 @ 15 fps + m_sParamMPEG4.nAllowedPictureTypes = 2; // pframe and iframe + m_sParamMPEG4.nHeaderExtension = 1; // number of video packet headers per vop + m_sParamMPEG4.bReversibleVLC = OMX_FALSE; + + // h263 specific init + OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE); + m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps + m_sParamH263.nBFrames = 0; + m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline; + m_sParamH263.eLevel = OMX_VIDEO_H263Level10; + m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE; + m_sParamH263.nAllowedPictureTypes = 2; + m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE; + m_sParamH263.nPictureHeaderRepetition = 0; + m_sParamH263.nGOBHeaderInterval = 1; + + // h264 specific init + OMX_INIT_STRUCT(&m_sParamAVC, OMX_VIDEO_PARAM_AVCTYPE); + m_sParamAVC.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamAVC.nSliceHeaderSpacing = 0; + m_sParamAVC.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps + m_sParamAVC.nBFrames = 0; + m_sParamAVC.bUseHadamard = OMX_FALSE; + m_sParamAVC.nRefFrames = 1; + m_sParamAVC.nRefIdx10ActiveMinus1 = 1; + m_sParamAVC.nRefIdx11ActiveMinus1 = 0; + m_sParamAVC.bEnableUEP = OMX_FALSE; + m_sParamAVC.bEnableFMO = OMX_FALSE; + m_sParamAVC.bEnableASO = OMX_FALSE; + m_sParamAVC.bEnableRS = OMX_FALSE; + m_sParamAVC.eProfile = OMX_VIDEO_AVCProfileBaseline; + m_sParamAVC.eLevel = OMX_VIDEO_AVCLevel1; + m_sParamAVC.nAllowedPictureTypes = 2; + m_sParamAVC.bFrameMBsOnly = OMX_FALSE; + m_sParamAVC.bMBAFF = OMX_FALSE; + m_sParamAVC.bEntropyCodingCABAC = OMX_FALSE; + m_sParamAVC.bWeightedPPrediction = OMX_FALSE; + m_sParamAVC.nWeightedBipredicitonMode = 0; + m_sParamAVC.bconstIpred = OMX_FALSE; + m_sParamAVC.bDirect8x8Inference = OMX_FALSE; + m_sParamAVC.bDirectSpatialTemporal = OMX_FALSE; + m_sParamAVC.nCabacInitIdc = 0; + m_sParamAVC.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; + + OMX_INIT_STRUCT(&m_sParamLTRMode, QOMX_VIDEO_PARAM_LTRMODE_TYPE); + m_sParamLTRMode.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + m_sParamLTRMode.eLTRMode = QOMX_VIDEO_LTRMode_Disable; + + m_state = OMX_StateLoaded; + m_sExtraData = 0; + + if(eRet == OMX_ErrorNone) + { + if(pipe(fds)) + { + DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); + eRet = OMX_ErrorInsufficientResources; + } + else + { + if(fds[0] == 0 || fds[1] == 0) + { + if(pipe(fds)) + { + DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); + eRet = OMX_ErrorInsufficientResources; + } + } + if(eRet == OMX_ErrorNone) + { + m_pipe_in = fds[0]; + m_pipe_out = fds[1]; + } + } + msg_thread_created = true; + r = pthread_create(&msg_thread_id,0, message_thread, this); + if(r < 0) + { + eRet = OMX_ErrorInsufficientResources; + msg_thread_created = false; + } + else + { + async_thread_created = true; + r = pthread_create(&async_thread_id,0, venc_dev::async_venc_message_thread, this); + if(r < 0) + { + eRet = OMX_ErrorInsufficientResources; + async_thread_created = false; + } else + dev_set_message_thread_id(async_thread_id); + } + } + + DEBUG_PRINT_HIGH("\n Component_init return value = 0x%x", eRet); + return eRet; +} + + +/* ====================================================================== +FUNCTION + omx_venc::Setparameter + +DESCRIPTION + OMX Set Parameter method implementation. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. + +========================================================================== */ +OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE paramIndex, + OMX_IN OMX_PTR paramData) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State\n"); + return OMX_ErrorInvalidState; + } + if(paramData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); + return OMX_ErrorBadParameter; + } + + /*set_parameter can be called in loaded state + or disabled port */ + if(m_state == OMX_StateLoaded + || m_sInPortDef.bEnabled == OMX_FALSE + || m_sOutPortDef.bEnabled == OMX_FALSE) + { + DEBUG_PRINT_LOW("Set Parameter called in valid state"); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + + switch(paramIndex) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", + (int)portDefn->format.video.nFrameHeight, + (int)portDefn->format.video.nFrameWidth); + + if(PORT_INDEX_IN == portDefn->nPortIndex) + { + if (!dev_is_video_session_supported(portDefn->format.video.nFrameWidth, + portDefn->format.video.nFrameHeight)) { + DEBUG_PRINT_ERROR("video session not supported\n"); + omx_report_unsupported_setting(); + return OMX_ErrorUnsupportedSetting; + } + DEBUG_PRINT_LOW("\n i/p actual cnt requested = %d\n", portDefn->nBufferCountActual); + DEBUG_PRINT_LOW("\n i/p min cnt requested = %d\n", portDefn->nBufferCountMin); + DEBUG_PRINT_LOW("\n i/p buffersize requested = %d\n", portDefn->nBufferSize); + if(portDefn->nBufferCountMin > portDefn->nBufferCountActual) + { + DEBUG_PRINT_ERROR("\nERROR: (In_PORT) Min buffers (%d) > actual count (%d)\n", + portDefn->nBufferCountMin, portDefn->nBufferCountActual); + return OMX_ErrorUnsupportedSetting; + } + if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); + return OMX_ErrorUnsupportedSetting; + } + + DEBUG_PRINT_LOW("\n i/p previous actual cnt = %d\n", m_sInPortDef.nBufferCountActual); + DEBUG_PRINT_LOW("\n i/p previous min cnt = %d\n", m_sInPortDef.nBufferCountMin); + memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); + +#ifdef _ANDROID_ICS_ + if (portDefn->format.video.eColorFormat == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { + m_sInPortDef.format.video.eColorFormat = + OMX_COLOR_FormatYUV420SemiPlanar; + if(!mUseProxyColorFormat){ + if (!c2d_conv.init()) { + DEBUG_PRINT_ERROR("\n C2D init failed"); + return OMX_ErrorUnsupportedSetting; + } + DEBUG_PRINT_ERROR("\nC2D init is successful"); + } + mUseProxyColorFormat = true; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ; + } else + mUseProxyColorFormat = false; +#endif + /*Query Input Buffer Requirements*/ + dev_get_buf_req (&m_sInPortDef.nBufferCountMin, + &m_sInPortDef.nBufferCountActual, + &m_sInPortDef.nBufferSize, + m_sInPortDef.nPortIndex); + + /*Query ouput Buffer Requirements*/ + dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual; + } + else if(PORT_INDEX_OUT == portDefn->nPortIndex) + { + DEBUG_PRINT_LOW("\n o/p actual cnt requested = %d\n", portDefn->nBufferCountActual); + DEBUG_PRINT_LOW("\n o/p min cnt requested = %d\n", portDefn->nBufferCountMin); + DEBUG_PRINT_LOW("\n o/p buffersize requested = %d\n", portDefn->nBufferSize); + if(portDefn->nBufferCountMin > portDefn->nBufferCountActual) + { + DEBUG_PRINT_ERROR("\nERROR: (Out_PORT) Min buffers (%d) > actual count (%d)\n", + portDefn->nBufferCountMin, portDefn->nBufferCountActual); + return OMX_ErrorUnsupportedSetting; + } + if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_set_param output failed"); + return OMX_ErrorUnsupportedSetting; + } +#ifdef _MSM8974_ + /*Query ouput Buffer Requirements*/ + dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); +#endif + memcpy(&m_sOutPortDef,portDefn,sizeof(struct OMX_PARAM_PORTDEFINITIONTYPE)); + update_profile_level(); //framerate , bitrate + + DEBUG_PRINT_LOW("\n o/p previous actual cnt = %d\n", m_sOutPortDef.nBufferCountActual); + DEBUG_PRINT_LOW("\n o/p previous min cnt = %d\n", m_sOutPortDef.nBufferCountMin); + m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d", + (int)portDefn->nPortIndex); + eRet = OMX_ErrorBadPortIndex; + } + m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate; + m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate; + m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate; + } + break; + + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", + portFmt->eColorFormat); + //set the driver with the corresponding values + if(PORT_INDEX_IN == portFmt->nPortIndex) + { + if(handle->venc_set_param(paramData,OMX_IndexParamVideoPortFormat) != true) + { + return OMX_ErrorUnsupportedSetting; + } + + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", + portFmt->eColorFormat); + update_profile_level(); //framerate + +#ifdef _ANDROID_ICS_ + if (portFmt->eColorFormat == + (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { + m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; + if(!mUseProxyColorFormat){ + if (!c2d_conv.init()) { + DEBUG_PRINT_ERROR("\n C2D init failed"); + return OMX_ErrorUnsupportedSetting; + } + DEBUG_PRINT_ERROR("\nC2D init is successful"); + } + mUseProxyColorFormat = true; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ; + } + else +#endif + { + m_sInPortFormat.eColorFormat = portFmt->eColorFormat; + m_input_msg_id = OMX_COMPONENT_GENERATE_ETB; + mUseProxyColorFormat = false; + } + m_sInPortFormat.xFramerate = portFmt->xFramerate; + } + //TODO if no use case for O/P port,delet m_sOutPortFormat + } + break; + case OMX_IndexParamVideoInit: + { //TODO, do we need this index set param + OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData); + DEBUG_PRINT_LOW("\n Set OMX_IndexParamVideoInit called"); + break; + } + + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate"); + if(handle->venc_set_param(paramData,OMX_IndexParamVideoBitrate) != true) + { + return OMX_ErrorUnsupportedSetting; + } + m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate; + m_sParamBitrate.eControlRate = pParam->eControlRate; + update_profile_level(); //bitrate + m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate; + m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate; + m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate; + DEBUG_PRINT_LOW("\nbitrate = %u", m_sOutPortDef.format.video.nBitrate); + break; + } + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; + OMX_VIDEO_PARAM_MPEG4TYPE mp4_param; + memcpy(&mp4_param, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4"); + if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { +#ifdef MAX_RES_1080P + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + mp4_param.nBFrames = 1; + } +#else + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + mp4_param.nBFrames = 0; + } +#endif + } + else + { + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + mp4_param.nBFrames = 0; + } + } + if(handle->venc_set_param(&mp4_param,OMX_IndexParamVideoMpeg4) != true) + { + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamMPEG4,pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); + m_sIntraperiod.nPFrames = m_sParamMPEG4.nPFrames; + m_sIntraperiod.nBFrames = m_sParamMPEG4.nBFrames; + break; + } + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263"); + if(handle->venc_set_param(paramData,OMX_IndexParamVideoH263) != true) + { + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE)); + m_sIntraperiod.nPFrames = m_sParamH263.nPFrames; + m_sIntraperiod.nBFrames = m_sParamH263.nBFrames; + break; + } + case OMX_IndexParamVideoAvc: + { + OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; + OMX_VIDEO_PARAM_AVCTYPE avc_param; + memcpy(&avc_param, pParam, sizeof( struct OMX_VIDEO_PARAM_AVCTYPE)); + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc"); + + if((pParam->eProfile == OMX_VIDEO_AVCProfileHigh)|| + (pParam->eProfile == OMX_VIDEO_AVCProfileMain)) + { +#ifdef MAX_RES_1080P + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + avc_param.nBFrames = 1; + } + if(pParam->nRefFrames != 2) + { + DEBUG_PRINT_ERROR("Warning: 2 RefFrames are needed, changing RefFrames from %lu to 2", pParam->nRefFrames); + avc_param.nRefFrames = 2; + } +#else + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + avc_param.nBFrames = 0; + } + if(pParam->nRefFrames != 1) + { + DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %lu to 1)", pParam->nRefFrames); + avc_param.nRefFrames = 1; + } +#endif + } + else + { + if(pParam->nRefFrames != 1) + { + DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %lu to 1)", pParam->nRefFrames); + avc_param.nRefFrames = 1; + } + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + avc_param.nBFrames = 0; + } + } + if(handle->venc_set_param(&avc_param,OMX_IndexParamVideoAvc) != true) + { + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamAVC,pParam, sizeof(struct OMX_VIDEO_PARAM_AVCTYPE)); + m_sIntraperiod.nPFrames = m_sParamAVC.nPFrames; + m_sIntraperiod.nBFrames = m_sParamAVC.nBFrames; + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent"); + if(handle->venc_set_param(pParam,OMX_IndexParamVideoProfileLevelCurrent) != true) + { + DEBUG_PRINT_ERROR("set_parameter: OMX_IndexParamVideoProfileLevelCurrent failed for Profile: %lu " + "Level :%lu", pParam->eProfile, pParam->eLevel); + return OMX_ErrorUnsupportedSetting; + } + m_sParamProfileLevel.eProfile = pParam->eProfile; + m_sParamProfileLevel.eLevel = pParam->eLevel; + + if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile; + m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel; + DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, + m_sParamMPEG4.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile; + m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel; + DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, + m_sParamH263.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)m_sParamProfileLevel.eProfile; + m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)m_sParamProfileLevel.eLevel; + DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, + m_sParamAVC.eLevel); + } + break; + } + case OMX_IndexParamStandardComponentRole: + { + OMX_PARAM_COMPONENTROLETYPE *comp_role; + comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", + comp_role->cRole); + + if((m_state == OMX_StateLoaded)&& + !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) + { + DEBUG_PRINT_LOW("Set Parameter called in valid state"); + } + else + { + DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + + if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((char*)comp_role->cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); + eRet = OMX_ErrorUnsupportedSetting; + } + } + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } +#ifdef _MSM8974_ + else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + if(!strncmp((const char*)comp_role->cRole,"video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) + { + strlcpy((char*)m_cRole,"video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); + } + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); + eRet =OMX_ErrorUnsupportedSetting; + } + } +#endif + else + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s\n", m_nkind); + eRet = OMX_ErrorInvalidComponentName; + } + break; + } + + case OMX_IndexParamPriorityMgmt: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt"); + if(m_state != OMX_StateLoaded) + { + DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); + return OMX_ErrorIncorrectStateOperation; + } + OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", + priorityMgmtype->nGroupID); + + DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", + priorityMgmtype->nGroupPriority); + + m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID; + m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority; + + break; + } + + case OMX_IndexParamCompBufferSupplier: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier"); + OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", + bufferSupplierType->eBufferSupplier); + if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) + m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; + + else + + eRet = OMX_ErrorBadPortIndex; + + break; + + } + case OMX_IndexParamVideoQuantization: + { + DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization\n"); + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; + if(session_qp->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_param(paramData, OMX_IndexParamVideoQuantization) != true) + { + return OMX_ErrorUnsupportedSetting; + } + m_sSessionQuantization.nQpI = session_qp->nQpI; + m_sSessionQuantization.nQpP = session_qp->nQpP; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for Session QP setting\n"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + + case OMX_QcomIndexParamVideoQPRange: + { + DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoQPRange\n"); + OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; + if(qp_range->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPRange) != true) + { + return OMX_ErrorUnsupportedSetting; + } + m_sSessionQPRange.minQP= qp_range->minQP; + m_sSessionQPRange.maxQP= qp_range->maxQP; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for QP range setting\n"); + eRet = OMX_ErrorBadPortIndex; + } + break; + } + + case OMX_QcomIndexPortDefn: + { + OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam = + (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData; + DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn"); + if(pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) + { + if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && + pParam->nMemRegion < OMX_QCOM_MemRegionMax) + { + m_use_input_pmem = OMX_TRUE; + } + else + { + m_use_input_pmem = OMX_FALSE; + } + } + else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && + pParam->nMemRegion < OMX_QCOM_MemRegionMax) + { + m_use_output_pmem = OMX_TRUE; + } + else + { + m_use_output_pmem = OMX_FALSE; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn"); + return OMX_ErrorBadPortIndex; + } + break; + } + + case OMX_IndexParamVideoErrorCorrection: + { + DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam = + (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; + if(!handle->venc_set_param(paramData, OMX_IndexParamVideoErrorCorrection)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Error Resilience failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection)); + break; + } + case OMX_IndexParamVideoIntraRefresh: + { + DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh\n"); + OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam = + (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; + if(!handle->venc_set_param(paramData,OMX_IndexParamVideoIntraRefresh)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra refresh failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh)); + break; + } +#ifdef _ANDROID_ICS_ + case OMX_QcomIndexParamVideoEncodeMetaBufferMode: + { + StoreMetaDataInBuffersParams *pParam = + (StoreMetaDataInBuffersParams*)paramData; + DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoEncodeMetaBufferMode: " + "port_index = %lu, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData); + if(pParam->nPortIndex == PORT_INDEX_IN) + { + if(pParam->bStoreMetaData != meta_mode_enable) + { + if(!handle->venc_set_meta_mode(pParam->bStoreMetaData)) + { + DEBUG_PRINT_ERROR("\nERROR: set Metabuffer mode %d fail", + pParam->bStoreMetaData); + return OMX_ErrorUnsupportedSetting; + } + meta_mode_enable = pParam->bStoreMetaData; + if(meta_mode_enable) { + m_sInPortDef.nBufferCountActual = 4; + if(handle->venc_set_param(&m_sInPortDef,OMX_IndexParamPortDefinition) != true) + { + DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); + return OMX_ErrorUnsupportedSetting; + } + } else { + /*TODO: reset encoder driver Meta mode*/ + dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + } + } + } + else + { + DEBUG_PRINT_ERROR("set_parameter: metamode is " + "valid for input port only"); + eRet = OMX_ErrorUnsupportedIndex; + } + } + break; +#endif +#if !defined(MAX_RES_720P) || defined(_MSM8974_) + case OMX_QcomIndexParamIndexExtraDataType: + { + DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType"); + QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; + if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) + { + if (pParam->nPortIndex == PORT_INDEX_OUT) + { + if (pParam->bEnabled == OMX_TRUE) + m_sExtraData |= VEN_EXTRADATA_SLICEINFO; + else + m_sExtraData &= ~VEN_EXTRADATA_SLICEINFO; + DEBUG_PRINT_HIGH("SliceInfo extradata %s", + ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled")); + if(handle->venc_set_param(&m_sExtraData, + (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting " + "OMX_ExtraDataVideoEncoderSliceInfo failed"); + return OMX_ErrorUnsupportedSetting; + } + else + { + m_sOutPortDef.nPortIndex = PORT_INDEX_OUT; + dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%lu, " + "count min=%lu, buffer size=%lu", + m_sOutPortDef.nBufferCountActual, + m_sOutPortDef.nBufferCountMin, + m_sOutPortDef.nBufferSize); + } + } + } +#ifndef _MSM8974_ + else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) + { + if (pParam->nPortIndex == PORT_INDEX_OUT) + { + if (pParam->bEnabled == OMX_TRUE) + m_sExtraData |= VEN_EXTRADATA_LTRINFO; + else + m_sExtraData &= ~VEN_EXTRADATA_LTRINFO; + DEBUG_PRINT_HIGH("LTRInfo extradata %s", + ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled")); + if(handle->venc_set_param(&m_sExtraData, + (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting " + "OMX_ExtraDataVideoLTRInfo failed"); + return OMX_ErrorUnsupportedSetting; + } + else + { + m_sOutPortDef.nPortIndex = PORT_INDEX_OUT; + dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, + &m_sOutPortDef.nBufferCountActual, + &m_sOutPortDef.nBufferSize, + m_sOutPortDef.nPortIndex); + DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%d, " + "count min=%d, buffer size=%d", + m_sOutPortDef.nBufferCountActual, + m_sOutPortDef.nBufferCountMin, + m_sOutPortDef.nBufferSize); + } + } + else + { + DEBUG_PRINT_ERROR("set_parameter: LTR information is " + "valid for output port only"); + eRet = OMX_ErrorUnsupportedIndex; + } + } +#endif + else + { + DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)", + pParam->nIndex); + eRet = OMX_ErrorUnsupportedIndex; + } + break; + } + case QOMX_IndexParamVideoLTRMode: + { + QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam = + (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData; + if(!handle->venc_set_param(paramData, (OMX_INDEXTYPE)QOMX_IndexParamVideoLTRMode)) + { + DEBUG_PRINT_ERROR("\nERROR: Setting LTR mode failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamLTRMode, pParam, sizeof(m_sParamLTRMode)); + break; + } + case QOMX_IndexParamVideoLTRCount: + { + QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam = + (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData; + if(!handle->venc_set_param(paramData, (OMX_INDEXTYPE)QOMX_IndexParamVideoLTRCount)) + { + DEBUG_PRINT_ERROR("\nERROR: Setting LTR count failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sParamLTRCount, pParam, sizeof(m_sParamLTRCount)); + break; + } +#endif + case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + handle->m_max_allowed_bitrate_check = + ((pParam->bEnable == OMX_TRUE) ? true : false); + DEBUG_PRINT_HIGH("set_parameter: max allowed bitrate check %s", + ((pParam->bEnable == OMX_TRUE) ? "enabled" : "disabled")); + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexParamVideoMaxAllowedBitrateCheck " + " called on wrong port(%lu)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } +#ifdef MAX_RES_1080P + case OMX_QcomIndexEnableSliceDeliveryMode: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(!handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) + { + DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableSliceDeliveryMode " + "called on wrong port(%lu)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } +#endif + case OMX_QcomIndexEnableH263PlusPType: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType"); + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(!handle->venc_set_param(paramData, + (OMX_INDEXTYPE)OMX_QcomIndexEnableH263PlusPType)) + { + DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableH263PlusPType " + "called on wrong port(%lu)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexParamVideoSliceFMO: + default: + { + DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d\n", paramIndex); + eRet = OMX_ErrorUnsupportedIndex; + break; + } + } + return eRet; +} + +bool omx_venc::update_profile_level() +{ + OMX_U32 eProfile, eLevel; + + if(!handle->venc_get_profile_level(&eProfile,&eLevel)) + { + DEBUG_PRINT_ERROR("\nFailed to update the profile_level\n"); + return false; + } + + m_sParamProfileLevel.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; + m_sParamProfileLevel.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; + + if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; + m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; + DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, + m_sParamMPEG4.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile; + m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel; + DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, + m_sParamH263.eLevel); + } + else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ + OMX_MAX_STRINGNAME_SIZE)) + { + m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)eProfile; + m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)eLevel; + DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, + m_sParamAVC.eLevel); + } + return true; +} +/* ====================================================================== +FUNCTION + omx_video::SetConfig + +DESCRIPTION + OMX Set Config method implementation + +PARAMETERS + . + +RETURN VALUE + OMX Error None if successful. +========================================================================== */ +OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp, + OMX_IN OMX_INDEXTYPE configIndex, + OMX_IN OMX_PTR configData) +{ + if(configData == NULL) + { + DEBUG_PRINT_ERROR("ERROR: param is null"); + return OMX_ErrorBadParameter; + } + + if(m_state == OMX_StateInvalid) + { + DEBUG_PRINT_ERROR("ERROR: config called in Invalid state"); + return OMX_ErrorIncorrectStateOperation; + } + + // params will be validated prior to venc_init + switch(configIndex) + { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE* pParam = + reinterpret_cast(configData); + DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%lu)", pParam->nEncodeBitrate); + + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_config(configData, OMX_IndexConfigVideoBitrate) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoBitrate failed"); + return OMX_ErrorUnsupportedSetting; + } + + m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate; + m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate; + m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE* pParam = + reinterpret_cast(configData); + DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%lx)", pParam->xEncodeFramerate); + + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_config(configData, OMX_IndexConfigVideoFramerate) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoFramerate failed"); + return OMX_ErrorUnsupportedSetting; + } + + m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate; + m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate; + m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + + break; + } + case QOMX_IndexConfigVideoIntraperiod: + { + QOMX_VIDEO_INTRAPERIODTYPE* pParam = + reinterpret_cast(configData); + + DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod"); + if(pParam->nPortIndex == PORT_INDEX_OUT) + { +#ifdef MAX_RES_720P + if(pParam->nBFrames > 0) + { + DEBUG_PRINT_ERROR("B frames not supported\n"); + return OMX_ErrorUnsupportedSetting; + } +#endif + DEBUG_PRINT_HIGH("Old: P/B frames = %lu/%lu, New: P/B frames = %lu/%lu", + m_sIntraperiod.nPFrames, m_sIntraperiod.nBFrames, + pParam->nPFrames, pParam->nBFrames); + if (m_sIntraperiod.nBFrames != pParam->nBFrames) + { + DEBUG_PRINT_HIGH("Dynamically changing B-frames not supported"); + return OMX_ErrorUnsupportedSetting; + } + if(handle->venc_set_config(configData, (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting QOMX_IndexConfigVideoIntraperiod failed"); + return OMX_ErrorUnsupportedSetting; + } + m_sIntraperiod.nPFrames = pParam->nPFrames; + m_sIntraperiod.nBFrames = pParam->nBFrames; + m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod; + + if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4) + { + m_sParamMPEG4.nPFrames = pParam->nPFrames; + if(m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple) + m_sParamMPEG4.nBFrames = pParam->nBFrames; + else + m_sParamMPEG4.nBFrames = 0; + } + else if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263) + { + m_sParamH263.nPFrames = pParam->nPFrames; + } + else + { + m_sParamAVC.nPFrames = pParam->nPFrames; + if(m_sParamAVC.eProfile != OMX_VIDEO_AVCProfileBaseline) + m_sParamAVC.nBFrames = pParam->nBFrames; + else + m_sParamAVC.nBFrames = 0; + } + } + else + { + DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %lu", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + + break; + } + + case OMX_IndexConfigVideoIntraVOPRefresh: + { + OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam = + reinterpret_cast(configData); + + DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh"); + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(handle->venc_set_config(configData, + OMX_IndexConfigVideoIntraVOPRefresh) != true) + { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoIntraVOPRefresh failed"); + return OMX_ErrorUnsupportedSetting; + } + + m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP; + } + else + { + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + + break; + } + case OMX_IndexConfigCommonRotate: + { + OMX_CONFIG_ROTATIONTYPE *pParam = + reinterpret_cast(configData); + OMX_S32 nRotation; + + if(pParam->nPortIndex != PORT_INDEX_IN){ + DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + if( pParam->nRotation == 0 || + pParam->nRotation == 90 || + pParam->nRotation == 180 || + pParam->nRotation == 270 ) { + DEBUG_PRINT_HIGH("\nset_config: Rotation Angle %lu", pParam->nRotation); + } else { + DEBUG_PRINT_ERROR("ERROR: un supported Rotation %lu", pParam->nRotation); + return OMX_ErrorUnsupportedSetting; + } + nRotation = pParam->nRotation - m_sConfigFrameRotation.nRotation; + if(nRotation < 0) + nRotation = -nRotation; + if(nRotation == 90 || nRotation == 270) { + DEBUG_PRINT_HIGH("\nset_config: updating device Dims"); + if(handle->venc_set_config(configData, + OMX_IndexConfigCommonRotate) != true) { + DEBUG_PRINT_ERROR("ERROR: Set OMX_IndexConfigCommonRotate failed"); + return OMX_ErrorUnsupportedSetting; + } else { + OMX_U32 nFrameWidth; + + DEBUG_PRINT_HIGH("\nset_config: updating port Dims"); + + nFrameWidth = m_sInPortDef.format.video.nFrameWidth; + m_sInPortDef.format.video.nFrameWidth = + m_sInPortDef.format.video.nFrameHeight; + m_sInPortDef.format.video.nFrameHeight = nFrameWidth; + + m_sOutPortDef.format.video.nFrameWidth = + m_sInPortDef.format.video.nFrameWidth; + m_sOutPortDef.format.video.nFrameHeight = + m_sInPortDef.format.video.nFrameHeight; + m_sConfigFrameRotation.nRotation = pParam->nRotation; + } + } else { + m_sConfigFrameRotation.nRotation = pParam->nRotation; + } + break; + } + case OMX_QcomIndexConfigVideoFramePackingArrangement: + { + DEBUG_PRINT_HIGH("set_config(): OMX_QcomIndexConfigVideoFramePackingArrangement"); + if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingAVC) + { + OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = + (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; + extra_data_handle.set_frame_pack_data(configFmt); + } + else + { + DEBUG_PRINT_ERROR("ERROR: FramePackingData not supported for non AVC compression"); + } + break; + } + case QOMX_IndexConfigVideoLTRPeriod: + { + QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData; + if(!handle->venc_set_config(configData, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRPeriod)) + { + DEBUG_PRINT_ERROR("\nERROR: Setting LTR period failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sConfigLTRPeriod, pParam, sizeof(m_sConfigLTRPeriod)); + break; + } + case QOMX_IndexConfigVideoLTRUse: + { + QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData; + if(!handle->venc_set_config(configData, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRUse)) + { + DEBUG_PRINT_ERROR("\nERROR: Setting LTR use failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sConfigLTRUse, pParam, sizeof(m_sConfigLTRUse)); + break; + } + case QOMX_IndexConfigVideoLTRMark: + { + QOMX_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRMARK_TYPE*)configData; + DEBUG_PRINT_ERROR("Setting ltr mark is not supported"); + return OMX_ErrorUnsupportedSetting; + break; + } + case OMX_IndexConfigVideoAVCIntraPeriod: + { + OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData; + DEBUG_PRINT_LOW("set_config: OMX_IndexConfigVideoAVCIntraPeriod"); + if(!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_IndexConfigVideoAVCIntraPeriod)) + { + DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoAVCIntraPeriod failed"); + return OMX_ErrorUnsupportedSetting; + } + memcpy(&m_sConfigAVCIDRPeriod, pParam, sizeof(m_sConfigAVCIDRPeriod)); + break; + } + default: + DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); + break; + } + + return OMX_ErrorNone; +} + +/* ====================================================================== +FUNCTION + omx_venc::ComponentDeInit + +DESCRIPTION + Destroys the component and release memory allocated to the heap. + +PARAMETERS + . + +RETURN VALUE + OMX Error None if everything successful. + +========================================================================== */ +OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp) +{ + OMX_U32 i = 0; + DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_deinit()"); + if(OMX_StateLoaded != m_state) + { + DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ + m_state); + } + if(m_out_mem_ptr) + { + DEBUG_PRINT_LOW("Freeing the Output Memory\n"); + for(i=0; i< m_sOutPortDef.nBufferCountActual; i++ ) + { + free_output_buffer (&m_out_mem_ptr[i]); + } + free(m_out_mem_ptr); + m_out_mem_ptr = NULL; + } + + /*Check if the input buffers have to be cleaned up*/ + if(m_inp_mem_ptr +#ifdef _ANDROID_ICS_ + && !meta_mode_enable +#endif + ) + { + DEBUG_PRINT_LOW("Freeing the Input Memory\n"); + for(i=0; ivenc_close(); + DEBUG_PRINT_HIGH("Deleting HANDLE[%p]\n", handle); + delete (handle); + DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit\n"); + return OMX_ErrorNone; +} + + +OMX_U32 omx_venc::dev_stop( void) +{ + return handle->venc_stop(); +} + + +OMX_U32 omx_venc::dev_pause(void) +{ + return handle->venc_pause(); +} + +OMX_U32 omx_venc::dev_start(void) +{ + return handle->venc_start(); +} + +OMX_U32 omx_venc::dev_flush(unsigned port) +{ + return handle->venc_flush(port); +} +OMX_U32 omx_venc::dev_resume(void) +{ + return handle->venc_resume(); +} + +OMX_U32 omx_venc::dev_start_done(void) +{ + return handle->venc_start_done(); +} + +OMX_U32 omx_venc::dev_set_message_thread_id(pthread_t tid) +{ + return handle->venc_set_message_thread_id(tid); +} + +bool omx_venc::dev_use_buf(void *buf_addr,unsigned port,unsigned index) +{ + return handle->venc_use_buf(buf_addr,port,index); +} + +bool omx_venc::dev_free_buf(void *buf_addr,unsigned port) +{ + return handle->venc_free_buf(buf_addr,port); +} + +bool omx_venc::dev_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) +{ + return handle->venc_empty_buf(buffer, pmem_data_buf,index,fd); +} + +bool omx_venc::dev_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) +{ + return handle->venc_fill_buf(buffer, pmem_data_buf,index,fd); +} + +bool omx_venc::dev_get_seq_hdr(void *buffer, unsigned size, unsigned *hdrlen) +{ + return handle->venc_get_seq_hdr(buffer, size, hdrlen); +} + +bool omx_venc::dev_get_capability_ltrcount(OMX_U32 *min, OMX_U32 *max, OMX_U32 *step_size) +{ +#ifdef _MSM8974_ + DEBUG_PRINT_ERROR("Get Capability LTR Count is not supported"); + return false; +#else + return handle->venc_get_capability_ltrcount(min, max, step_size); +#endif +} + +bool omx_venc::dev_loaded_start() +{ + return handle->venc_loaded_start(); +} + +bool omx_venc::dev_loaded_stop() +{ + return handle->venc_loaded_stop(); +} + +bool omx_venc::dev_loaded_start_done() +{ + return handle->venc_loaded_start_done(); +} + +bool omx_venc::dev_loaded_stop_done() +{ + return handle->venc_loaded_stop_done(); +} + +bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count, + OMX_U32 *actual_buff_count, + OMX_U32 *buff_size, + OMX_U32 port) +{ + return handle->venc_get_buf_req(min_buff_count, + actual_buff_count, + buff_size, + port); + +} + +bool omx_venc::dev_set_buf_req(OMX_U32 *min_buff_count, + OMX_U32 *actual_buff_count, + OMX_U32 *buff_size, + OMX_U32 port) +{ + return handle->venc_set_buf_req(min_buff_count, + actual_buff_count, + buff_size, + port); + +} + +bool omx_venc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height) +{ +#ifdef _MSM8974_ + return handle->venc_is_video_session_supported(width,height); +#else + DEBUG_PRINT_LOW("Check against video capability not supported"); + return true; +#endif +} + +#ifdef _MSM8974_ +int omx_venc::dev_handle_extradata(void *buffer, int index) +{ + return handle->handle_extradata(buffer, index); +} + +int omx_venc::dev_set_format(int color) +{ + return handle->venc_set_format(color); +} +#endif + +int omx_venc::async_message_process (void *context, void* message) +{ + omx_video* omx = NULL; + struct venc_msg *m_sVenc_msg = NULL; + OMX_BUFFERHEADERTYPE* omxhdr = NULL; + struct venc_buffer *temp_buff = NULL; + + if(context == NULL || message == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: omx_venc::async_message_process invalid i/p params"); + return -1; + } + m_sVenc_msg = (struct venc_msg *)message; + + omx = reinterpret_cast(context); + + if(m_sVenc_msg->statuscode != VEN_S_SUCCESS) + { + DEBUG_PRINT_ERROR("\nERROR: async_msg_process() - Error statuscode = %lu\n", + m_sVenc_msg->statuscode); + omx->omx_report_error(); + } + + DEBUG_PRINT_LOW("\n omx_venc::async_message_process- msgcode = %d\n", + m_sVenc_msg->msgcode); + switch(m_sVenc_msg->msgcode) + { + case VEN_MSG_START: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_START_DONE); + break; + case VEN_MSG_STOP: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_STOP_DONE); + break; + case VEN_MSG_RESUME: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_RESUME_DONE); + break; + case VEN_MSG_PAUSE: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_PAUSE_DONE); + break; + case VEN_MSG_FLUSH_INPUT_DONE: + + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); + break; + case VEN_MSG_FLUSH_OUPUT_DONE: + omx->post_event (NULL,m_sVenc_msg->statuscode,\ + OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); + break; + case VEN_MSG_INPUT_BUFFER_DONE: + omxhdr = (OMX_BUFFERHEADERTYPE* )\ + m_sVenc_msg->buf.clientdata; + + if(omxhdr == NULL || + (((OMX_U32)(omxhdr - omx->m_inp_mem_ptr) > omx->m_sInPortDef.nBufferCountActual) && + ((OMX_U32)(omxhdr - omx->meta_buffer_hdr) > omx->m_sInPortDef.nBufferCountActual))) + { + omxhdr = NULL; + m_sVenc_msg->statuscode = VEN_S_EFAIL; + } + +#ifdef _ANDROID_ICS_ + omx->omx_release_meta_buffer(omxhdr); +#endif + omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, + OMX_COMPONENT_GENERATE_EBD); + break; + case VEN_MSG_OUTPUT_BUFFER_DONE: + omxhdr = (OMX_BUFFERHEADERTYPE*)m_sVenc_msg->buf.clientdata; + + if( (omxhdr != NULL) && + ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual)) + { + if(m_sVenc_msg->buf.len <= omxhdr->nAllocLen) + { + omxhdr->nFilledLen = m_sVenc_msg->buf.len; + omxhdr->nOffset = m_sVenc_msg->buf.offset; + omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp; + DEBUG_PRINT_LOW("\n o/p TS = %u", (OMX_U32)m_sVenc_msg->buf.timestamp); + omxhdr->nFlags = m_sVenc_msg->buf.flags; + + /*Use buffer case*/ + if(omx->output_use_buffer && !omx->m_use_output_pmem) + { + DEBUG_PRINT_LOW("\n memcpy() for o/p Heap UseBuffer"); + memcpy(omxhdr->pBuffer, + (m_sVenc_msg->buf.ptrbuffer), + m_sVenc_msg->buf.len); + } + } + else + { + omxhdr->nFilledLen = 0; + } + + } + else + { + omxhdr = NULL; + m_sVenc_msg->statuscode = VEN_S_EFAIL; + } + omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, + OMX_COMPONENT_GENERATE_FBD); + break; + case VEN_MSG_NEED_OUTPUT_BUFFER: + //TBD what action needs to be done here?? + break; +#ifndef _MSM8974_ + case VEN_MSG_LTRUSE_FAILED: + DEBUG_PRINT_ERROR("LTRUSE Failed!"); + omx->post_event (NULL,m_sVenc_msg->statuscode, + OMX_COMPONENT_GENERATE_LTRUSE_FAILED); + break; +#endif + default: + break; + } + return 0; +} diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp new file mode 100644 index 00000000..7b56d33a --- /dev/null +++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp @@ -0,0 +1,3235 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include "video_encoder_device.h" +#include "omx_video_encoder.h" +#include +#ifdef USE_ION +#include +#endif + +#define MPEG4_SP_START 0 +#define MPEG4_ASP_START (MPEG4_SP_START + 8) +#define MPEG4_720P_LEVEL 6 +#define H263_BP_START 0 +#define H264_BP_START 0 +#define H264_HP_START (H264_BP_START + 13) +#define H264_MP_START (H264_BP_START + 26) + +/* MPEG4 profile and level table*/ +static const unsigned int mpeg4_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, + {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, + {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, + {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, + {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, + {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {0,0,0,0,0}, + + {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {0,0,0,0,0}, +}; + +/* H264 profile and level table*/ +static const unsigned int h264_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, + {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, + {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, + {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, + {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, + {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, + {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, + {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, + {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, + {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, + {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, + {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, + {0,0,0,0,0}, + + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, + {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, + {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, + {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, + {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, + {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, + {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, + {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, + {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, + {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, + {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, + {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, + {0,0,0,0,0}, + + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, + {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, + {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, + {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, + {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, + {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, + {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, + {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, + {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, + {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, + {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, + {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, + {0,0,0,0,0} + +}; + +/* H263 profile and level table*/ +static const unsigned int h263_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, + {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, + {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, + {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, + {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, + {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, + {0,0,0,0,0} +}; + +#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } +#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } + +#ifdef INPUT_BUFFER_LOG +FILE *inputBufferFile1; +char inputfilename [] = "/data/input.yuv"; +#endif +#ifdef OUTPUT_BUFFER_LOG +FILE *outputBufferFile1; +char outputfilename [] = "/data/output-bitstream.\0\0\0\0"; +#endif +//constructor +venc_dev::venc_dev(class omx_venc *venc_class) +{ + m_max_allowed_bitrate_check = false; + m_eLevel = 0; + m_eProfile = 0; + pthread_mutex_init(&loaded_start_stop_mlock, NULL); + pthread_cond_init (&loaded_start_stop_cond, NULL); + DEBUG_PRINT_LOW("venc_dev constructor"); +} + +venc_dev::~venc_dev() +{ + pthread_cond_destroy(&loaded_start_stop_cond); + pthread_mutex_destroy(&loaded_start_stop_mlock); + DEBUG_PRINT_LOW("venc_dev distructor"); +} + +void* async_venc_message_thread (void *input) +{ + struct venc_ioctl_msg ioctl_msg ={NULL,NULL}; + struct venc_timeout timeout; + struct venc_msg venc_msg; + int error_code = 0; + omx_venc *omx = reinterpret_cast(input); + + prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); + timeout.millisec = VEN_TIMEOUT_INFINITE; + while(1) + { + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&venc_msg; + + /*Wait for a message from the video decoder driver*/ + error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg); + if (error_code == -512) // ERESTARTSYS + { + DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!"); + } + else if (error_code <0) + { + DEBUG_PRINT_LOW("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed"); + break; + } + else if(omx->async_message_process(input,&venc_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); + break; + } + } + DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n"); + return NULL; +} + +bool venc_dev::venc_open(OMX_U32 codec) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + int r; + unsigned int alignment = 0,buffer_size = 0, temp =0; + + m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); + if(m_nDriver_fd == 0) + { + DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n"); + m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); + } + + if((int)m_nDriver_fd < 0) + { + DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n"); + return false; + } + + DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd); +#ifdef SINGLE_ENCODER_INSTANCE + OMX_U32 num_instances = 0; + ioctl_msg.in = NULL; + ioctl_msg.out = &num_instances; + if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < 0 ) + { + DEBUG_PRINT_ERROR("\nERROR: Request number of encoder instances failed"); + } + else if (num_instances > 1) + { + DEBUG_PRINT_ERROR("\nSecond encoder instance rejected!"); + venc_close(); + return false; + } +#endif + // set the basic configuration of the video encoder driver + m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; + m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; + m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; + m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; + m_sVenc_cfg.fps_num = 30; + m_sVenc_cfg.fps_den = 1; + m_sVenc_cfg.targetbitrate = 64000; +#ifdef MAX_RES_1080P + m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; +#else + m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12; +#endif +// initializing QP range parameters + qp_range.minqp = 2; + if(codec == OMX_VIDEO_CodingAVC) + qp_range.maxqp = 51; + else + qp_range.maxqp = 31; + + if(codec == OMX_VIDEO_CodingMPEG4) + { + m_sVenc_cfg.codectype = VEN_CODEC_MPEG4; + codec_profile.profile = VEN_PROFILE_MPEG4_SP; + profile_level.level = VEN_LEVEL_MPEG4_2; +#ifdef OUTPUT_BUFFER_LOG + strcat(outputfilename, "m4v"); +#endif + } + else if(codec == OMX_VIDEO_CodingH263) + { + m_sVenc_cfg.codectype = VEN_CODEC_H263; + codec_profile.profile = VEN_PROFILE_H263_BASELINE; + profile_level.level = VEN_LEVEL_H263_20; +#ifdef OUTPUT_BUFFER_LOG + strcat(outputfilename, "263"); +#endif + } + if(codec == OMX_VIDEO_CodingAVC) + { + m_sVenc_cfg.codectype = VEN_CODEC_H264; + codec_profile.profile = VEN_PROFILE_H264_BASELINE; + profile_level.level = VEN_LEVEL_H264_1p1; +#ifdef OUTPUT_BUFFER_LOG + strcat(outputfilename, "264"); +#endif + } + ioctl_msg.in = (void*)&m_sVenc_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 ) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed"); + return false; + } +#ifdef INPUT_BUFFER_LOG + inputBufferFile1 = fopen (inputfilename, "ab"); +#endif +#ifdef OUTPUT_BUFFER_LOG + outputBufferFile1 = fopen (outputfilename, "ab"); +#endif + // Get the I/P and O/P buffer requirements + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&m_sInput_buff_property; + if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed"); + return false; + } + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&m_sOutput_buff_property; + if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed"); + return false; + } + + m_profile_set = false; + m_level_set = false; + if(venc_set_profile_level(0, 0)) + { + DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success", + __func__); + } + recon_buffers_count = MAX_RECON_BUFFERS; + ltrmode.ltr_mode = 0; + ltrcount.ltr_count = 0; + ltrperiod.ltr_period = 0; + + return true; +} + +void venc_dev::venc_close() +{ + DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd); + if((int)m_nDriver_fd >= 0) + { + DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG"); + (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG, + NULL); + DEBUG_PRINT_LOW("\nCalling close()\n"); + close(m_nDriver_fd); + m_nDriver_fd = -1; + } +#ifdef INPUT_BUFFER_LOG + fclose (inputBufferFile1); +#endif +#ifdef OUTPUT_BUFFER_LOG + fclose (outputBufferFile1); +#endif +} + +bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count, + unsigned long *actual_buff_count, + unsigned long *buff_size, + unsigned long port) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + unsigned long temp_count = 0; + + if(port == 0) + { + if(*actual_buff_count > m_sInput_buff_property.mincount) + { + temp_count = m_sInput_buff_property.actualcount; + m_sInput_buff_property.actualcount = *actual_buff_count; + ioctl_msg.in = (void*)&m_sInput_buff_property; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed"); + m_sInput_buff_property.actualcount = temp_count; + return false; + } + DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count); + } + } + else + { + if(*actual_buff_count > m_sOutput_buff_property.mincount) + { + temp_count = m_sOutput_buff_property.actualcount; + m_sOutput_buff_property.actualcount = *actual_buff_count; + ioctl_msg.in = (void*)&m_sOutput_buff_property; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed"); + m_sOutput_buff_property.actualcount = temp_count; + return false; + } + DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count); + } + } + + return true; + +} + +bool venc_dev::venc_loaded_start() +{ + struct timespec ts; + int status = 0; + if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0) + { + DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed"); + return false; + } + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) + { + DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__); + return false; + } + ts.tv_sec += 1; + pthread_mutex_lock(&loaded_start_stop_mlock); + DEBUG_PRINT_LOW("%s: wait on start done", __func__); + status = pthread_cond_timedwait(&loaded_start_stop_cond, + &loaded_start_stop_mlock, &ts); + if (status != 0) + { + DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__, + status, strerror(status)); + pthread_mutex_unlock(&loaded_start_stop_mlock); + return false; + } + DEBUG_PRINT_LOW("%s: wait over on start done", __func__); + pthread_mutex_unlock(&loaded_start_stop_mlock); + DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__); + return true; +} + +bool venc_dev::venc_loaded_stop() +{ + struct timespec ts; + int status = 0; + if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0) + { + DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed"); + return false; + } + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) + { + DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__); + return false; + } + ts.tv_sec += 1; + pthread_mutex_lock(&loaded_start_stop_mlock); + DEBUG_PRINT_LOW("%s: wait on stop done", __func__); + status = pthread_cond_timedwait(&loaded_start_stop_cond, + &loaded_start_stop_mlock, &ts); + if (status != 0) + { + DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__, + status, strerror(status)); + pthread_mutex_unlock(&loaded_start_stop_mlock); + return false; + } + DEBUG_PRINT_LOW("%s: wait over on stop done", __func__); + pthread_mutex_unlock(&loaded_start_stop_mlock); + DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__); + return true; +} + +bool venc_dev::venc_loaded_start_done() +{ + pthread_mutex_lock(&loaded_start_stop_mlock); + DEBUG_PRINT_LOW("%s: signal start done", __func__); + pthread_cond_signal(&loaded_start_stop_cond); + pthread_mutex_unlock(&loaded_start_stop_mlock); + return true; +} + +bool venc_dev::venc_loaded_stop_done() +{ + pthread_mutex_lock(&loaded_start_stop_mlock); + DEBUG_PRINT_LOW("%s: signal stop done", __func__); + pthread_cond_signal(&loaded_start_stop_cond); + pthread_mutex_unlock(&loaded_start_stop_mlock); + return true; +} + +bool venc_dev::venc_get_seq_hdr(void *buffer, + unsigned buffer_size, unsigned *header_len) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + int i = 0; + DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr"); + venc_seqheader seq_in, seq_out; + seq_in.hdrlen = 0; + seq_in.bufsize = buffer_size; + seq_in.hdrbufptr = (unsigned char*)buffer; + if (seq_in.hdrbufptr == NULL) { + DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed"); + return false; + } + DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr, + seq_in.bufsize, seq_in.hdrlen); + + ioctl_msg.in = (void*)&seq_in; + ioctl_msg.out = (void*)&seq_out; + if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed"); + return false; + } + if (seq_out.hdrlen == 0) { + DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header"); + DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr, + seq_out.bufsize, seq_out.hdrlen); + return false; + } + *header_len = seq_out.hdrlen; + DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr, + seq_out.bufsize, seq_out.hdrlen); + + return true; +} + +bool venc_dev::venc_get_capability_ltrcount(unsigned long *min, + unsigned long *max, unsigned long *step_size) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + venc_range cap_ltr_count; + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&cap_ltr_count; + if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_CAPABILITY_LTRCOUNT, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("ERROR: Get LTR Capability failed"); + return false; + } + else + { + *min = cap_ltr_count.min; + *max = cap_ltr_count.max; + *step_size = cap_ltr_count.step_size; + DEBUG_PRINT_HIGH("LTR Capability: min=%x, max=%d, step_size=%d", + *min, *max, *step_size); + } + return true; +} + +bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count, + unsigned long *actual_buff_count, + unsigned long *buff_size, + unsigned long port) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + + if(port == 0) + { + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&m_sInput_buff_property; + if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed"); + return false; + } + *min_buff_count = m_sInput_buff_property.mincount; + *actual_buff_count = m_sInput_buff_property.actualcount; +#ifdef USE_ION + // For ION memory allocations of the allocated buffer size + // must be 4k aligned, hence aligning the input buffer + // size to 4k. + m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095) + & (~4095); +#endif + *buff_size = m_sInput_buff_property.datasize; + } + else + { + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&m_sOutput_buff_property; + if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed"); + return false; + } + *min_buff_count = m_sOutput_buff_property.mincount; + *actual_buff_count = m_sOutput_buff_property.actualcount; + *buff_size = m_sOutput_buff_property.datasize; + } + + return true; + +} + +bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n"); + switch(index) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_HIGH("venc_set_param: OMX_IndexParamPortDefinition"); + if(portDefn->nPortIndex == PORT_INDEX_IN) + { + + if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) + { + return false; + } + + if(!venc_set_color_format(portDefn->format.video.eColorFormat)) + { + return false; + } + + DEBUG_PRINT_LOW("Basic parameter has changed"); + m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; + m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; + + ioctl_msg.in = (void*)&m_sVenc_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed"); + return false; + } + DEBUG_PRINT_HIGH("WxH (%dx%d), codec (%d), fps(nr/dr) (%d/%d), bitrate (%d), " + "color_format (%d)", m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, + m_sVenc_cfg.codectype, m_sVenc_cfg.fps_num, m_sVenc_cfg.fps_den, + m_sVenc_cfg.targetbitrate, m_sVenc_cfg.inputformat); + + DEBUG_PRINT_LOW("Updating the buffer count/size for the new resolution"); + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&m_sInput_buff_property; + if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed"); + return false; + } + DEBUG_PRINT_HIGH("Got updated m_sInput_buff_property values: " + "datasize = %u, maxcount = %u, actualcnt = %u, " + "mincount = %u", m_sInput_buff_property.datasize, + m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount, + m_sInput_buff_property.mincount); + + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&m_sOutput_buff_property; + if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed"); + return false; + } + + DEBUG_PRINT_HIGH("Got updated m_sOutput_buff_property values: " + "datasize = %u, maxcount = %u, actualcnt = %u, " + "mincount = %u", m_sOutput_buff_property.datasize, + m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount, + m_sOutput_buff_property.mincount); + ioctl_msg.in = (void*)&m_sOutput_buff_property; + ioctl_msg.out = NULL; + + if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed"); + return false; + } + + if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) && + (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) { + m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; + ioctl_msg.in = (void*)&m_sInput_buff_property; + ioctl_msg.out = NULL; + if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed"); + return false; + } + } + if(m_sInput_buff_property.datasize != portDefn->nBufferSize) { + DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u]," + "Driver's updated i/p bufsize = %u", portDefn->nBufferSize, + m_sInput_buff_property.datasize); + } + m_level_set = false; + if(venc_set_profile_level(0, 0)) { + DEBUG_PRINT_LOW("%s(): Profile/Level setting success", __func__); + } + } + else if(portDefn->nPortIndex == PORT_INDEX_OUT) + { + if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) + { + return false; + } + + if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) + && + (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual) + && + (m_sOutput_buff_property.datasize == portDefn->nBufferSize) + ) + { + m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; + ioctl_msg.in = (void*)&m_sOutput_buff_property; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); + } + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; + portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n"); + + if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) + { + if(!venc_set_color_format(portFmt->eColorFormat)) + { + return false; + } + } + else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(!venc_set_encode_framerate(portFmt->xFramerate, 0)) + { + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); + } + break; + } + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE* pParam; + pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n"); + + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) + { + DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed"); + return false; + } + if(!venc_set_ratectrl_cfg(pParam->eControlRate)) + { + DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); + } + break; + } + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE* pParam; + OMX_U32 bFrames = 0; + + pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n"); + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(!venc_set_voptiming_cfg(pParam->nTimeIncRes)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed"); + return false; + } + m_profile_set = false; + m_level_set = false; + if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); + return false; + } +#ifdef MAX_RES_1080P + else { + if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + bFrames = 1; + } + } + else + { + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + bFrames = 0; + } + } + } +#endif + if(!venc_set_intra_period (pParam->nPFrames,bFrames)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); + } + break; + } + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n"); + OMX_U32 bFrames = 0; + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + m_profile_set = false; + m_level_set = false; + if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); + return false; + } + if (pParam->nBFrames) + DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263"); + + if(venc_set_intra_period (pParam->nPFrames, bFrames) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263"); + } + break; + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n"); + OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; + OMX_U32 bFrames = 0; + + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n", + pParam->eProfile,pParam->eLevel); + + m_profile_set = false; + m_level_set = false; + + if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d", + pParam->eProfile, pParam->eLevel); + return false; + } +#ifdef MAX_RES_1080P + else { + if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) + { + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + bFrames = 1; + } + } + else + { + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + bFrames = 0; + } + } + } +#endif + if(!venc_set_intra_period (pParam->nPFrames, bFrames)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed"); + return false; + } + if(!venc_set_inloop_filter (pParam->eLoopFilterMode)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed"); + return false; + } + if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) + { + DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); + } + //TBD, lot of other variables to be updated, yet to decide + break; + } + case OMX_IndexParamVideoIntraRefresh: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n"); + OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = + (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; + if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); + } + break; + } + case OMX_IndexParamVideoErrorCorrection: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n"); + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = + (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; + if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_error_resilience(error_resilience) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); + } + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n"); + OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = + (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; + if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + m_profile_set = false; + m_level_set = false; + if(!venc_set_profile_level (profile_level->eProfile, + profile_level->eLevel)) + { + DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); + } + break; + } + case OMX_IndexParamVideoQuantization: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n"); + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = + (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; + if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_session_qp (session_qp->nQpI, + session_qp->nQpP) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); + } + break; + } + + case OMX_QcomIndexParamVideoQPRange: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange\n"); + OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = + (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData; + if(qp_range->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_qp_range (qp_range->minQP, + qp_range->maxQP) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting QP Range failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange"); + } + break; + } + + case OMX_ExtraDataVideoEncoderSliceInfo: + { + DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); + OMX_U32 extra_data = *(OMX_U32 *)paramData; + if(venc_set_extradata(extra_data) == false) + { + DEBUG_PRINT_ERROR("ERROR: Setting " + "OMX_ExtraDataVideoEncoderSliceInfo failed"); + return false; + } + break; + } + case OMX_ExtraDataVideoLTRInfo: + { + DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoLTRInfo"); + OMX_U32 extra_data = *(OMX_U32 *)paramData; + if(venc_set_extradata(extra_data) == false) + { + DEBUG_PRINT_ERROR("ERROR: Setting " + "OMX_ExtraDataVideoLTRInfo failed"); + return false; + } + break; + } + case OMX_QcomIndexEnableSliceDeliveryMode: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(venc_set_slice_delivery_mode(pParam->bEnable) == false) + { + DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case OMX_QcomIndexEnableH263PlusPType: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType"); + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(venc_set_plusptype(pParam->bEnable) == false) + { + DEBUG_PRINT_ERROR("Setting PlusPType failed for H263"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("OMX_QcomIndexEnableH263PlusPType " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case QOMX_IndexParamVideoLTRMode: + { + QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam = + (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(!venc_set_ltrmode(pParam->eLTRMode)) + { + DEBUG_PRINT_ERROR("Setting ltr mode failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRMode " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case QOMX_IndexParamVideoLTRCount: + { + QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam = + (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(!venc_set_ltrcount(pParam->nCount)) + { + DEBUG_PRINT_ERROR("Setting ltr count failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRCount " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case OMX_IndexParamVideoSliceFMO: + default: + DEBUG_PRINT_ERROR("venc_set_param: Unsupported index 0x%x", index); + break; + } + + return true; +} + +bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + DEBUG_PRINT_LOW("\n Inside venc_set_config"); + + switch(index) + { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) + configData; + if(m_max_allowed_bitrate_check && + !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate)) + { + DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed"); + return false; + } + DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate"); + if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); + } + break; + } + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) + configData; + DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate"); + if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); + } + break; + } + case QOMX_IndexConfigVideoIntraperiod: + { + DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n"); + QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = + (QOMX_VIDEO_INTRAPERIODTYPE *)configData; + if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + } + break; + } + case OMX_IndexConfigVideoIntraVOPRefresh: + { + OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) + configData; + DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); + if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); + } + break; + } + case OMX_IndexConfigCommonRotate: + { + OMX_CONFIG_ROTATIONTYPE *config_rotation = + reinterpret_cast(configData); + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + OMX_U32 nFrameWidth; + + DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims"); + nFrameWidth = m_sVenc_cfg.input_width; + m_sVenc_cfg.input_width = m_sVenc_cfg.input_height; + m_sVenc_cfg.input_height = nFrameWidth; + ioctl_msg.in = (void*)&m_sVenc_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed"); + return false; + } + break; + } + case QOMX_IndexConfigVideoLTRPeriod: + { + QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam = + (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(!venc_set_ltrperiod(pParam->nFrames)) + { + DEBUG_PRINT_ERROR("Setting ltr period failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRPeriod " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case QOMX_IndexConfigVideoLTRUse: + { + QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam = + (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(!venc_set_ltruse(pParam->nID, pParam->nFrames)) + { + DEBUG_PRINT_ERROR("Setting ltr use failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRUse " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + default: + DEBUG_PRINT_ERROR("venc_set_config: Unsupported index = 0x%x", index); + break; + } + + return true; +} + +unsigned venc_dev::venc_stop( void) +{ +#ifdef MAX_RES_1080P + pmem_free(); +#endif + return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL); +} + +unsigned venc_dev::venc_pause(void) +{ + return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL); +} + +unsigned venc_dev::venc_resume(void) +{ + return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ; +} + +unsigned venc_dev::venc_start_done(void) +{ + return 0; +} + +unsigned venc_dev::venc_set_message_thread_id(pthread_t) +{ + return 0; +} + +unsigned venc_dev::venc_start(void) +{ + DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start", + __func__); + if (!venc_set_profile_level(0, 0)) + { + DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET", + __func__); + } + else + { + DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET", + __func__, codec_profile.profile, profile_level.level); + } + + if(m_max_allowed_bitrate_check && + !venc_max_allowed_bitrate_check(bitrate.target_bitrate)) + { + DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed"); + return -1; + } + + venc_config_print(); + +#ifdef MAX_RES_1080P + if((codec_profile.profile == VEN_PROFILE_MPEG4_SP) || + (codec_profile.profile == VEN_PROFILE_H264_BASELINE) || + (codec_profile.profile == VEN_PROFILE_H263_BASELINE)) + recon_buffers_count = MAX_RECON_BUFFERS - 2; + else + recon_buffers_count = MAX_RECON_BUFFERS; + + if (ltrmode.ltr_mode == (unsigned long)QOMX_VIDEO_LTRMode_Auto) + { + recon_buffers_count = MAX_RECON_BUFFERS; + DEBUG_PRINT_HIGH("ltr mode enabled, so set recon buffers " + "count to %d", recon_buffers_count); + } + + if (!venc_allocate_recon_buffers()) + return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL); + else + { + DEBUG_PRINT_ERROR("Failed in creating Recon buffers\n"); + return -1; + } +#else + return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL); +#endif +} + +#ifdef MAX_RES_1080P +OMX_U32 venc_dev::venc_allocate_recon_buffers() +{ + OMX_U32 yuv_size; + struct venc_ioctl_msg ioctl_msg; + struct venc_recon_buff_size recon_buff_size; + + recon_buff_size.width = ((m_sVenc_cfg.input_width + 15) / 16) * 16; + recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16; + + DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d\n", m_sVenc_cfg.input_width, + m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height); + + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&recon_buff_size; + + if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\n VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" , + recon_buff_size.width, recon_buff_size.height); + return OMX_ErrorInsufficientResources; + } + + DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d\n", + m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width, + recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment, + recon_buffers_count); + + for(int i = 0; i < recon_buffers_count; i++) + { + if(pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i)) + { + DEBUG_PRINT_ERROR("Error returned in allocating recon buffers\n"); + return -1; + } + } + return 0; +} +OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count) +{ + OMX_U32 pmem_fd = -1; + OMX_U32 width, height; + void *buf_addr = NULL; + struct venc_ioctl_msg ioctl_msg; + struct venc_recon_addr recon_addr; + int rc = 0; + +#ifdef USE_ION + recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY); + if(recon_buff[count].ion_device_fd < 0) + { + DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed"); + return -1; + } + + recon_buff[count].alloc_data.len = size; +#ifdef MAX_RES_720P + recon_buff[count].alloc_data.heap_mask = ION_HEAP(MEM_HEAP_ID); +#else + recon_buff[count].alloc_data.heap_mask = (ION_HEAP(MEM_HEAP_ID) | + ION_HEAP(ION_IOMMU_HEAP_ID)); +#endif + recon_buff[count].alloc_data.flags = ION_FLAG_CACHED; + recon_buff[count].alloc_data.align = clip2(alignment); + if (recon_buff[count].alloc_data.align != 8192) + recon_buff[count].alloc_data.align = 8192; + + rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data); + if(rc || !recon_buff[count].alloc_data.handle) { + DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); + recon_buff[count].alloc_data.handle=NULL; + return -1; + } + + recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle; + rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd); + if(rc) { + DEBUG_PRINT_ERROR("\n ION MAP failed "); + recon_buff[count].ion_alloc_fd.fd =-1; + recon_buff[count].ion_alloc_fd.fd =-1; + return -1; + } + pmem_fd = recon_buff[count].ion_alloc_fd.fd; +#else + struct pmem_allocation allocation; + pmem_fd = open(MEM_DEVICE, O_RDWR); + + if ((int)(pmem_fd) < 0) + { + DEBUG_PRINT_ERROR("\n Failed to get an pmem handle"); + return -1; + } + + allocation.size = size; + allocation.align = clip2(alignment); + + if (allocation.align != 8192) + allocation.align = 8192; + + if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) + { + DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", + allocation.align, allocation.size); + return -1; + } +#endif + buf_addr = mmap(NULL, size, + PROT_READ | PROT_WRITE, + MAP_SHARED, pmem_fd, 0); + + if (buf_addr == (void*) MAP_FAILED) + { + close(pmem_fd); + pmem_fd = -1; + DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr); +#ifdef USE_ION + if(ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE, + &recon_buff[count].alloc_data.handle)) { + DEBUG_PRINT_LOW("ion recon buffer free failed"); + } + recon_buff[count].alloc_data.handle = NULL; + recon_buff[count].ion_alloc_fd.fd =-1; + close(recon_buff[count].ion_device_fd); + recon_buff[count].ion_device_fd =-1; +#endif + return -1; + } + + DEBUG_PRINT_HIGH("\n Allocated virt:%p, FD: %d of size %d \n", buf_addr, pmem_fd, size); + + recon_addr.buffer_size = size; + recon_addr.pmem_fd = pmem_fd; + recon_addr.offset = 0; + recon_addr.pbuffer = (unsigned char *)buf_addr; + + ioctl_msg.in = (void*)&recon_addr; + ioctl_msg.out = NULL; + + if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Failed to set the Recon_buffers\n"); + return -1; + } + + recon_buff[count].virtual_address = (unsigned char *) buf_addr; + recon_buff[count].size = size; + recon_buff[count].offset = 0; + recon_buff[count].pmem_fd = pmem_fd; + + DEBUG_PRINT_ERROR("\n Allocated virt:%p, FD: %d of size %d at index: %d\n", recon_buff[count].virtual_address, + recon_buff[count].pmem_fd, recon_buff[count].size, count); + return 0; +} + +OMX_U32 venc_dev::pmem_free() +{ + int cnt = 0; + struct venc_ioctl_msg ioctl_msg; + struct venc_recon_addr recon_addr; + for (cnt = 0; cnt < recon_buffers_count; cnt++) + { + if(recon_buff[cnt].pmem_fd) + { + recon_addr.pbuffer = recon_buff[cnt].virtual_address; + recon_addr.offset = recon_buff[cnt].offset; + recon_addr.pmem_fd = recon_buff[cnt].pmem_fd; + recon_addr.buffer_size = recon_buff[cnt].size; + ioctl_msg.in = (void*)&recon_addr; + ioctl_msg.out = NULL; + if(ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0) + DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed"); + munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size); + close(recon_buff[cnt].pmem_fd); +#ifdef USE_ION + if(ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE, + &recon_buff[cnt].alloc_data.handle)) { + DEBUG_PRINT_LOW("ion recon buffer free failed"); + } + recon_buff[cnt].alloc_data.handle = NULL; + recon_buff[cnt].ion_alloc_fd.fd =-1; + close(recon_buff[cnt].ion_device_fd); + recon_buff[cnt].ion_device_fd =-1; +#endif + DEBUG_PRINT_LOW("\n cleaning Index %d of size %d \n",cnt,recon_buff[cnt].size); + recon_buff[cnt].pmem_fd = -1; + recon_buff[cnt].virtual_address = NULL; + recon_buff[cnt].offset = 0; + recon_buff[cnt].alignment = 0; + recon_buff[cnt].size = 0; + } + } + return 0; +} +#endif + +void venc_dev::venc_config_print() +{ + + DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %d, Profile %d, level : %d", + m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level); + + DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %d, Height:%d, Fps: %d", + m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, + m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d", + bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %d, qpP: %d, qpb: 0", + session_qp.iframeqp, session_qp.pframqp); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: minQP: %d, maxQP: %d", + qp_range.minqp, qp_range.maxqp); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d", + voptimecfg.voptime_resolution, multislice.mslice_mode, + multislice.mslice_size); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %d", + entropy.longentropysel, entropy.cabacmodel); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d\n", + dbkfilter.db_mode, dbkfilter.slicealpha_offset, + dbkfilter.slicebeta_offset); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %d, HEC: %d\n", + intra_refresh.mbcount, hec.header_extension); +} + +unsigned venc_dev::venc_flush( unsigned port) +{ + struct venc_ioctl_msg ioctl_msg; + struct venc_bufferflush buffer_index; + + if(port == PORT_INDEX_IN) + { + DEBUG_PRINT_HIGH("Calling Input Flush"); + buffer_index.flush_mode = VEN_FLUSH_INPUT; + ioctl_msg.in = (void*)&buffer_index; + ioctl_msg.out = NULL; + + return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); + } + else if(port == PORT_INDEX_OUT) + { + DEBUG_PRINT_HIGH("Calling Output Flush"); + buffer_index.flush_mode = VEN_FLUSH_OUTPUT; + ioctl_msg.in = (void*)&buffer_index; + ioctl_msg.out = NULL; + return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); + } + else + { + return -1; + } +} + +//allocating I/P memory from pmem and register with the device + + +bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct pmem *pmem_tmp; + struct venc_bufferpayload dev_buffer = {0}; + struct venc_allocatorproperty buff_alloc_property = {0}; + + pmem_tmp = (struct pmem *)buf_addr; + + DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); + + if(port == PORT_INDEX_IN) + { + dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; + dev_buffer.fd = pmem_tmp->fd; + dev_buffer.maped_size = pmem_tmp->size; + dev_buffer.sz = pmem_tmp->size; + dev_buffer.offset = pmem_tmp->offset; + + if((m_sVenc_cfg.input_height %16 !=0) || (m_sVenc_cfg.input_width%16 != 0)) + { + unsigned long ht = m_sVenc_cfg.input_height; + unsigned long wd = m_sVenc_cfg.input_width; + unsigned int luma_size, luma_size_2k; + + ht = (ht + 15) & ~15; + wd = (wd + 15) & ~15; + + luma_size = ht * wd; + luma_size_2k = (luma_size + 2047) & ~2047; + + dev_buffer.sz = luma_size_2k + ((luma_size/2 + 2047) & ~2047); +#ifdef USE_ION + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&buff_alloc_property; + if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:get input buffer failed "); + return false; + } + if(buff_alloc_property.alignment < 4096) + { + dev_buffer.sz = ((dev_buffer.sz + 4095) & ~4095); + } + else + { + dev_buffer.sz = ((dev_buffer.sz + (buff_alloc_property.alignment - 1)) & + ~(buff_alloc_property.alignment - 1)); + } +#endif + dev_buffer.maped_size = dev_buffer.sz; + } + + ioctl_msg.in = (void*)&dev_buffer; + ioctl_msg.out = NULL; + + DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ + dev_buffer.pbuffer, \ + dev_buffer.fd, \ + dev_buffer.offset, \ + dev_buffer.maped_size); + + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed "); + return false; + } + } + else if(port == PORT_INDEX_OUT) + { + dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; + dev_buffer.fd = pmem_tmp->fd; + dev_buffer.sz = pmem_tmp->size; + dev_buffer.maped_size = pmem_tmp->size; + dev_buffer.offset = pmem_tmp->offset; + ioctl_msg.in = (void*)&dev_buffer; + ioctl_msg.out = NULL; + + DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ + dev_buffer.pbuffer, \ + dev_buffer.fd, \ + dev_buffer.offset, \ + dev_buffer.maped_size); + + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed "); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index "); + return false; + } + + return true; +} + +bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct pmem *pmem_tmp; + struct venc_bufferpayload dev_buffer = {0}; + + pmem_tmp = (struct pmem *)buf_addr; + + DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); + + if(port == PORT_INDEX_IN) + { + dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; + dev_buffer.fd = pmem_tmp->fd; + dev_buffer.maped_size = pmem_tmp->size; + dev_buffer.sz = pmem_tmp->size; + dev_buffer.offset = pmem_tmp->offset; + ioctl_msg.in = (void*)&dev_buffer; + ioctl_msg.out = NULL; + + DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ + dev_buffer.pbuffer, \ + dev_buffer.fd, \ + dev_buffer.offset, \ + dev_buffer.maped_size); + + if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed "); + return false; + } + } + else if(port == PORT_INDEX_OUT) + { + dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; + dev_buffer.fd = pmem_tmp->fd; + dev_buffer.sz = pmem_tmp->size; + dev_buffer.maped_size = pmem_tmp->size; + dev_buffer.offset = pmem_tmp->offset; + ioctl_msg.in = (void*)&dev_buffer; + ioctl_msg.out = NULL; + + DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ + dev_buffer.pbuffer, \ + dev_buffer.fd, \ + dev_buffer.offset, \ + dev_buffer.maped_size); + + if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed "); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index "); + return false; + } + + return true; +} + +bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned) +{ + struct venc_buffer frameinfo; + struct pmem *temp_buffer; + struct venc_ioctl_msg ioctl_msg; + struct OMX_BUFFERHEADERTYPE *bufhdr; + + if(buffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL"); + return false; + } + bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; + + DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen); + + if(pmem_data_buf) + { + DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); + frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; + } + else + { + DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); + frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; + } + + frameinfo.clientdata = (void *) buffer; + frameinfo.sz = bufhdr->nFilledLen; + frameinfo.len = bufhdr->nFilledLen; + frameinfo.flags = bufhdr->nFlags; + frameinfo.offset = bufhdr->nOffset; + frameinfo.timestamp = bufhdr->nTimeStamp; + DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp); + ioctl_msg.in = &frameinfo; + ioctl_msg.out = NULL; + + DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", + bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); + if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) + { + /*Generate an async error and move to invalid state*/ + return false; + } +#ifdef INPUT_BUFFER_LOG +#ifdef MAX_RES_1080P + + int y_size = 0; + int c_offset = 0; + unsigned char *buf_addr = NULL; + + y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height; + //chroma offset is y_size aligned to the 2k boundary + c_offset= (y_size + 2047) & (~(2047)); + + if(pmem_data_buf) + { + DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); + buf_addr = (OMX_U8 *)pmem_data_buf; + } + else + { + DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); + buf_addr = (unsigned char *)mmap(NULL, + ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2], + PROT_READ|PROT_WRITE, MAP_SHARED, + ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[0], 0); + } + + if(inputBufferFile1) + { + fwrite((const char *)buf_addr, y_size, 1,inputBufferFile1); + fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1,inputBufferFile1); + } + + munmap (buf_addr, ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2]); +#else + if(inputBufferFile1) + { + fwrite((const char *)frameinfo.ptrbuffer, frameinfo.len, 1,inputBufferFile1); + } +#endif + +#endif + return true; +} +bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct pmem *temp_buffer = NULL; + struct venc_buffer frameinfo; + struct OMX_BUFFERHEADERTYPE *bufhdr; + + if(buffer == NULL) + { + return false; + } + bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; + + if(pmem_data_buf) + { + DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); + frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; + } + else + { + DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); + frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; + } + + frameinfo.clientdata = buffer; + frameinfo.sz = bufhdr->nAllocLen; + frameinfo.flags = bufhdr->nFlags; + frameinfo.offset = bufhdr->nOffset; + + ioctl_msg.in = &frameinfo; + ioctl_msg.out = NULL; + DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", + bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); + if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed"); + return false; + } + + return true; +} + +bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable); + if(multislice.mslice_mode == VEN_MSLICE_CNT_MB) + { + if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0) + { + DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set " + "slice delivery mode to the driver.", multislice.mslice_mode); + } + return true; +} + +bool venc_dev::venc_set_plusptype(OMX_BOOL enable) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_plusptype plusptype = {0}; + DEBUG_PRINT_LOW("Set plusptype: %d", enable); + plusptype.plusptype_enable = enable; + ioctl_msg.in = (void*)&plusptype; + ioctl_msg.out = NULL; + if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_H263_PLUSPTYPE,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("Request for setting plusptype for h263 failed"); + return false; + } + return true; +} + +bool venc_dev::venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + venc_ltrmode ltr_mode; + ltr_mode.ltr_mode = (unsigned long)mode; + DEBUG_PRINT_HIGH("Set ltr mode: %d", mode); + ioctl_msg.in = (void*)<r_mode; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRMODE, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("ERROR: Setting ltrmode failed"); + return false; + } + ltrmode.ltr_mode = (unsigned long)mode; + return true; +} + +bool venc_dev::venc_set_ltrcount(OMX_U32 count) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + venc_ltrcount ltr_count; + ltr_count.ltr_count = (unsigned long)count; + DEBUG_PRINT_HIGH("Set ltr count: %d", count); + ioctl_msg.in = (void*)<r_count; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRCOUNT, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("ERROR: Setting ltrcount failed"); + return false; + } + ltrcount.ltr_count = (unsigned long)count; + return true; +} + +bool venc_dev::venc_set_ltrperiod(OMX_U32 period) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + venc_ltrperiod ltr_period; + ltr_period.ltr_period = (unsigned long)period; + DEBUG_PRINT_HIGH("Set ltr period: %d", period); + ioctl_msg.in = (void*)<r_period; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRPERIOD, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("ERROR: Setting ltrperiod failed"); + return false; + } + ltrperiod.ltr_period = (unsigned long)period; + return true; +} + +bool venc_dev::venc_set_ltruse(OMX_U32 id, OMX_U32 frames) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + venc_ltruse ltr_use; + ltr_use.ltr_id = (unsigned long)id; + ltr_use.ltr_frames = (unsigned long)frames; + DEBUG_PRINT_HIGH("Set ltr use: id = %d, ltr_frames = %d", id, frames); + ioctl_msg.in = (void*)<r_use; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRUSE, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("ERROR: Setting ltruse failed"); + return false; + } + return true; +} + +bool venc_dev::venc_set_extradata(OMX_U32 extra_data) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data); + ioctl_msg.in = (void*)&extra_data; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed"); + return false; + } + + return true; +} + +bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_sessionqp qp = {0, 0}; + DEBUG_PRINT_HIGH("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp, + p_frame_qp); + + qp.iframeqp = i_frame_qp; + qp.pframqp = p_frame_qp; + + ioctl_msg.in = (void*)&qp; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed"); + return false; + } + + session_qp.iframeqp = i_frame_qp; + session_qp.pframqp = p_frame_qp; + + return true; +} + +bool venc_dev::venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_qprange qp = {0, 0}; + DEBUG_PRINT_LOW("venc_set_qp_range:: min_qp = %d, max_qp = %d", min_qp, + max_qp); + + qp.minqp = min_qp; + qp.maxqp = max_qp; + + ioctl_msg.in = (void*)&qp; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_QP_RANGE,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting qp range failed"); + return false; + } + + qp_range.minqp= min_qp; + qp_range.maxqp= max_qp; + + return true; +} + +bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_profile requested_profile; + struct ven_profilelevel requested_level; + unsigned const int *profile_tbl = NULL; + unsigned long mb_per_frame = 0, mb_per_sec = 0; + DEBUG_PRINT_HIGH("venc_set_profile_level:: eProfile = %d, Level = %d", + eProfile, eLevel); + mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* + ((m_sVenc_cfg.input_width + 15) >> 4); + if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) + { + DEBUG_PRINT_HIGH("Set profile/level was done already"); + return true; + } + + if(eProfile && eLevel) + { + /* non-zero values will be set by user, saving the same*/ + m_eProfile = eProfile; + m_eLevel = eLevel; + DEBUG_PRINT_HIGH("Save profile/level (%d/%d) for max allowed bitrate check", + m_eProfile, m_eLevel); + } + + DEBUG_PRINT_LOW("Validating Profile/Level from table"); + if(!venc_validate_profile_level(&eProfile, &eLevel)) + { + DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed"); + return false; + } + + if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) + { + DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and " + "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile, + OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); + if(eProfile == OMX_VIDEO_MPEG4ProfileSimple) + { + requested_profile.profile = VEN_PROFILE_MPEG4_SP; + profile_tbl = (unsigned int const *) + (&mpeg4_profile_level_table[MPEG4_SP_START]); + profile_tbl += MPEG4_720P_LEVEL*5; + } + else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { + requested_profile.profile = VEN_PROFILE_MPEG4_ASP; + profile_tbl = (unsigned int const *) + (&mpeg4_profile_level_table[MPEG4_ASP_START]); + profile_tbl += MPEG4_720P_LEVEL*5; + } + else + { + DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u", + eProfile); + return false; + } + + DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," + "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," + "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, + OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); + + if(mb_per_frame >= 3600) + { + if(requested_profile.profile == VEN_PROFILE_MPEG4_ASP) + requested_level.level = VEN_LEVEL_MPEG4_5; + if(requested_profile.profile == VEN_PROFILE_MPEG4_SP) + requested_level.level = VEN_LEVEL_MPEG4_6; + } + else + { + switch(eLevel) + { + case OMX_VIDEO_MPEG4Level0: + requested_level.level = VEN_LEVEL_MPEG4_0; + break; + case OMX_VIDEO_MPEG4Level1: + requested_level.level = VEN_LEVEL_MPEG4_1; + break; + case OMX_VIDEO_MPEG4Level2: + requested_level.level = VEN_LEVEL_MPEG4_2; + break; + case OMX_VIDEO_MPEG4Level3: + requested_level.level = VEN_LEVEL_MPEG4_3; + break; + case OMX_VIDEO_MPEG4Level4a: + requested_level.level = VEN_LEVEL_MPEG4_4; + break; + case OMX_VIDEO_MPEG4Level5: + mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den); + if((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) && + (mb_per_sec >= profile_tbl[1])) + { + DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution"); + requested_level.level = VEN_LEVEL_MPEG4_6; + } + else + { + DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution"); + requested_level.level = VEN_LEVEL_MPEG4_5; + } + break; + default: + return false; + // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 + break; + } + } + } + else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) + { + if(eProfile == OMX_VIDEO_H263ProfileBaseline) + { + requested_profile.profile = VEN_PROFILE_H263_BASELINE; + } + else + { + DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u", + requested_profile.profile); + return false; + } + //profile level + switch(eLevel) + { + case OMX_VIDEO_H263Level10: + requested_level.level = VEN_LEVEL_H263_10; + break; + case OMX_VIDEO_H263Level20: + requested_level.level = VEN_LEVEL_H263_20; + break; + case OMX_VIDEO_H263Level30: + requested_level.level = VEN_LEVEL_H263_30; + break; + case OMX_VIDEO_H263Level40: + requested_level.level = VEN_LEVEL_H263_40; + break; + case OMX_VIDEO_H263Level45: + requested_level.level = VEN_LEVEL_H263_45; + break; + case OMX_VIDEO_H263Level50: + requested_level.level = VEN_LEVEL_H263_50; + break; + case OMX_VIDEO_H263Level60: + requested_level.level = VEN_LEVEL_H263_60; + break; + case OMX_VIDEO_H263Level70: + requested_level.level = VEN_LEVEL_H263_70; + break; + default: + return false; + break; + } + } + else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) + { + if(eProfile == OMX_VIDEO_AVCProfileBaseline) + { + requested_profile.profile = VEN_PROFILE_H264_BASELINE; + } + else if(eProfile == OMX_VIDEO_AVCProfileMain) + { + requested_profile.profile = VEN_PROFILE_H264_MAIN; + } + else if(eProfile == OMX_VIDEO_AVCProfileHigh) + { + requested_profile.profile = VEN_PROFILE_H264_HIGH; + } + else + { + DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u", + requested_profile.profile); + return false; + } + //profile level + switch(eLevel) + { + case OMX_VIDEO_AVCLevel1: + requested_level.level = VEN_LEVEL_H264_1; + break; + case OMX_VIDEO_AVCLevel1b: + requested_level.level = VEN_LEVEL_H264_1b; + break; + case OMX_VIDEO_AVCLevel11: + requested_level.level = VEN_LEVEL_H264_1p1; + break; + case OMX_VIDEO_AVCLevel12: + requested_level.level = VEN_LEVEL_H264_1p2; + break; + case OMX_VIDEO_AVCLevel13: + requested_level.level = VEN_LEVEL_H264_1p3; + break; + case OMX_VIDEO_AVCLevel2: + requested_level.level = VEN_LEVEL_H264_2; + break; + case OMX_VIDEO_AVCLevel21: + requested_level.level = VEN_LEVEL_H264_2p1; + break; + case OMX_VIDEO_AVCLevel22: + requested_level.level = VEN_LEVEL_H264_2p2; + break; + case OMX_VIDEO_AVCLevel3: + requested_level.level = VEN_LEVEL_H264_3; + break; + case OMX_VIDEO_AVCLevel31: + requested_level.level = VEN_LEVEL_H264_3p1; + break; + case OMX_VIDEO_AVCLevel32: + requested_level.level = VEN_LEVEL_H264_3p2; + break; + case OMX_VIDEO_AVCLevel4: + requested_level.level = VEN_LEVEL_H264_4; + break; + default : + DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %u", + requested_level.level); + return false; + break; + } + } + if(!m_profile_set) + { + ioctl_msg.in = (void*)&requested_profile; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting profile failed"); + return false; + } + codec_profile.profile = requested_profile.profile; + m_profile_set = true; + DEBUG_PRINT_HIGH("Set codec profile = 0x%x", codec_profile.profile); + } + + if(!m_level_set) + { + ioctl_msg.in = (void*)&requested_level; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting profile level failed"); + return false; + } + profile_level.level = requested_level.level; + m_level_set = true; + DEBUG_PRINT_HIGH("Set codec level = 0x%x", profile_level.level); + } + + return true; +} + +bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_voptimingcfg vop_timing_cfg; + + DEBUG_PRINT_HIGH("venc_set_voptiming_cfg: TimeRes = %u", + TimeIncRes); + + vop_timing_cfg.voptime_resolution = TimeIncRes; + + ioctl_msg.in = (void*)&vop_timing_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Vop Timing failed"); + return false; + } + + voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; + return true; +} + +bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_intraperiod intraperiod_cfg; + + DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u", + nPFrames); + intraperiod_cfg.num_pframes = nPFrames; + if((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) || + (codec_profile.profile == VEN_PROFILE_H264_MAIN) || + (codec_profile.profile == VEN_PROFILE_H264_HIGH)) + { +#ifdef MAX_RES_1080P + if (nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + intraperiod_cfg.num_bframes = 1; + } + else + intraperiod_cfg.num_bframes = 0; +#else + if(nBFrames) + { + DEBUG_PRINT_ERROR("B frames not supported"); + intraperiod_cfg.num_bframes = 0; + } + else + { + DEBUG_PRINT_ERROR("B frames not supported"); + intraperiod_cfg.num_bframes = 0; + } +#endif + } + else + intraperiod_cfg.num_bframes = 0; + + DEBUG_PRINT_HIGH("venc_set_intra_period: nPFrames = %u nBFrames = %u", + intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes); + ioctl_msg.in = (void*)&intraperiod_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + + intra_period.num_pframes = intraperiod_cfg.num_pframes; + intra_period.num_bframes = intraperiod_cfg.num_bframes; + return true; +} + +bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_entropycfg entropy_cfg; + + memset(&entropy_cfg,0,sizeof(entropy_cfg)); + DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level); + + if(enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)){ + entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC; + if (i_cabac_level == 0) { + entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0; + } +#ifdef MAX_RES_1080P + else + { + DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to model 0",i_cabac_level); + entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0; + } +#else + else if (i_cabac_level == 1) { + entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1; + } + else if (i_cabac_level == 2) { + entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2; + } +#endif + } + else if(!enable){ + entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC; + } + else{ + DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile"); + return false; + } + + ioctl_msg.in = (void*)&entropy_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting entropy config failed"); + return false; + } + entropy.longentropysel = entropy_cfg.longentropysel; + entropy.cabacmodel = entropy_cfg.cabacmodel; + return true; +} + +bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB +{ + venc_ioctl_msg ioctl_msg = {NULL, NULL}; + bool status = true; + struct venc_multiclicecfg multislice_cfg; + + if((Codec != OMX_IndexParamVideoH263) && (nSlicesize)){ + multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB; + multislice_cfg.mslice_size = nSlicesize; + } + else{ + multislice_cfg.mslice_mode = VEN_MSLICE_OFF; + multislice_cfg.mslice_size = 0; + } + + DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode, + multislice_cfg.mslice_size); + + ioctl_msg.in = (void*)&multislice_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed"); + status = false; + } + else + { + multislice.mslice_mode = multislice_cfg.mslice_mode; + multislice.mslice_size = nSlicesize; + } + return status; +} + +bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) +{ + venc_ioctl_msg ioctl_msg = {NULL, NULL}; + bool status = true; + struct venc_intrarefresh intraRefresh_cfg; + + // There is no disabled mode. Disabled mode is indicated by a 0 count. + if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) + { + intraRefresh_cfg.irmode = VEN_IR_OFF; + intraRefresh_cfg.mbcount = 0; + } + else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && + (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) + { + intraRefresh_cfg.irmode = VEN_IR_CYCLIC; + intraRefresh_cfg.mbcount = irMBs; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:" + "mb count: %d, mb mode:%d", irMBs, ir_mode); + return false; + } + + ioctl_msg.in = (void*)&intraRefresh_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra Refresh failed"); + status = false; + } + else + { + intra_refresh.irmode = intraRefresh_cfg.irmode; + intra_refresh.mbcount = intraRefresh_cfg.mbcount; + } + return status; +} + +bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) +{ + venc_ioctl_msg ioctl_msg = {NULL, NULL}; + bool status = true; + struct venc_headerextension hec_cfg; + struct venc_multiclicecfg multislice_cfg; + + if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) { + if (error_resilience->bEnableHEC) { + hec_cfg.header_extension = 1; + } + else { + hec_cfg.header_extension = 0; + } + + ioctl_msg.in = (void*)&hec_cfg; + ioctl_msg.out = NULL; + if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Request for setting HEader Error correction failed"); + return false; + } + hec.header_extension = error_resilience->bEnableHEC; + } + + if (error_resilience->bEnableRVLC) { + DEBUG_PRINT_ERROR("\n RVLC is not Supported"); + return false; + } + + if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) && + (error_resilience->bEnableDataPartitioning)) { + DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264"); + return false; + } + + if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) && + (error_resilience->nResynchMarkerSpacing)) { + multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; + multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; + } + else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 && + error_resilience->bEnableDataPartitioning) { + multislice_cfg.mslice_mode = VEN_MSLICE_GOB; + multislice_cfg.mslice_size = 0; + } + else { + multislice_cfg.mslice_mode = VEN_MSLICE_OFF; + multislice_cfg.mslice_size = 0; + } + DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode, + multislice_cfg.mslice_size); + ioctl_msg.in = (void*)&multislice_cfg; + ioctl_msg.out = NULL; + if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed"); + status = false; + } + else + { + multislice.mslice_mode = multislice_cfg.mslice_mode ; + multislice.mslice_size = multislice_cfg.mslice_size; + + } + return status; +} + +bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_dbcfg filter_cfg; + + memset(&filter_cfg, 0, sizeof(filter_cfg)); + DEBUG_PRINT_LOW("\n venc_set_inloop_filter: %u",loopfilter); + + if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){ + filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY; + } + else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){ + filter_cfg.db_mode = VEN_DB_DISABLE; + } + else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){ + filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY; + } + filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0; + + ioctl_msg.in = (void*)&filter_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting inloop filter failed"); + return false; + } + + dbkfilter.db_mode = filter_cfg.db_mode; + dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; + return true; +} + +bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) +{ + venc_ioctl_msg ioctl_msg = {NULL, NULL}; + struct venc_targetbitrate bitrate_cfg; + + DEBUG_PRINT_HIGH("venc_set_target_bitrate: bitrate = %u", + nTargetBitrate); + bitrate_cfg.target_bitrate = nTargetBitrate ; + ioctl_msg.in = (void*)&bitrate_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed"); + return false; + } + m_sVenc_cfg.targetbitrate = nTargetBitrate; + bitrate.target_bitrate = nTargetBitrate; + if(!config) + { + m_level_set = false; + if(venc_set_profile_level(0, 0)) + { + DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d\n",profile_level.level); + } + } + return true; +} + +bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) +{ + venc_ioctl_msg ioctl_msg = {NULL, NULL}; + struct venc_framerate frame_rate_cfg; + + Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); + + DEBUG_PRINT_HIGH("venc_set_encode_framerate: framerate(Q16) = %u, NR: %d, DR: %d", + encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); + + ioctl_msg.in = (void*)&frame_rate_cfg; + ioctl_msg.out = NULL; + if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed"); + return false; + } + + m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; + m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; + if(!config) + { + m_level_set = false; + if(venc_set_profile_level(0, 0)) + { + DEBUG_PRINT_LOW("Calling set level (Framerate) with %d",profile_level.level); + } + } + return true; +} + +bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) +{ + venc_ioctl_msg ioctl_msg = {NULL, NULL}; + if(color_format == OMX_COLOR_FormatYUV420SemiPlanar) + { +#ifdef MAX_RES_1080P + m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; +#else + m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; +#endif + } + else + { + DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format); +#ifdef MAX_RES_1080P + m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; +#else + m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; +#endif + DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set"); + } + ioctl_msg.in = (void*)&m_sVenc_cfg; + ioctl_msg.out = NULL; + if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed"); + return false; + } + return true; +} + +bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) +{ + DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); + if(intra_vop_refresh == OMX_TRUE) + { + if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect"); + } + return true; +} + +bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + bool status = true; + struct venc_ratectrlcfg ratectrl_cfg; + + //rate control + switch(eControlRate) + { + case OMX_Video_ControlRateDisable: + ratectrl_cfg.rcmode = VEN_RC_OFF; + break; + case OMX_Video_ControlRateVariableSkipFrames: + ratectrl_cfg.rcmode = VEN_RC_VBR_VFR; + break; + case OMX_Video_ControlRateVariable: + ratectrl_cfg.rcmode = VEN_RC_VBR_CFR; + break; + case OMX_Video_ControlRateConstantSkipFrames: + ratectrl_cfg.rcmode = VEN_RC_CBR_VFR; + break; + case OMX_Video_ControlRateConstant: + ratectrl_cfg.rcmode = VEN_RC_CBR_CFR; + break; + default: + status = false; + break; + } + + if(status) + { + ioctl_msg.in = (void*)&ratectrl_cfg; + ioctl_msg.out = NULL; + if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed"); + status = false; + } + else + rate_ctrl.rcmode = ratectrl_cfg.rcmode; + } + return status; +} + +bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) +{ + bool status = true; + if(eProfile == NULL || eLevel == NULL) + { + return false; + } + + if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) + { + switch(codec_profile.profile) + { + case VEN_PROFILE_MPEG4_SP: + *eProfile = OMX_VIDEO_MPEG4ProfileSimple; + break; + case VEN_PROFILE_MPEG4_ASP: + *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + break; + default: + *eProfile = OMX_VIDEO_MPEG4ProfileMax; + status = false; + break; + } + + if(!status) + { + return status; + } + + //profile level + switch(profile_level.level) + { + case VEN_LEVEL_MPEG4_0: + *eLevel = OMX_VIDEO_MPEG4Level0; + break; + case VEN_LEVEL_MPEG4_1: + *eLevel = OMX_VIDEO_MPEG4Level1; + break; + case VEN_LEVEL_MPEG4_2: + *eLevel = OMX_VIDEO_MPEG4Level2; + break; + case VEN_LEVEL_MPEG4_3: + *eLevel = OMX_VIDEO_MPEG4Level3; + break; + case VEN_LEVEL_MPEG4_4: + *eLevel = OMX_VIDEO_MPEG4Level4a; + break; + case VEN_LEVEL_MPEG4_5: + case VEN_LEVEL_MPEG4_6: + *eLevel = OMX_VIDEO_MPEG4Level5; + break; + default: + *eLevel = OMX_VIDEO_MPEG4LevelMax; + status = false; + break; + } + } + else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) + { + if(codec_profile.profile == VEN_PROFILE_H263_BASELINE) + { + *eProfile = OMX_VIDEO_H263ProfileBaseline; + } + else + { + *eProfile = OMX_VIDEO_H263ProfileMax; + return false; + } + switch(profile_level.level) + { + case VEN_LEVEL_H263_10: + *eLevel = OMX_VIDEO_H263Level10; + break; + case VEN_LEVEL_H263_20: + *eLevel = OMX_VIDEO_H263Level20; + break; + case VEN_LEVEL_H263_30: + *eLevel = OMX_VIDEO_H263Level30; + break; + case VEN_LEVEL_H263_40: + *eLevel = OMX_VIDEO_H263Level40; + break; + case VEN_LEVEL_H263_45: + *eLevel = OMX_VIDEO_H263Level45; + break; + case VEN_LEVEL_H263_50: + *eLevel = OMX_VIDEO_H263Level50; + break; + case VEN_LEVEL_H263_60: + *eLevel = OMX_VIDEO_H263Level60; + break; + case VEN_LEVEL_H263_70: + *eLevel = OMX_VIDEO_H263Level70; + break; + default: + *eLevel = OMX_VIDEO_H263LevelMax; + status = false; + break; + } + } + else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) + { + switch(codec_profile.profile) + { + case VEN_PROFILE_H264_BASELINE: + *eProfile = OMX_VIDEO_AVCProfileBaseline; + break; + case VEN_PROFILE_H264_MAIN: + *eProfile = OMX_VIDEO_AVCProfileMain; + break; + case VEN_PROFILE_H264_HIGH: + *eProfile = OMX_VIDEO_AVCProfileHigh; + break; + default: + *eProfile = OMX_VIDEO_AVCProfileMax; + status = false; + break; + } + + if(!status) + { + return status; + } + + switch(profile_level.level) + { + case VEN_LEVEL_H264_1: + *eLevel = OMX_VIDEO_AVCLevel1; + break; + case VEN_LEVEL_H264_1b: + *eLevel = OMX_VIDEO_AVCLevel1b; + break; + case VEN_LEVEL_H264_1p1: + *eLevel = OMX_VIDEO_AVCLevel11; + break; + case VEN_LEVEL_H264_1p2: + *eLevel = OMX_VIDEO_AVCLevel12; + break; + case VEN_LEVEL_H264_1p3: + *eLevel = OMX_VIDEO_AVCLevel13; + break; + case VEN_LEVEL_H264_2: + *eLevel = OMX_VIDEO_AVCLevel2; + break; + case VEN_LEVEL_H264_2p1: + *eLevel = OMX_VIDEO_AVCLevel21; + break; + case VEN_LEVEL_H264_2p2: + *eLevel = OMX_VIDEO_AVCLevel22; + break; + case VEN_LEVEL_H264_3: + *eLevel = OMX_VIDEO_AVCLevel3; + break; + case VEN_LEVEL_H264_3p1: + *eLevel = OMX_VIDEO_AVCLevel31; + break; + case VEN_LEVEL_H264_3p2: + *eLevel = OMX_VIDEO_AVCLevel32; + break; + case VEN_LEVEL_H264_4: + *eLevel = OMX_VIDEO_AVCLevel4; + break; + default : + *eLevel = OMX_VIDEO_AVCLevelMax; + status = false; + break; + } + } + return status; +} + +bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) +{ + OMX_U32 new_profile = 0, new_level = 0; + unsigned const int *profile_tbl = NULL; + OMX_U32 mb_per_frame, mb_per_sec; + bool profile_level_found = false; + + DEBUG_PRINT_LOW("\n Init profile table for respective codec"); + //validate the ht,width,fps,bitrate and set the appropriate profile and level + if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) + { + if(*eProfile == 0) + { + if(!m_profile_set) + { + *eProfile = OMX_VIDEO_MPEG4ProfileSimple; + } + else + { + switch(codec_profile.profile) + { + case VEN_PROFILE_MPEG4_ASP: + *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + break; + case VEN_PROFILE_MPEG4_SP: + *eProfile = OMX_VIDEO_MPEG4ProfileSimple; + break; + default: + DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); + return false; + } + } + } + + if(*eLevel == 0 && !m_level_set) + { + *eLevel = OMX_VIDEO_MPEG4LevelMax; + } + + if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple) + { + profile_tbl = (unsigned int const *)mpeg4_profile_level_table; + } + else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { + profile_tbl = (unsigned int const *) + (&mpeg4_profile_level_table[MPEG4_ASP_START]); + } + else + { + DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile); + return false; + } + } + else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) + { + if(*eProfile == 0) + { + if(!m_profile_set) + { + *eProfile = OMX_VIDEO_AVCProfileBaseline; + } + else + { + switch(codec_profile.profile) + { + case VEN_PROFILE_H264_BASELINE: + *eProfile = OMX_VIDEO_AVCProfileBaseline; + break; + case VEN_PROFILE_H264_MAIN: + *eProfile = OMX_VIDEO_AVCProfileMain; + break; + case VEN_PROFILE_H264_HIGH: + *eProfile = OMX_VIDEO_AVCProfileHigh; + break; + default: + DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); + return false; + } + } + } + + if(*eLevel == 0 && !m_level_set) + { + *eLevel = OMX_VIDEO_AVCLevelMax; + } + + if(*eProfile == OMX_VIDEO_AVCProfileBaseline) + { + profile_tbl = (unsigned int const *)h264_profile_level_table; + } + else if(*eProfile == OMX_VIDEO_AVCProfileHigh) + { + profile_tbl = (unsigned int const *) + (&h264_profile_level_table[H264_HP_START]); + } + else if(*eProfile == OMX_VIDEO_AVCProfileMain) + { + profile_tbl = (unsigned int const *) + (&h264_profile_level_table[H264_MP_START]); + } + else + { + DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile); + return false; + } + } + else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) + { + if(*eProfile == 0) + { + if(!m_profile_set) + { + *eProfile = OMX_VIDEO_H263ProfileBaseline; + } + else + { + switch(codec_profile.profile) + { + case VEN_PROFILE_H263_BASELINE: + *eProfile = OMX_VIDEO_H263ProfileBaseline; + break; + default: + DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); + return false; + } + } + } + + if(*eLevel == 0 && !m_level_set) + { + *eLevel = OMX_VIDEO_H263LevelMax; + } + + if(*eProfile == OMX_VIDEO_H263ProfileBaseline) + { + profile_tbl = (unsigned int const *)h263_profile_level_table; + } + else + { + DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile); + return false; + } + } + else + { + DEBUG_PRINT_LOW("\n Invalid codec type"); + return false; + } + + mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* + ((m_sVenc_cfg.input_width + 15)>> 4); + + if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)) + { + if(codec_profile.profile == VEN_PROFILE_MPEG4_ASP) + profile_level.level = VEN_LEVEL_MPEG4_5; + if(codec_profile.profile == VEN_PROFILE_MPEG4_SP) + profile_level.level = VEN_LEVEL_MPEG4_6; + { + new_level = profile_level.level; + new_profile = codec_profile.profile; + return true; + } + } + + mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; + + do{ + if(mb_per_frame <= (int)profile_tbl[0]) + { + if(mb_per_sec <= (int)profile_tbl[1]) + { + if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2]) + { + new_level = (int)profile_tbl[3]; + new_profile = (int)profile_tbl[4]; + profile_level_found = true; + DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level); + break; + } + } + } + profile_tbl = profile_tbl + 5; + }while(profile_tbl[0] != 0); + + if (profile_level_found != true) + { + DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n"); + return false; + } + + if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) + || (*eLevel == OMX_VIDEO_H263LevelMax)) + { + *eLevel = new_level; + } + DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu" + "Level = %lu", __func__, *eProfile, *eLevel); + + return true; +} + +bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate) +{ + unsigned const int *profile_tbl = NULL; + + switch(m_sVenc_cfg.codectype) + { + case VEN_CODEC_MPEG4: + if(m_eProfile == OMX_VIDEO_MPEG4ProfileSimple) + { + profile_tbl = (unsigned int const *)mpeg4_profile_level_table; + } + else if(m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { + profile_tbl = (unsigned int const *) + (&mpeg4_profile_level_table[MPEG4_ASP_START]); + } + else + { + DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile); + return false; + } + break; + case VEN_CODEC_H264: + if(m_eProfile == OMX_VIDEO_AVCProfileBaseline) + { + profile_tbl = (unsigned int const *)h264_profile_level_table; + } + else if(m_eProfile == OMX_VIDEO_AVCProfileHigh) + { + profile_tbl = (unsigned int const *) + (&h264_profile_level_table[H264_HP_START]); + } + else if(m_eProfile == OMX_VIDEO_AVCProfileMain) + { + profile_tbl = (unsigned int const *) + (&h264_profile_level_table[H264_MP_START]); + } + else + { + DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile); + return false; + } + + break; + case VEN_CODEC_H263: + if(m_eProfile == OMX_VIDEO_H263ProfileBaseline) + { + profile_tbl = (unsigned int const *)h263_profile_level_table; + } + else + { + DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile); + return false; + } + break; + default: + DEBUG_PRINT_ERROR("%s: unknown codec type", __func__); + return false; + } + while(profile_tbl[0] != 0) + { + if(profile_tbl[3] == m_eLevel) + { + if(nTargetBitrate > profile_tbl[2]) + { + DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]" + " is %u", m_eProfile, m_eLevel, profile_tbl[2]); + return false; + } + } + profile_tbl += 5; + } + return true; +} + +#ifdef _ANDROID_ICS_ +bool venc_dev::venc_set_meta_mode(bool mode) +{ + venc_ioctl_msg ioctl_msg = {NULL,NULL}; + ioctl_msg.in = &mode; + DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode); + if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0) + { + DEBUG_PRINT_ERROR(" Set meta buffer mode failed"); + return false; + } + return true; +} +#endif diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp new file mode 100644 index 00000000..bddd8e4c --- /dev/null +++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp @@ -0,0 +1,3214 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ + +#include +#include +#include +#include +#include +#include "video_encoder_device_v4l2.h" +#include "omx_video_encoder.h" +#include +#ifdef USE_ION +#include +#endif +#include +#include + +#define EXTRADATA_IDX(__num_planes) (__num_planes - 1) + +#define MPEG4_SP_START 0 +#define MPEG4_ASP_START (MPEG4_SP_START + 10) +#define H263_BP_START 0 +#define H264_BP_START 0 +#define H264_HP_START (H264_BP_START + 17) +#define H264_MP_START (H264_BP_START + 34) +#define POLL_TIMEOUT 1000 +#define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */ + +/* MPEG4 profile and level table*/ +static const unsigned int mpeg4_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, + {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, + {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, + {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, + {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, + {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {0,0,0,0,0}, + + {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {0,0,0,0,0}, +}; + +/* H264 profile and level table*/ +static const unsigned int h264_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, + {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, + {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, + {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, + {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, + {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, + {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, + {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, + {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, + {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, + {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, + {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, + {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline}, + {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline}, + {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline}, + {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline}, + {0,0,0,0,0}, + + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, + {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, + {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, + {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, + {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, + {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, + {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, + {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, + {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, + {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, + {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, + {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, + {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh}, + {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh}, + {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh}, + {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh}, + {0,0,0,0,0}, + + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, + {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, + {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, + {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, + {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, + {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, + {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, + {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, + {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, + {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, + {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, + {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, + {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain}, + {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain}, + {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain}, + {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain}, + {0,0,0,0,0} + +}; + +/* H263 profile and level table*/ +static const unsigned int h263_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, + {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, + {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, + {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, + {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, + {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, + {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, + {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, + {0,0,0,0,0} +}; + +#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } +#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } + +#ifdef INPUT_BUFFER_LOG +FILE *inputBufferFile1; +char inputfilename [] = "/data/input.yuv"; +#endif +#ifdef OUTPUT_BUFFER_LOG +FILE *outputBufferFile1; +char outputfilename [] = "/data/output-bitstream.\0\0\0\0"; +#endif + +//constructor +venc_dev::venc_dev(class omx_venc *venc_class) +{ + //nothing to do + int i = 0; + venc_handle = venc_class; + etb = ebd = ftb = fbd = 0; + for (i = 0; i < MAX_PORT; i++) + streaming[i] = false; + + paused = false; + async_thread_created = false; + color_format = 0; + pthread_mutex_init(&pause_resume_mlock, NULL); + pthread_cond_init(&pause_resume_cond, NULL); + memset(&extradata_info, 0, sizeof(extradata_info)); + memset(&idrperiod, 0, sizeof(idrperiod)); + memset(&multislice, 0, sizeof(multislice)); + memset (&slice_mode, 0 , sizeof(slice_mode)); + memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg)); + memset(&rate_ctrl, 0, sizeof(rate_ctrl)); + memset(&bitrate, 0, sizeof(bitrate)); + memset(&intra_period, 0, sizeof(intra_period)); + memset(&codec_profile, 0, sizeof(codec_profile)); + memset(&set_param, 0, sizeof(set_param)); + memset(&time_inc, 0, sizeof(time_inc)); + memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property)); + memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property)); + memset(&session_qp, 0, sizeof(session_qp)); + memset(&entropy, 0, sizeof(entropy)); + memset(&dbkfilter, 0, sizeof(dbkfilter)); + memset(&intra_refresh, 0, sizeof(intra_refresh)); + memset(&hec, 0, sizeof(hec)); + memset(&voptimecfg, 0, sizeof(voptimecfg)); + memset(&capability, 0, sizeof(capability)); +} + +venc_dev::~venc_dev() +{ + //nothing to do +} + +void* venc_dev::async_venc_message_thread (void *input) +{ + struct venc_msg venc_msg; + omx_video* omx_venc_base = NULL; + omx_venc *omx = reinterpret_cast(input); + omx_venc_base = reinterpret_cast(input); + OMX_BUFFERHEADERTYPE* omxhdr = NULL; + + prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + struct pollfd pfd; + struct v4l2_buffer v4l2_buf; + struct v4l2_event dqevent; + pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; + pfd.fd = omx->handle->m_nDriver_fd; + int error_code = 0,rc=0; + + memset(&v4l2_buf, 0, sizeof(v4l2_buf)); + while(1) + { + pthread_mutex_lock(&omx->handle->pause_resume_mlock); + if (omx->handle->paused) { + venc_msg.msgcode = VEN_MSG_PAUSE; + venc_msg.statuscode = VEN_S_SUCCESS; + if(omx->async_message_process(input, &venc_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Failed to process pause msg"); + pthread_mutex_unlock(&omx->handle->pause_resume_mlock); + break; + } + + /* Block here until the IL client resumes us again */ + pthread_cond_wait(&omx->handle->pause_resume_cond, + &omx->handle->pause_resume_mlock); + + venc_msg.msgcode = VEN_MSG_RESUME; + venc_msg.statuscode = VEN_S_SUCCESS; + if(omx->async_message_process(input, &venc_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Failed to process resume msg"); + pthread_mutex_unlock(&omx->handle->pause_resume_mlock); + break; + } + } + pthread_mutex_unlock(&omx->handle->pause_resume_mlock); + + rc = poll(&pfd, 1, POLL_TIMEOUT); + if (!rc) { + DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d\n", + omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd); + continue; + } else if (rc < 0) { + DEBUG_PRINT_ERROR("Error while polling: %d\n", rc); + break; + } + + if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + v4l2_buf.memory = V4L2_MEMORY_USERPTR; + v4l2_buf.length = omx->handle->num_planes; + v4l2_buf.m.planes = plane; + while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { + venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE; + venc_msg.statuscode=VEN_S_SUCCESS; + omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index; + venc_msg.buf.len= v4l2_buf.m.planes->bytesused; + venc_msg.buf.offset = 0; + venc_msg.buf.flags = 0; + venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer; + venc_msg.buf.clientdata=(void*)omxhdr; + venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec; + /* TODO: ideally report other types of frames as well + * for now it doesn't look like IL client cares about + * other types + */ + if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) + venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR; + if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) + venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME; + if(v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG) + venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG; + if(v4l2_buf.flags & V4L2_BUF_FLAG_EOS) + venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS; + if(omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused) + venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA; + omx->handle->fbd++; + if(omx->async_message_process(input,&venc_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); + break; + } + } + } + if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { + v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + v4l2_buf.memory = V4L2_MEMORY_USERPTR; + v4l2_buf.m.planes = plane; + v4l2_buf.length = 1; + while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { + venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE; + venc_msg.statuscode=VEN_S_SUCCESS; + omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index; + venc_msg.buf.clientdata=(void*)omxhdr; + omx->handle->ebd++; + if(omx->async_message_process(input,&venc_msg) < 0) + { + DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); + break; + } + } + } + if (pfd.revents & POLLPRI) { + rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); + if(dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { + DEBUG_PRINT_HIGH("CLOSE DONE\n"); + break; + } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { + venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE; + venc_msg.statuscode = VEN_S_SUCCESS; + if (omx->async_message_process(input,&venc_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); + break; + } + venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE; + venc_msg.statuscode = VEN_S_SUCCESS; + if (omx->async_message_process(input,&venc_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); + break; + } + } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){ + DEBUG_PRINT_ERROR("\n HW Error recieved \n"); + venc_msg.statuscode=VEN_S_EFAIL; + if (omx->async_message_process(input,&venc_msg) < 0) { + DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); + break; + } + } + } + } + DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n"); + return NULL; +} + +static const int event_type[] = { + V4L2_EVENT_MSM_VIDC_FLUSH_DONE, + V4L2_EVENT_MSM_VIDC_CLOSE_DONE, + V4L2_EVENT_MSM_VIDC_SYS_ERROR +}; + +static OMX_ERRORTYPE subscribe_to_events(int fd) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_event_subscription sub; + int array_sz = sizeof(event_type)/sizeof(int); + int i,rc; + memset(&sub, 0, sizeof(sub)); + if (fd < 0) { + printf("Invalid input: %d\n", fd); + return OMX_ErrorBadParameter; + } + + for (i = 0; i < array_sz; ++i) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); + if (rc) { + printf("Failed to subscribe event: 0x%x\n", sub.type); + break; + } + } + if (i < array_sz) { + for (--i; i >=0 ; i--) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); + if (rc) + printf("Failed to unsubscribe event: 0x%x\n", sub.type); + } + eRet = OMX_ErrorNotImplemented; + } + return eRet; +} + +bool venc_dev::handle_extradata(void *buffer, int index) +{ + OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer; + OMX_OTHER_EXTRADATATYPE *p_extra = NULL; + if (!extradata_info.uaddr) { + DEBUG_PRINT_ERROR("Extradata buffers not allocated\n"); + return false; + } + p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned)(p_bufhdr->pBuffer + p_bufhdr->nOffset + p_bufhdr->nFilledLen + 3)&(~3)); + char *p_extradata = extradata_info.uaddr + index * extradata_info.buffer_size; + if ((OMX_U8*)p_extra > (p_bufhdr->pBuffer + p_bufhdr->nAllocLen)){ + DEBUG_PRINT_ERROR("Insufficient buffer size\n"); + p_extra = NULL; + return false; + } + memcpy(p_extra, p_extradata, extradata_info.buffer_size); + return true; +} + +int venc_dev::venc_set_format(int format) +{ + int rc = true; + if (format) + color_format = format; + else + { + color_format = 0; + rc = false; + } + return rc; +} + +OMX_ERRORTYPE venc_dev::allocate_extradata() +{ + if (extradata_info.allocated) { + DEBUG_PRINT_ERROR("2nd allocation return"); + return OMX_ErrorNone; + } +#ifdef USE_ION + if (extradata_info.buffer_size) { + if (extradata_info.ion.ion_alloc_data.handle) { + munmap((void *)extradata_info.uaddr, extradata_info.size); + close(extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&extradata_info.ion); + } + extradata_info.size = (extradata_info.size + 4095) & (~4095); + + extradata_info.ion.ion_device_fd = alloc_map_ion_memory( + extradata_info.size, + &extradata_info.ion.ion_alloc_data, + &extradata_info.ion.fd_ion_data, 0); + if (extradata_info.ion.ion_device_fd < 0) { + DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n"); + return OMX_ErrorInsufficientResources; + } + extradata_info.uaddr = (char *)mmap(NULL, + extradata_info.size, + PROT_READ|PROT_WRITE, MAP_SHARED, + extradata_info.ion.fd_ion_data.fd , 0); + if (extradata_info.uaddr == MAP_FAILED) { + DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); + close(extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&extradata_info.ion); + return OMX_ErrorInsufficientResources; + } + } +#endif + extradata_info.allocated = 1; + return OMX_ErrorNone; +} + +void venc_dev::free_extradata() { +#ifdef USE_ION + if (extradata_info.uaddr) { + munmap((void *)extradata_info.uaddr, extradata_info.size); + close(extradata_info.ion.fd_ion_data.fd); + free_ion_memory(&extradata_info.ion); + } + memset(&extradata_info, 0, sizeof(extradata_info)); +#endif +} + +bool venc_dev::venc_open(OMX_U32 codec) +{ + int r; + unsigned int alignment = 0,buffer_size = 0, temp =0; + struct v4l2_control control; + OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc"; + + char platform_name[64]; + property_get("ro.board.platform", platform_name, "0"); + if (!strncmp(platform_name, "msm8610", 7)) { + device_name = (OMX_STRING)"/dev/video/q6_enc"; + } + + m_nDriver_fd = open (device_name, O_RDWR); + if(m_nDriver_fd == 0) + { + DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n"); + m_nDriver_fd = open (device_name, O_RDWR); + } + + if((int)m_nDriver_fd < 0) + { + DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n"); + return false; + } + + DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd); + // set the basic configuration of the video encoder driver + m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; + m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; + m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; + m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; + m_sVenc_cfg.fps_num = 30; + m_sVenc_cfg.fps_den = 1; + m_sVenc_cfg.targetbitrate = 64000; + m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12; + if(codec == OMX_VIDEO_CodingMPEG4) + { + m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4; + codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; + profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; +#ifdef OUTPUT_BUFFER_LOG + strcat(outputfilename, "m4v"); +#endif + } + else if(codec == OMX_VIDEO_CodingH263) + { + m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263; + codec_profile.profile = VEN_PROFILE_H263_BASELINE; + profile_level.level = VEN_LEVEL_H263_20; +#ifdef OUTPUT_BUFFER_LOG + strcat(outputfilename, "263"); +#endif + } + if(codec == OMX_VIDEO_CodingAVC) + { + m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264; + codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; + profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; +#ifdef OUTPUT_BUFFER_LOG + strcat(outputfilename, "264"); +#endif + } +if (codec == OMX_VIDEO_CodingVPX) + { + m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8; + codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; + profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; +#ifdef OUTPUT_BUFFER_LOG + strcat(outputfilename, "ivf"); +#endif + } +#ifdef INPUT_BUFFER_LOG + inputBufferFile1 = fopen (inputfilename, "ab"); + if (!inputBufferFile1) + DEBUG_PRINT_ERROR("Input File open failed"); +#endif +#ifdef OUTPUT_BUFFER_LOG + outputBufferFile1 = fopen (outputfilename, "ab"); +#endif + int ret; + ret = subscribe_to_events(m_nDriver_fd); + if (ret) { + DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n"); + return false; + } + struct v4l2_capability cap; + struct v4l2_fmtdesc fdesc; + struct v4l2_format fmt; + struct v4l2_requestbuffers bufreq; + + ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap); + if (ret) { + DEBUG_PRINT_ERROR("Failed to query capabilities\n"); + } else { + DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s," + " version = %d, capabilities = %x\n", cap.driver, cap.card, + cap.bus_info, cap.version, cap.capabilities); + } + ret=0; + fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fdesc.index=0; + while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { + DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, + fdesc.pixelformat, fdesc.flags); + fdesc.index++; + } + fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fdesc.index=0; + while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { + DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, + fdesc.pixelformat, fdesc.flags); + fdesc.index++; + } + + m_sOutput_buff_property.alignment=m_sInput_buff_property.alignment=4096; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; + + /*TODO: Return values not handled properly in this function anywhere. + * Need to handle those.*/ + ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); + if (ret) { + DEBUG_PRINT_ERROR("Failed to set format on capture port\n"); + return false; + } + m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; + + ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); + m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = 2; + + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); + m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; + + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + bufreq.count = 2; + ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); + m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; + + + stopped = 0; + metadatamode = 0; + + control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; + control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; + + DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d\n", control.id, control.value); + if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) + DEBUG_PRINT_ERROR("Failed to set control\n"); + + struct v4l2_frmsizeenum frmsize; + + //Get the hardware capabilities + memset((void *)&frmsize,0,sizeof(frmsize)); + frmsize.index = 0; + frmsize.pixel_format = m_sVenc_cfg.codectype; + ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize); + if(ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { + DEBUG_PRINT_ERROR("Failed to get framesizes\n"); + return false; + } + + if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { + capability.min_width = frmsize.stepwise.min_width; + capability.max_width = frmsize.stepwise.max_width; + capability.min_height = frmsize.stepwise.min_height; + capability.max_height = frmsize.stepwise.max_height; + } + + return true; +} + + +static OMX_ERRORTYPE unsubscribe_to_events(int fd) +{ + OMX_ERRORTYPE eRet = OMX_ErrorNone; + struct v4l2_event_subscription sub; + int array_sz = sizeof(event_type)/sizeof(int); + int i,rc; + if (fd < 0) { + printf("Invalid input: %d\n", fd); + return OMX_ErrorBadParameter; + } + + for (i = 0; i < array_sz; ++i) { + memset(&sub, 0, sizeof(sub)); + sub.type = event_type[i]; + rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); + if (rc) { + printf("Failed to unsubscribe event: 0x%x\n", sub.type); + break; + } + } + return eRet; +} + +void venc_dev::venc_close() +{ + struct v4l2_encoder_cmd enc; + DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd); + if((int)m_nDriver_fd >= 0) + { + enc.cmd = V4L2_ENC_CMD_STOP; + ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc); + DEBUG_PRINT_HIGH("venc_close E\n"); + if (async_thread_created) + pthread_join(m_tid,NULL); + DEBUG_PRINT_HIGH("venc_close X\n"); + unsubscribe_to_events(m_nDriver_fd); + close(m_nDriver_fd); + m_nDriver_fd = -1; + } +#ifdef INPUT_BUFFER_LOG + fclose (inputBufferFile1); +#endif +#ifdef OUTPUT_BUFFER_LOG + fclose (outputBufferFile1); +#endif +} + +bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count, + unsigned long *actual_buff_count, + unsigned long *buff_size, + unsigned long port) +{ + + unsigned long temp_count = 0; + + if(port == 0) + { + if(*actual_buff_count > m_sInput_buff_property.mincount) + { + temp_count = m_sInput_buff_property.actualcount; + m_sInput_buff_property.actualcount = *actual_buff_count; + DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count); + } + } + else + { + if(*actual_buff_count > m_sOutput_buff_property.mincount) + { + temp_count = m_sOutput_buff_property.actualcount; + m_sOutput_buff_property.actualcount = *actual_buff_count; + DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count); + } + } + + return true; + +} + +bool venc_dev::venc_loaded_start() +{ + return true; +} + +bool venc_dev::venc_loaded_stop() +{ + return true; +} + +bool venc_dev::venc_loaded_start_done() +{ + return true; +} + +bool venc_dev::venc_loaded_stop_done() +{ + return true; +} + +bool venc_dev::venc_get_seq_hdr(void *buffer, + unsigned buffer_size, unsigned *header_len) +{ + return true; +} + +bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count, + unsigned long *actual_buff_count, + unsigned long *buff_size, + unsigned long port) +{ + struct v4l2_format fmt; + struct v4l2_requestbuffers bufreq; + unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; + int ret; + if(port == 0) + { + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; + ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); + m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + bufreq.memory = V4L2_MEMORY_USERPTR; + if (*actual_buff_count) + bufreq.count = *actual_buff_count; + else + bufreq.count = 2; + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); + if (ret) { + DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n "); + return false; + } + m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; + *min_buff_count = m_sInput_buff_property.mincount; + *actual_buff_count = m_sInput_buff_property.actualcount; +#ifdef USE_ION +// For ION memory allocations of the allocated buffer size +// must be 4k aligned, hence aligning the input buffer +// size to 4k. + m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095) & (~4095); +#endif + *buff_size = m_sInput_buff_property.datasize; + } + else + { + int extra_idx = 0; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; + + ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); + m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; + + ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); + m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + bufreq.memory = V4L2_MEMORY_USERPTR; + if (*actual_buff_count) + bufreq.count = *actual_buff_count; + else + bufreq.count = 2; + bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); + if (ret) { + DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS CAPTURE_MPLANE Failed \n "); + return false; + } + m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; + *min_buff_count = m_sOutput_buff_property.mincount; + *actual_buff_count = m_sOutput_buff_property.actualcount; + *buff_size = m_sOutput_buff_property.datasize; + num_planes = fmt.fmt.pix_mp.num_planes; + extra_idx = EXTRADATA_IDX(num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + extradata_info.buffer_size = extra_data_size; + extradata_info.count = m_sOutput_buff_property.actualcount; + extradata_info.size = extradata_info.buffer_size * extradata_info.count; + } + return true; +} + +bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) +{ + DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n"); + struct v4l2_format fmt; + struct v4l2_requestbuffers bufreq; + int ret; + switch(index) + { + case OMX_IndexParamPortDefinition: + { + OMX_PARAM_PORTDEFINITIONTYPE *portDefn; + portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n"); + if(portDefn->nPortIndex == PORT_INDEX_IN) + { + if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) + { + return false; + } + if(!venc_set_color_format(portDefn->format.video.eColorFormat)) + { + return false; + } + if(m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight || + m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) + { + DEBUG_PRINT_LOW("\n Basic parameter has changed"); + m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; + m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; + if(ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { + DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT OUTPUT_MPLANE Failed \n "); + return false; + } + m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = portDefn->nBufferCountActual; + bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { + DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n "); + return false; + } + if(bufreq.count == portDefn->nBufferCountActual) + m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; + if(portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) + m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; + } + DEBUG_PRINT_LOW("input: actual: %d, min: %d, count_req: %d\n", + portDefn->nBufferCountActual, m_sInput_buff_property.mincount, bufreq.count); + } + else if(portDefn->nPortIndex == PORT_INDEX_OUT) + { + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; + if(ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { + DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT CAPTURE_MPLANE Failed \n "); + return false; + } + m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; + + if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) + { + return false; + } + + if((portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) + && (m_sOutput_buff_property.datasize == portDefn->nBufferSize)) + { + m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; + bufreq.memory = V4L2_MEMORY_USERPTR; + bufreq.count = portDefn->nBufferCountActual; + bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer count failed: requested: %lu, current: %lu", + portDefn->nBufferCountActual, m_sOutput_buff_property.actualcount); + return false; + } + if(bufreq.count == portDefn->nBufferCountActual) + m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; + if(portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) + m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; + if (num_planes > 1) + extradata_info.count = m_sOutput_buff_property.actualcount; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed"); + return false; + } + DEBUG_PRINT_LOW("Output: actual: %d, min: %d, count_req: %d\n", + portDefn->nBufferCountActual, m_sOutput_buff_property.mincount, bufreq.count); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); + } + break; + } + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; + portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n"); + + if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) + { + if(!venc_set_color_format(portFmt->eColorFormat)) + { + return false; + } + } + else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(!venc_set_encode_framerate(portFmt->xFramerate, 0)) + { + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); + } + break; + } + case OMX_IndexParamVideoBitrate: + { + OMX_VIDEO_PARAM_BITRATETYPE* pParam; + pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n"); + + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) + { + DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed"); + return false; + } + if(!venc_set_ratectrl_cfg(pParam->eControlRate)) + { + DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); + } + break; + } + case OMX_IndexParamVideoMpeg4: + { + OMX_VIDEO_PARAM_MPEG4TYPE* pParam; + OMX_U32 bFrames = 0; + + pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n"); + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(!venc_set_voptiming_cfg(pParam->nTimeIncRes)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed"); + return false; + } + m_profile_set = false; + m_level_set = false; + if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); + return false; + } + else { + if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + bFrames = 1; + } + } + else + { + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + bFrames = 0; + } + } + } + if(!venc_set_intra_period (pParam->nPFrames,bFrames)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); + } + break; + } + case OMX_IndexParamVideoH263: + { + OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n"); + OMX_U32 bFrames = 0; + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + m_profile_set = false; + m_level_set = false; + if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); + return false; + } + if (pParam->nBFrames) + DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263"); + + if(venc_set_intra_period (pParam->nPFrames, bFrames) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263"); + } + break; + } + case OMX_IndexParamVideoAvc: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n"); + OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; + OMX_U32 bFrames = 0; + + if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n", + pParam->eProfile,pParam->eLevel); + + m_profile_set = false; + m_level_set = false; + + if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) + { + DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d", + pParam->eProfile, pParam->eLevel); + return false; + } + else { + if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) + { + if(pParam->nBFrames) + { + DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); + bFrames = 1; + } + } + else + { + if(pParam->nBFrames) + { + DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); + bFrames = 0; + } + } + } + if(!venc_set_intra_period (pParam->nPFrames, bFrames)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed"); + return false; + } + if(!venc_set_inloop_filter (pParam->eLoopFilterMode)) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed"); + return false; + } + if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) + { + DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); + } + //TBD, lot of other variables to be updated, yet to decide + break; + } + case OMX_IndexParamVideoIntraRefresh: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n"); + OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = + (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; + if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); + } + break; + } + case OMX_IndexParamVideoErrorCorrection: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n"); + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = + (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; + if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_error_resilience(error_resilience) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); + } + break; + } + case OMX_IndexParamVideoProfileLevelCurrent: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n"); + OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = + (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; + if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + m_profile_set = false; + m_level_set = false; + if(!venc_set_profile_level (profile_level->eProfile, + profile_level->eLevel)) + { + DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); + } + break; + } + case OMX_IndexParamVideoQuantization: + { + DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n"); + OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = + (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; + if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_session_qp (session_qp->nQpI, + session_qp->nQpP, + session_qp->nQpB) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); + } + break; + } + case OMX_QcomIndexEnableSliceDeliveryMode: + { + QOMX_EXTNINDEX_PARAMTYPE* pParam = + (QOMX_EXTNINDEX_PARAMTYPE*)paramData; + if(pParam->nPortIndex == PORT_INDEX_OUT) + { + if(venc_set_slice_delivery_mode(pParam->bEnable) == false) + { + DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); + return OMX_ErrorUnsupportedSetting; + } + } + else + { + DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " + "called on wrong port(%d)", pParam->nPortIndex); + return OMX_ErrorBadPortIndex; + } + break; + } + case OMX_ExtraDataVideoEncoderSliceInfo: + { + DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); + OMX_U32 extra_data = *(OMX_U32 *)paramData; + if(venc_set_extradata(extra_data) == false) + { + DEBUG_PRINT_ERROR("ERROR: Setting " + "OMX_ExtraDataVideoEncoderSliceInfo failed"); + return false; + } + extradata = true; + break; + } + case OMX_IndexParamVideoSliceFMO: + default: + DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u", + index); + break; + //case + } + + return true; +} + +bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) +{ + + DEBUG_PRINT_LOW("\n Inside venc_set_config"); + + switch(index) + { + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) + configData; + DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate"); + if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); + } + break; + } + case OMX_IndexConfigVideoFramerate: + { + OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) + configData; + DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate"); + if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); + } + break; + } + case QOMX_IndexConfigVideoIntraperiod: + { + DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n"); + QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = + (QOMX_VIDEO_INTRAPERIODTYPE *)configData; + if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) + { + if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + } + break; + } + case OMX_IndexConfigVideoIntraVOPRefresh: + { + OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) + configData; + DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); + if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) + { + if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) + { + DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); + } + break; + } + case OMX_IndexConfigCommonRotate: + { + OMX_CONFIG_ROTATIONTYPE *config_rotation = + reinterpret_cast(configData); + OMX_U32 nFrameWidth; + + DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims"); + nFrameWidth = m_sVenc_cfg.input_width; + m_sVenc_cfg.input_width = m_sVenc_cfg.input_height; + m_sVenc_cfg.input_height = nFrameWidth; + if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < */0) { + DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed"); + return false; + } + break; + } + case OMX_IndexConfigVideoAVCIntraPeriod: + { + OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData; + DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod"); + if(venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod) + == false) + { + DEBUG_PRINT_ERROR("ERROR: Setting " + "OMX_IndexConfigVideoAVCIntraPeriod failed"); + return false; + } + break; + } + default: + DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index); + break; + } + + return true; +} + +unsigned venc_dev::venc_stop( void) +{ + struct venc_msg venc_msg; + int rc = 0; + if(!stopped) { + enum v4l2_buf_type cap_type; + if (streaming[OUTPUT_PORT]) { + cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); + if (rc) { + DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n", + cap_type, rc); + } else + streaming[OUTPUT_PORT] = false; + } + if (!rc && streaming[CAPTURE_PORT]) { + cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); + if (rc) { + DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n", + cap_type, rc); + } else + streaming[CAPTURE_PORT] = false; + } + if (!rc) { + venc_stop_done(); + stopped = 1; + } + } + return rc; +} + +unsigned venc_dev::venc_pause(void) +{ + pthread_mutex_lock(&pause_resume_mlock); + paused = true; + pthread_mutex_unlock(&pause_resume_mlock); + return 0; +} + +unsigned venc_dev::venc_resume(void) +{ + pthread_mutex_lock(&pause_resume_mlock); + paused = false; + pthread_mutex_unlock(&pause_resume_mlock); + + return pthread_cond_signal(&pause_resume_cond); +} + +unsigned venc_dev::venc_start_done(void) +{ + struct venc_msg venc_msg; + venc_msg.msgcode = VEN_MSG_START; + venc_msg.statuscode = VEN_S_SUCCESS; + venc_handle->async_message_process(venc_handle,&venc_msg); + return 0; +} + +unsigned venc_dev::venc_stop_done(void) +{ + struct venc_msg venc_msg; + free_extradata(); + venc_msg.msgcode=VEN_MSG_STOP; + venc_msg.statuscode=VEN_S_SUCCESS; + venc_handle->async_message_process(venc_handle,&venc_msg); + return 0; +} + +unsigned venc_dev::venc_set_message_thread_id(pthread_t tid) +{ + async_thread_created = true; + m_tid=tid; + return 0; +} + + +unsigned venc_dev::venc_start(void) +{ + enum v4l2_buf_type buf_type; + int ret,r; + DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start", + __func__); + if (!venc_set_profile_level(0, 0)) + { + DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET", + __func__); + } + else + { + DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET", + __func__, codec_profile.profile, profile_level.level); + } + venc_config_print(); + /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */ + if (slice_mode.enable && multislice.mslice_size && + (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) { + DEBUG_PRINT_ERROR("slice_mode: %d, max slices (%d) should be less than (%d)\n", slice_mode.enable, + (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)/(256 * multislice.mslice_size), + MAX_SUPPORTED_SLICES_PER_FRAME); + return 1; + } + + buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); + ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type); + + if (ret) + return 1; + + streaming[CAPTURE_PORT] = true; + return 0; +} + +void venc_dev::venc_config_print() +{ + + DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %ld, Profile %ld, level : %ld", + m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level); + + DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %ld, Height:%ld, Fps: %ld", + m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, + m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld", + bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld", + session_qp.iframeqp, session_qp.pframqp,session_qp.bframqp); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld", + voptimecfg.voptime_resolution, multislice.mslice_mode, + multislice.mslice_size); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %ld", + entropy.longentropysel, entropy.cabacmodel); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld\n", + dbkfilter.db_mode, dbkfilter.slicealpha_offset, + dbkfilter.slicebeta_offset); + + DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld\n", + intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod); + +} + +unsigned venc_dev::venc_flush( unsigned port) +{ + struct v4l2_encoder_cmd enc; + DEBUG_PRINT_LOW("in %s", __func__); + + enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH; + enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE; + + if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) + { + DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", port); + return -1; + } + return 0; + +} + +//allocating I/P memory from pmem and register with the device + + +bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index) +{ + + struct pmem *pmem_tmp; + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + int rc = 0, extra_idx; + + pmem_tmp = (struct pmem *)buf_addr; + DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); + + if(port == PORT_INDEX_IN) + { + buf.index = index; + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].length = pmem_tmp->size; + plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; + plane[0].reserved[0] = pmem_tmp->fd; + plane[0].reserved[1] = 0; + plane[0].data_offset = pmem_tmp->offset; + buf.m.planes = plane; + buf.length = 1; + + rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); + if (rc) + DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n"); + } + else if(port == PORT_INDEX_OUT) + { + extra_idx = EXTRADATA_IDX(num_planes); + if ((num_planes > 1) && (extra_idx)) { + rc = allocate_extradata(); + if (rc) + DEBUG_PRINT_ERROR("Failed to allocate extradata: %d\n", rc); + } + buf.index = index; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].length = pmem_tmp->size; + plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; + plane[0].reserved[0] = pmem_tmp->fd; + plane[0].reserved[1] = 0; + plane[0].data_offset = pmem_tmp->offset; + buf.m.planes = plane; + buf.length = num_planes; + + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].length = extradata_info.buffer_size; + plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); + return OMX_ErrorBadParameter; + } + rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); + if (rc) + DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n"); + } else { + DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index "); + return false; + } + return true; +} + +bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) +{ + struct pmem *pmem_tmp; + struct venc_bufferpayload dev_buffer; + + memset(&dev_buffer, 0, sizeof(dev_buffer)); + pmem_tmp = (struct pmem *)buf_addr; + + if(port == PORT_INDEX_IN) + { + dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; + dev_buffer.fd = pmem_tmp->fd; + dev_buffer.maped_size = pmem_tmp->size; + dev_buffer.sz = pmem_tmp->size; + dev_buffer.offset = pmem_tmp->offset; + DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ + dev_buffer.pbuffer, \ + dev_buffer.fd, \ + dev_buffer.offset, \ + dev_buffer.maped_size); + + } + else if(port == PORT_INDEX_OUT) + { + dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; + dev_buffer.fd = pmem_tmp->fd; + dev_buffer.sz = pmem_tmp->size; + dev_buffer.maped_size = pmem_tmp->size; + dev_buffer.offset = pmem_tmp->offset; + + DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ + dev_buffer.pbuffer, \ + dev_buffer.fd, \ + dev_buffer.offset, \ + dev_buffer.maped_size); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index "); + return false; + } + return true; +} + +bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd) +{ + struct pmem *temp_buffer; + struct v4l2_buffer buf; + struct v4l2_plane plane; + int rc=0; + struct OMX_BUFFERHEADERTYPE *bufhdr; + encoder_media_buffer_type * meta_buf = NULL; + temp_buffer = (struct pmem *)buffer; + + memset (&buf, 0, sizeof(buf)); + memset (&plane, 0, sizeof(plane)); + if(buffer == NULL) + { + DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL"); + return false; + } + bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; + + DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen); + if(pmem_data_buf) + { + DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); + plane.m.userptr = (unsigned long)pmem_data_buf; + plane.data_offset = bufhdr->nOffset; + plane.length = bufhdr->nAllocLen; + plane.bytesused = bufhdr->nFilledLen; + } + else + { + DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); + if (metadatamode && !color_format) { // meta Buffer + Camera buffers + meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer; + if (!meta_buf) + return false; + plane.m.userptr = index; + plane.data_offset = meta_buf->meta_handle->data[1]; + plane.length = meta_buf->meta_handle->data[2]; + plane.bytesused = meta_buf->meta_handle->data[2]; + } + else + { // meta Buffer + Gralloc buffers || pmem buffers + plane.m.userptr = (unsigned long) bufhdr->pBuffer; + plane.data_offset = bufhdr->nOffset; + plane.length = bufhdr->nAllocLen; + plane.bytesused = bufhdr->nFilledLen; + } + } + + buf.index = index; + buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane.reserved[0] = fd; + plane.reserved[1] = 0; + buf.m.planes = &plane; + buf.length = 1; + if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) + buf.flags = V4L2_BUF_FLAG_EOS; + buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000; + buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000); + rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); + if (rc) { + DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver"); + return false; + } + etb++; + if(!streaming[OUTPUT_PORT]) + { + enum v4l2_buf_type buf_type; + buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + int ret; + ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type); + if (ret) { + DEBUG_PRINT_ERROR("Failed to call streamon\n"); + return false; + } else { + streaming[OUTPUT_PORT] = true; + } +} +#ifdef INPUT_BUFFER_LOG + int i; + int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width); + int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height); + char *temp = (char *)bufhdr->pBuffer; + for (i = 0; i < m_sVenc_cfg.input_height; i++) { + fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1); + temp += stride; + } + temp = (char *)bufhdr->pBuffer + (stride * scanlines); + for(i = 0; i < m_sVenc_cfg.input_height/2; i++) { + fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1); + temp += stride; + } +#endif + return true; +} +bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) +{ + struct pmem *temp_buffer = NULL; + struct venc_buffer frameinfo; + struct v4l2_buffer buf; + struct v4l2_plane plane[VIDEO_MAX_PLANES]; + int rc = 0, extra_idx; + struct OMX_BUFFERHEADERTYPE *bufhdr; + + if(buffer == NULL) + return false; + + bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; + + if(pmem_data_buf) + { + DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); + plane[0].m.userptr = (unsigned long)pmem_data_buf; + } else { + DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); + plane[0].m.userptr = (unsigned long)bufhdr->pBuffer; + } + + buf.index = index; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + buf.memory = V4L2_MEMORY_USERPTR; + plane[0].length = bufhdr->nAllocLen; + plane[0].bytesused = bufhdr->nFilledLen; + plane[0].reserved[0] = fd; + plane[0].reserved[1] = 0; + plane[0].data_offset = bufhdr->nOffset; + buf.m.planes = plane; + buf.length = num_planes; + + extra_idx = EXTRADATA_IDX(num_planes); + if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { + plane[extra_idx].bytesused = 0; + plane[extra_idx].length = extradata_info.buffer_size; + plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); +#ifdef USE_ION + plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; +#endif + plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; + plane[extra_idx].data_offset = 0; + } else if (extra_idx >= VIDEO_MAX_PLANES) { + DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); + return false; + } + rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); + if (rc) { + DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver"); + return false; + } + ftb++; + return true; +} + +bool venc_dev::venc_set_extradata(OMX_U32 extra_data) +{ + struct v4l2_control control; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; + control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO; + DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data); + if(multislice.mslice_mode && multislice.mslice_mode != V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) + { + if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed"); + return false; + } + } + else + { + DEBUG_PRINT_ERROR("Failed to set slice extradata, slice_mode " + "is set to [%lu]", multislice.mslice_mode); + } + return true; +} + +bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable) +{ + struct v4l2_control control; + if (enable) { + control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE; + control.value = 1; + DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value); + if(multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) + { + if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { + DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); + return false; + } + else { + DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d\n", control.id, control.value); + slice_mode.enable = 1; + } + } + else + { + DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%d] " + "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode, + m_sVenc_cfg.codectype); + } + } + else + { + DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled\n"); + } + return true; +} + +bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp) +{ + int rc; + struct v4l2_control control; + + control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP; + control.value = i_frame_qp; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + session_qp.iframeqp = control.value; + + control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP; + control.value = p_frame_qp; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + session_qp.pframqp = control.value; + + if((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) || + (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) + { + + control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; + control.value = b_frame_qp; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + session_qp.bframqp = control.value; + } + + return true; +} + +bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) +{ + struct venc_profile requested_profile = {0}; + struct ven_profilelevel requested_level = {0}; + unsigned long mb_per_frame = 0; + DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d", + eProfile, eLevel); + mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* + ((m_sVenc_cfg.input_width + 15) >> 4); + if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) + { + DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start"); + return true; + } + + DEBUG_PRINT_LOW("\n Validating Profile/Level from table"); + if(!venc_validate_profile_level(&eProfile, &eLevel)) + { + DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed"); + return false; + } + + if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) + { + DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and " + "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile, + OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); + if(eProfile == OMX_VIDEO_MPEG4ProfileSimple) + { + requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; + } + else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { + requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE; + } + else + { + DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u", + eProfile); + return false; + } + + DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," + "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," + "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, + OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); + + if(mb_per_frame >= 3600) + { + if(requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; + if(requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; + } + else + { + switch(eLevel) + { + case OMX_VIDEO_MPEG4Level0: + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0; + break; + case OMX_VIDEO_MPEG4Level0b: + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B; + break; + case OMX_VIDEO_MPEG4Level1: + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1; + break; + case OMX_VIDEO_MPEG4Level2: + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; + break; + case OMX_VIDEO_MPEG4Level3: + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3; + break; + case OMX_VIDEO_MPEG4Level4a: + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4; + break; + case OMX_VIDEO_MPEG4Level5: + requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; + break; + default: + return false; + // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 + break; + } + } + } + else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) + { + + switch (eProfile) { + case OMX_VIDEO_H263ProfileBaseline: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE; + break; + case OMX_VIDEO_H263ProfileH320Coding: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING; + break; + case OMX_VIDEO_H263ProfileBackwardCompatible: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE; + break; + case OMX_VIDEO_H263ProfileISWV2: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2; + break; + case OMX_VIDEO_H263ProfileISWV3: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3; + break; + case OMX_VIDEO_H263ProfileHighCompression: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION; + break; + case OMX_VIDEO_H263ProfileInternet: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET; + break; + case OMX_VIDEO_H263ProfileInterlace: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE; + break; + case OMX_VIDEO_H263ProfileHighLatency: + requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY; + break; + default: + DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u", + requested_profile.profile); + return false; + } + //profile level + switch(eLevel) + { + case OMX_VIDEO_H263Level10: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0; + break; + case OMX_VIDEO_H263Level20: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0; + break; + case OMX_VIDEO_H263Level30: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0; + break; + case OMX_VIDEO_H263Level40: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0; + break; + case OMX_VIDEO_H263Level45: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5; + break; + case OMX_VIDEO_H263Level50: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0; + break; + case OMX_VIDEO_H263Level60: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0; + break; + case OMX_VIDEO_H263Level70: + requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0; + break; + default: + return false; + break; + } + } + else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) + { + if(eProfile == OMX_VIDEO_AVCProfileBaseline) + { + requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; + } + else if(eProfile == OMX_VIDEO_AVCProfileMain) + { + requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN; + } + else if(eProfile == OMX_VIDEO_AVCProfileExtended) + { + requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED; + } + else if(eProfile == OMX_VIDEO_AVCProfileHigh) + { + requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; + } + else if(eProfile == OMX_VIDEO_AVCProfileHigh10) + { + requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10; + } + else if(eProfile == OMX_VIDEO_AVCProfileHigh422) + { + requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422; + } + else if(eProfile == OMX_VIDEO_AVCProfileHigh444) + { + requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE; + } + else + { + DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u", + requested_profile.profile); + return false; + } + //profile level + switch(eLevel) + { + case OMX_VIDEO_AVCLevel1: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; + break; + case OMX_VIDEO_AVCLevel1b: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B; + break; + case OMX_VIDEO_AVCLevel11: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1; + break; + case OMX_VIDEO_AVCLevel12: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2; + break; + case OMX_VIDEO_AVCLevel13: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3; + break; + case OMX_VIDEO_AVCLevel2: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0; + break; + case OMX_VIDEO_AVCLevel21: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1; + break; + case OMX_VIDEO_AVCLevel22: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2; + break; + case OMX_VIDEO_AVCLevel3: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0; + break; + case OMX_VIDEO_AVCLevel31: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1; + break; + case OMX_VIDEO_AVCLevel32: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2; + break; + case OMX_VIDEO_AVCLevel4: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; + break; + case OMX_VIDEO_AVCLevel41: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1; + break; + case OMX_VIDEO_AVCLevel42: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2; + break; + case OMX_VIDEO_AVCLevel5: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0; + break; + case OMX_VIDEO_AVCLevel51: + requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1; + break; + default : + DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %lu", + requested_level.level); + return false; + break; + } + } + if(!m_profile_set) + { + int rc; + struct v4l2_control control; + if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { + control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; + } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { + control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE; + } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE; + } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { + DEBUG_PRINT_ERROR("\n No Profile and LEVEL Setting for VP8 \n"); + m_profile_set = true; + m_level_set = true; + return true; + } else { + DEBUG_PRINT_ERROR("\n Wrong CODEC \n"); + return false; + } + + control.value = requested_profile.profile; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + codec_profile.profile = control.value; + m_profile_set = true; + } + + if(!m_level_set) + { + int rc; + struct v4l2_control control; + if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { + control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; + } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { + control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL; + } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { + control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL; + } else { + DEBUG_PRINT_ERROR("\n Wrong CODEC \n"); + return false; + } + + control.value = requested_level.level; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + profile_level.level = control.value; + m_level_set = true; + } + + return true; +} + +bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) +{ + + struct venc_voptimingcfg vop_timing_cfg; + + DEBUG_PRINT_LOW("\n venc_set_voptiming_cfg: TimeRes = %u", + TimeIncRes); + + vop_timing_cfg.voptime_resolution = TimeIncRes; + + voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; + return true; +} + +bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) +{ + + DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u", + nPFrames); + int rc; + struct v4l2_control control; + if((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) && + (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && + (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) + { + nBFrames=0; + } + + control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; + control.value = nPFrames; + + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + intra_period.num_pframes = control.value; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES; + control.value = nBFrames; + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + + intra_period.num_bframes = control.value; + if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264){ + control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; + control.value = 1; + + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + idrperiod.idrperiod = 1; + } + return true; +} + +bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod) +{ + int rc = 0; + struct v4l2_control control; + DEBUG_PRINT_LOW("\n venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u\n", + nPFrames, nIDRPeriod); + + if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264){ + DEBUG_PRINT_ERROR("\nERROR: IDR period valid for H264 only!!"); + return false; + } + + if(venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) { + DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); + return false; + } + + intra_period.num_pframes = nPFrames; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; + control.value = nIDRPeriod; + + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + + idrperiod.idrperiod = nIDRPeriod; + return true; +} + +bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) +{ + int rc = 0; + struct v4l2_control control; + + DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level); + + if(enable &&(codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE)){ + + control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC; + control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + entropy.longentropysel = control.value; + if (i_cabac_level == 0) { + control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0; + } + else if (i_cabac_level == 1) { + control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1; + } + else if (i_cabac_level == 2) { + control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2; + } + + control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL; + //control.value = entropy_cfg.cabacmodel; + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + entropy.longentropysel=control.value; + } + else if(!enable){ + control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; + control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + entropy.longentropysel=control.value; + } + else{ + DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile"); + return false; + } + + return true; +} + +bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB +{ + int rc; + struct v4l2_control control; + bool status = true; + + if((Codec != OMX_IndexParamVideoH263) && (nSlicesize)){ + control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB; + } + else{ + control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; + } + control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + multislice.mslice_mode=control.value; + + if(multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE){ + + control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; + control.value = nSlicesize; + DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + multislice.mslice_size=control.value; + + } + return status; +} + +bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) +{ + bool status = true; + int rc; + struct v4l2_control control_mode,control_mbs; + control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE; + // There is no disabled mode. Disabled mode is indicated by a 0 count. + if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) + { + control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE; + return status; + } + else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && + (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) + { + control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC; + control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS; + control_mbs.value=irMBs; + } + else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) && + (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) + { + control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE; + control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS; + control_mbs.value=irMBs; + } + else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) && + (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) + { + control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE; + } + else + { + DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:" + "mb count: %lu, mb mode:%d", irMBs, ir_mode); + return false; + } + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%lu, val=%lu\n", control_mode.id, control_mode.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mode.id, control_mode.value); + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control_mbs.id, control_mbs.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mbs.id, control_mbs.value); + + intra_refresh.irmode = control_mode.value; + intra_refresh.mbcount = control_mbs.value; + + return status; +} + +bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) +{ + bool status = true; + struct venc_headerextension hec_cfg; + struct venc_multiclicecfg multislice_cfg; + int rc; + struct v4l2_control control; + + memset(&control, 0, sizeof(control)); + if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { + if (error_resilience->bEnableHEC) { + hec_cfg.header_extension = 1; + } else { + hec_cfg.header_extension = 0; + } + hec.header_extension = error_resilience->bEnableHEC; + } + + if (error_resilience->bEnableRVLC) { + DEBUG_PRINT_ERROR("\n RVLC is not Supported"); + return false; + } + + if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && + (error_resilience->bEnableDataPartitioning)) { + DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264"); + return false; + } + + if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && + (error_resilience->nResynchMarkerSpacing)) { + multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; + multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; + control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; + control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES; + } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 && + error_resilience->bEnableDataPartitioning) { + multislice_cfg.mslice_mode = VEN_MSLICE_GOB; + multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; + control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; + control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB; + } else { + multislice_cfg.mslice_mode = VEN_MSLICE_OFF; + multislice_cfg.mslice_size = 0; + control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; + control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; + } + DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, + multislice_cfg.mslice_mode, multislice_cfg.mslice_size); + printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + printf("Failed to set Slice mode control\n"); + return false; + } + printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); + multislice.mslice_mode=control.value; + + control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; + control.value = error_resilience->nResynchMarkerSpacing; + printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + printf("Failed to set MAX MB control\n"); + return false; + } + printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); + multislice.mslice_mode = multislice_cfg.mslice_mode; + multislice.mslice_size = multislice_cfg.mslice_size; + return status; +} + +bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) +{ + int rc; + struct v4l2_control control; + control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE; + if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){ + control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED; + } + else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){ + control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED; + } + else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){ + control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY; + } + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + dbkfilter.db_mode=control.value; + + control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA; + control.value=0; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA; + control.value=0; + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + + dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; + return true; +} + +bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) +{ + DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u", + nTargetBitrate); + struct v4l2_control control; + int rc = 0; + control.id = V4L2_CID_MPEG_VIDEO_BITRATE; + control.value = nTargetBitrate; + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + + m_sVenc_cfg.targetbitrate = control.value; + bitrate.target_bitrate = control.value; + if(!config) + { + m_level_set = false; + if(venc_set_profile_level(0, 0)) + { + DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu\n",profile_level.level); + } + } + return true; +} + +bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) +{ + struct v4l2_streamparm parm; + int rc = 0; + struct venc_framerate frame_rate_cfg; + Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); + parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator; + parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator; + if(frame_rate_cfg.fps_numerator > 0) + rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm); + if (rc) { + DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed\n"); + return false; + } + m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; + m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; + if(!config) + { + m_level_set = false; + if(venc_set_profile_level(0, 0)) + { + DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu\n",profile_level.level); + } + } + return true; +} + +bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) +{ + struct v4l2_format fmt; + DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format); + + if(color_format == OMX_COLOR_FormatYUV420SemiPlanar) + { + m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; + } + else if(color_format == QOMX_COLOR_FormatYVU420SemiPlanar) + { + m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21; + } + else + { + DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format); + m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; + DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set"); + } + fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; + fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; + fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; + if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { + DEBUG_PRINT_ERROR("Failed setting color format %x", color_format); + return false; + } + + return true; +} + +bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) +{ + DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); + if(intra_vop_refresh == OMX_TRUE) + { + struct v4l2_control control; + int rc; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME; + control.value = 1; + printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + printf("Failed to set Intra Frame Request control\n"); + return false; + } + printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); + } + else + { + DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect"); + } + return true; +} + +bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) +{ + bool status = true; + struct v4l2_control control; + int rc = 0; + control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL; + switch(eControlRate) + { + case OMX_Video_ControlRateDisable: + control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF; + break; + case OMX_Video_ControlRateVariableSkipFrames: + control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR; + break; + case OMX_Video_ControlRateVariable: + control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR; + break; + case OMX_Video_ControlRateConstantSkipFrames: + control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR; + break; + case OMX_Video_ControlRateConstant: + control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR; + break; + default: + status = false; + break; + } + + if(status) + { + + DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); + rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); + if (rc) { + DEBUG_PRINT_ERROR("Failed to set control\n"); + return false; + } + DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); + + rate_ctrl.rcmode = control.value; + } + return status; +} + +bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) +{ + bool status = true; + if(eProfile == NULL || eLevel == NULL) + { + return false; + } + + if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) + { + switch(codec_profile.profile) + { + case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: + *eProfile = OMX_VIDEO_MPEG4ProfileSimple; + break; + case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: + *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + break; + default: + *eProfile = OMX_VIDEO_MPEG4ProfileMax; + status = false; + break; + } + + if(!status) + { + return status; + } + + //profile level + switch(profile_level.level) + { + case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0: + *eLevel = OMX_VIDEO_MPEG4Level0; + break; + case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B: + *eLevel = OMX_VIDEO_MPEG4Level0b; + break; + case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1: + *eLevel = OMX_VIDEO_MPEG4Level1; + break; + case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2: + *eLevel = OMX_VIDEO_MPEG4Level2; + break; + case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3: + *eLevel = OMX_VIDEO_MPEG4Level3; + break; + case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4: + *eLevel = OMX_VIDEO_MPEG4Level4; + break; + case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5: + *eLevel = OMX_VIDEO_MPEG4Level5; + break; + default: + *eLevel = OMX_VIDEO_MPEG4LevelMax; + status = false; + break; + } + } + else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) + { + if(codec_profile.profile == VEN_PROFILE_H263_BASELINE) + { + *eProfile = OMX_VIDEO_H263ProfileBaseline; + } + else + { + *eProfile = OMX_VIDEO_H263ProfileMax; + return false; + } + switch(profile_level.level) + { + case VEN_LEVEL_H263_10: + *eLevel = OMX_VIDEO_H263Level10; + break; + case VEN_LEVEL_H263_20: + *eLevel = OMX_VIDEO_H263Level20; + break; + case VEN_LEVEL_H263_30: + *eLevel = OMX_VIDEO_H263Level30; + break; + case VEN_LEVEL_H263_40: + *eLevel = OMX_VIDEO_H263Level40; + break; + case VEN_LEVEL_H263_45: + *eLevel = OMX_VIDEO_H263Level45; + break; + case VEN_LEVEL_H263_50: + *eLevel = OMX_VIDEO_H263Level50; + break; + case VEN_LEVEL_H263_60: + *eLevel = OMX_VIDEO_H263Level60; + break; + case VEN_LEVEL_H263_70: + *eLevel = OMX_VIDEO_H263Level70; + break; + default: + *eLevel = OMX_VIDEO_H263LevelMax; + status = false; + break; + } + } + else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) + { + switch(codec_profile.profile) + { + case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: + *eProfile = OMX_VIDEO_AVCProfileBaseline; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: + *eProfile = OMX_VIDEO_AVCProfileMain; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: + *eProfile = OMX_VIDEO_AVCProfileHigh; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: + *eProfile = OMX_VIDEO_AVCProfileExtended; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: + *eProfile = OMX_VIDEO_AVCProfileHigh10; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: + *eProfile = OMX_VIDEO_AVCProfileHigh422; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: + *eProfile = OMX_VIDEO_AVCProfileHigh444; + break; + default: + *eProfile = OMX_VIDEO_AVCProfileMax; + status = false; + break; + } + + if(!status) + { + return status; + } + + switch(profile_level.level) + { + case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: + *eLevel = OMX_VIDEO_AVCLevel1; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1B: + *eLevel = OMX_VIDEO_AVCLevel1b; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: + *eLevel = OMX_VIDEO_AVCLevel11; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: + *eLevel = OMX_VIDEO_AVCLevel12; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: + *eLevel = OMX_VIDEO_AVCLevel13; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: + *eLevel = OMX_VIDEO_AVCLevel2; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: + *eLevel = OMX_VIDEO_AVCLevel21; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: + *eLevel = OMX_VIDEO_AVCLevel22; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: + *eLevel = OMX_VIDEO_AVCLevel3; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: + *eLevel = OMX_VIDEO_AVCLevel31; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: + *eLevel = OMX_VIDEO_AVCLevel32; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: + *eLevel = OMX_VIDEO_AVCLevel4; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: + *eLevel = OMX_VIDEO_AVCLevel41; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: + *eLevel = OMX_VIDEO_AVCLevel42; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: + *eLevel = OMX_VIDEO_AVCLevel5; + break; + case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: + *eLevel = OMX_VIDEO_AVCLevel51; + break; + default : + *eLevel = OMX_VIDEO_AVCLevelMax; + status = false; + break; + } + } + return status; +} + +bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) +{ + OMX_U32 new_profile = 0, new_level = 0; + unsigned const int *profile_tbl = NULL; + OMX_U32 mb_per_frame, mb_per_sec; + bool profile_level_found = false; + + DEBUG_PRINT_LOW("\n Init profile table for respective codec"); + //validate the ht,width,fps,bitrate and set the appropriate profile and level + if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) + { + if(*eProfile == 0) + { + if(!m_profile_set) + { + *eProfile = OMX_VIDEO_MPEG4ProfileSimple; + } + else + { + switch(codec_profile.profile) + { + case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: + *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; + break; + case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: + *eProfile = OMX_VIDEO_MPEG4ProfileSimple; + break; + default: + DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); + return false; + } + } + } + + if(*eLevel == 0 && !m_level_set) + { + *eLevel = OMX_VIDEO_MPEG4LevelMax; + } + + if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple) + { + profile_tbl = (unsigned int const *)mpeg4_profile_level_table; + } + else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) + { + profile_tbl = (unsigned int const *) + (&mpeg4_profile_level_table[MPEG4_ASP_START]); + } + else + { + DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile); + return false; + } + } + else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) + { + if(*eProfile == 0) + { + if(!m_profile_set) + { + *eProfile = OMX_VIDEO_AVCProfileBaseline; + } + else + { + switch(codec_profile.profile) + { + case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: + *eProfile = OMX_VIDEO_AVCProfileBaseline; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: + *eProfile = OMX_VIDEO_AVCProfileMain; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: + *eProfile = OMX_VIDEO_AVCProfileExtended; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: + *eProfile = OMX_VIDEO_AVCProfileHigh; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: + *eProfile = OMX_VIDEO_AVCProfileHigh10; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: + *eProfile = OMX_VIDEO_AVCProfileHigh422; + break; + case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: + *eProfile = OMX_VIDEO_AVCProfileHigh444; + break; + default: + DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); + return false; + } + } + } + + if(*eLevel == 0 && !m_level_set) + { + *eLevel = OMX_VIDEO_AVCLevelMax; + } + + if(*eProfile == OMX_VIDEO_AVCProfileBaseline) + { + profile_tbl = (unsigned int const *)h264_profile_level_table; + } + else if(*eProfile == OMX_VIDEO_AVCProfileHigh) + { + profile_tbl = (unsigned int const *) + (&h264_profile_level_table[H264_HP_START]); + } + else if(*eProfile == OMX_VIDEO_AVCProfileMain) + { + profile_tbl = (unsigned int const *) + (&h264_profile_level_table[H264_MP_START]); + } + else + { + DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile); + return false; + } + } + else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) + { + if(*eProfile == 0) + { + if(!m_profile_set) + { + *eProfile = OMX_VIDEO_H263ProfileBaseline; + } + else + { + switch(codec_profile.profile) + { + case VEN_PROFILE_H263_BASELINE: + *eProfile = OMX_VIDEO_H263ProfileBaseline; + break; + default: + DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); + return false; + } + } + } + + if(*eLevel == 0 && !m_level_set) + { + *eLevel = OMX_VIDEO_H263LevelMax; + } + + if(*eProfile == OMX_VIDEO_H263ProfileBaseline) + { + profile_tbl = (unsigned int const *)h263_profile_level_table; + } + else + { + DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile); + return false; + } + } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { + DEBUG_PRINT_HIGH("Disregarding profile/level setting for VP8\n"); + return true; + } + else + { + DEBUG_PRINT_LOW("\n Invalid codec type"); + return false; + } + + mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* + ((m_sVenc_cfg.input_width + 15)>> 4); + + if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) + { + if(codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) + profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; + if(codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) + profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; + { + new_level = profile_level.level; + new_profile = codec_profile.profile; + return true; + } + } + + mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; + + do{ + if(mb_per_frame <= (unsigned int)profile_tbl[0]) + { + if(mb_per_sec <= (unsigned int)profile_tbl[1]) + { + if(m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) + { + new_level = (int)profile_tbl[3]; + new_profile = (int)profile_tbl[4]; + profile_level_found = true; + DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level); + break; + } + } + } + profile_tbl = profile_tbl + 5; + }while(profile_tbl[0] != 0); + + if (profile_level_found != true) + { + DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n"); + return false; + } + + if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) + || (*eLevel == OMX_VIDEO_H263LevelMax)) + { + *eLevel = new_level; + } + DEBUG_PRINT_HIGH("%s: Returning with eProfile = %lu" + "Level = %lu", __func__, *eProfile, *eLevel); + + return true; +} +#ifdef _ANDROID_ICS_ +bool venc_dev::venc_set_meta_mode(bool mode) +{ + metadatamode = 1; + return true; +} +#endif + +bool venc_dev::venc_is_video_session_supported(unsigned long width, + unsigned long height) +{ + if ((width * height < capability.min_width * capability.min_height) || + (width * height > capability.max_width * capability.max_height)) { + DEBUG_PRINT_ERROR( + "Unsupported video resolution WxH = (%d)x(%d) supported range = min (%d)x(%d) - max (%d)x(%d)\n", + width, height, capability.min_width, capability.min_height, + capability.max_width, capability.max_height); + return false; + } + DEBUG_PRINT_LOW("\n video session supported\n"); + return true; +} diff --git a/mm-video-v4l2/vidc/venc/test/camera_test.cpp b/mm-video-v4l2/vidc/venc/test/camera_test.cpp new file mode 100755 index 00000000..f5ae6dbe --- /dev/null +++ b/mm-video-v4l2/vidc/venc/test/camera_test.cpp @@ -0,0 +1,93 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "camera_test.h" +// #include "camera_class.h" + +EXTERN_C_START + +// static android::Camera* pCamera = NULL; + +int CameraTest_Initialize(int nFrameRate, + int nFrameWidth, + int nFrameHeight, + CameraPreviewCallback pfnPreviewCallback) +{ + int result = 0; + +// pCamera = new android::Camera; +// if (!pCamera) +// return 1; + +// pCamera->init_camera(nFrameWidth, +// nFrameHeight, +// nFrameRate, +// pfnPreviewCallback); + + return result; +} + +int CameraTest_Run() +{ + int result = 0; + +// if (pCamera) +// pCamera->startPreview(); +// else +// return 1; + + return result; +} + +int CameraTest_ReleaseFrame(void* pPhys, void* pVirt) +{ + int result = 0; + +// if (pCamera) +// pCamera->releaseFrame(pPhys, pVirt); +// else +// return 1; + + return result; +} + +int CameraTest_Exit() +{ + int result = 0; + +// if (pCamera) +// { +// pCamera->stopPreview(); +// delete pCamera; +// } +// pCamera = NULL; + + return result; +} + + +EXTERN_C_END diff --git a/mm-video-v4l2/vidc/venc/test/fb_test.c b/mm-video-v4l2/vidc/venc/test/fb_test.c new file mode 100755 index 00000000..6479a3e9 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/test/fb_test.c @@ -0,0 +1,48 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "fb_test.h" + +int FBTest_Initialize(int nFrameWidth, + int nFrameHeight) +{ + return 0; +} +int FBTest_DisplayImage(int nPmemFd, int nOffset) +{ + return 0; +} + +int FBTest_Exit() +{ + return 0; +} + +int FBTest_RunTest() +{ + return 0; +} diff --git a/mm-video-v4l2/vidc/venc/test/queue.c b/mm-video-v4l2/vidc/venc/test/queue.c new file mode 100755 index 00000000..94756b0a --- /dev/null +++ b/mm-video-v4l2/vidc/venc/test/queue.c @@ -0,0 +1,174 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "queue.h" + +int check_if_queue_empty ( unsigned int queuetocheck, void* queuecontext ) +{ + struct video_queue_context *ptr_q = NULL; + /* + * queuetocheck - 0 command queue + * queuetocheck - 1 data queue + */ + if ( queuecontext == NULL || (queuetocheck > 1 ) ) + { + return 1; + } + ptr_q = (struct video_queue_context *)queuecontext; + + if (queuetocheck == 0) + { + if (ptr_q->read_comq == ptr_q->write_comq) + { + return 1; + } + } + else if (queuetocheck == 1) + { + if (ptr_q->write_dataq == ptr_q->read_dataq) + { + return 1; + } + } + + return 0; +} + + + +struct video_msgq * queue_get_cmd (void* queuecontext ) +{ + struct video_queue_context *ptr_q = NULL; + struct video_msgq *pitem = NULL; + + if( NULL == queuecontext ) + { + printf("\n queue_get_cmd: Invalid Input parameter\n"); + return NULL; + } + + ptr_q = (struct video_queue_context *)queuecontext; + + /* Wait on the semaphore till it is released */ + sem_wait(&ptr_q->sem_message); + + /* Lock the mutex to protect the critical section */ + pthread_mutex_lock(&ptr_q->mutex); + + if (ptr_q->read_comq != ptr_q->write_comq) + { + pitem = &ptr_q->ptr_cmdq [ptr_q->read_comq]; + ptr_q->read_comq = (ptr_q->read_comq + 1) % \ + ptr_q->commandq_size; + } + else if (ptr_q->write_dataq != ptr_q->read_dataq) + { + pitem = &ptr_q->ptr_dataq [ptr_q->read_dataq]; + ptr_q->read_dataq = (ptr_q->read_dataq + 1) % \ + ptr_q->dataq_size; + } + + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + + return pitem; +} + + +int queue_post_cmdq ( void* queuecontext, + struct video_msgq *pitem + ) +{ + struct video_queue_context *ptr_q = NULL; + + if (pitem == NULL || queuecontext == NULL) + { + return -1; + } + ptr_q = (struct video_queue_context *)queuecontext; + + /* Lock the mutex to protect the critical section */ + pthread_mutex_lock(&ptr_q->mutex); + + if ((ptr_q->write_comq + 1) % ptr_q->commandq_size == ptr_q->read_comq) + { + printf("\n QUEUE is FULL"); + return 0; + } + else + { + /* Store the command in the Message Queue & increment write offset */ + memcpy ( &ptr_q->ptr_cmdq [ptr_q->write_comq],pitem, \ + sizeof (struct video_msgq)); + ptr_q->write_comq = (ptr_q->write_comq + 1) % ptr_q->commandq_size; + } + + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + + /* Post the semaphore */ + sem_post(&ptr_q->sem_message); + return 1; +} + + +int queue_post_dataq ( void *queuecontext, + struct video_msgq *pitem + ) +{ + struct video_queue_context *ptr_q = NULL; + + if (pitem == NULL || queuecontext == NULL) + { + return -1; + } + ptr_q = (struct video_queue_context *)queuecontext; + + /* Lock the mutex to protect the critical section */ + pthread_mutex_lock(&ptr_q->mutex); + + if ((ptr_q->write_dataq + 1) % ptr_q->dataq_size == ptr_q->read_dataq) + { + printf("\n QUEUE is FULL"); + return 0; + } + else + { + /* Store the command in the Message Queue & increment write offset */ + memcpy ( &ptr_q->ptr_dataq [ptr_q->write_dataq],pitem, \ + sizeof (struct video_msgq)); + ptr_q->write_dataq = (ptr_q->write_dataq + 1) % ptr_q->dataq_size; + } + + /* Unlock the mutex to release the critical section */ + pthread_mutex_unlock(&ptr_q->mutex); + + /* Post the semaphore */ + sem_post(&ptr_q->sem_message); + return 1; + +} diff --git a/mm-video-v4l2/vidc/venc/test/venc_test.cpp b/mm-video-v4l2/vidc/venc/test/venc_test.cpp new file mode 100644 index 00000000..7afb5bd9 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/test/venc_test.cpp @@ -0,0 +1,2442 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +/*============================================================================ + V E N C _ T E S T. C P P + +DESCRIPTION + + This is the OMX test app . + +REFERENCES + +============================================================================*/ + +//usage +// FILE QVGA MP4 24 384000 100 enc_qvga.yuv QVGA_24.m4v +// FILE QCIF MP4 15 96000 0 foreman.qcif.yuv output_qcif.m4v +// FILE VGA MP4 24 1200000 218 enc_vga.yuv vga_output.m4v +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +//#include +#include "OMX_QCOMExtns.h" +#include "OMX_Core.h" + +#define QCOM_EXT 1 + +#include "OMX_Core.h" +#include "OMX_Video.h" +#include "OMX_Component.h" +#include "camera_test.h" +#include "fb_test.h" +#include "venc_util.h" +#include "extra_data_handler.h" +#ifdef USE_ION +#include +#endif +#ifdef _MSM8974_ +#include +#endif + +////////////////////////// +// MACROS +////////////////////////// + +#define CHK(result) if ((result != OMX_ErrorNone) && (result != OMX_ErrorNoMore)) { E("*************** error *************"); exit(0); } +#define TEST_LOG +#ifdef VENC_SYSLOG +#include +/// Debug message macro +#define D(fmt, ...) ALOGE("venc_test Debug %s::%d "fmt, \ + __FUNCTION__, __LINE__, \ + ## __VA_ARGS__) + +/// Error message macro +#define E(fmt, ...) ALOGE("venc_test Error %s::%d "fmt, \ + __FUNCTION__, __LINE__, \ + ## __VA_ARGS__) + +#else + #ifdef TEST_LOG + #define D(fmt, ...) fprintf(stderr, "venc_test Debug %s::%d "fmt"\n", \ + __FUNCTION__, __LINE__, \ + ## __VA_ARGS__) + + /// Error message macro + #define E(fmt, ...) fprintf(stderr, "venc_test Error %s::%d "fmt"\n", \ + __FUNCTION__, __LINE__, \ + ## __VA_ARGS__) + #else + #define D(fmt, ...) + #define E(fmt, ...) + #endif + +#endif + +////////////////////////// +// CONSTANTS +////////////////////////// +static const int MAX_MSG = 100; +//#warning do not hardcode these use port definition +static const int PORT_INDEX_IN = 0; +static const int PORT_INDEX_OUT = 1; + +static const int NUM_IN_BUFFERS = 10; +static const int NUM_OUT_BUFFERS = 10; + +unsigned int num_in_buffers = 0; +unsigned int num_out_buffers = 0; + +////////////////////////// +/* MPEG4 profile and level table*/ +static const unsigned int mpeg4_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, + {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, + {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, + {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, + {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, + {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, +#ifdef _MSM8974_ + {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, + {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, +#endif + {0,0,0,0,0}, + + {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, +#ifdef _MSM8974_ + {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, + {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, +#endif + {0,0,0,0,0}, +}; + +/* H264 profile and level table*/ +static const unsigned int h264_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, + {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, + {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, + {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, + {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, + {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, + {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, + {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, + {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, + {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, + {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, + {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, +#ifdef _MSM8974_ + {32400,972000,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, + {34560,1036800,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, +#endif + {0,0,0,0,0}, + + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, + {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, + {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, + {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, + {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, + {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, + {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, + {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, + {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, + {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, + {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, + {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, +#ifdef _MSM8974_ + {32400,972000,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, + {34560,1036800,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, +#endif + {0,0,0,0,0}, + + {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, + {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, + {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, + {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, + {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, + {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, + {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, + {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, + {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, + {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, + {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, + {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, +#ifdef _MSM8974_ + {32400,972000,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, + {34560,1036800,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, +#endif + {0,0,0,0,0} + +}; + +/* H263 profile and level table*/ +static const unsigned int h263_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, + {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, + {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, + {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, + {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, + {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, +#ifdef _MSM8974_ + {32400,972000,20000000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, + {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, +#endif + {0,0,0,0,0} +}; +#ifdef _MSM8974_ +static const unsigned int VP8_profile_level_table[][5]= +{ + /*max mb per frame, max mb per sec, max bitrate, level, profile*/ + {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, + {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, + {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, + {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, + {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, + {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, + {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, + {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, + {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, + {0,0,0,0,0} +}; +#endif + +#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } +#define FractionToQ16(q,num,den) { OMX_U32 power; Log2(den,power); q = num << (16 - power); } + +////////////////////////// +// TYPES +////////////////////////// +struct ProfileType +{ + OMX_VIDEO_CODINGTYPE eCodec; + OMX_VIDEO_MPEG4LEVELTYPE eLevel; + OMX_VIDEO_CONTROLRATETYPE eControlRate; + OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; + OMX_U32 nFrameWidth; + OMX_U32 nFrameHeight; + OMX_U32 nFrameBytes; +#ifdef _MSM8974_ + OMX_U32 nFramestride; + OMX_U32 nFrameScanlines; + OMX_U32 nFrameRead; +#endif + OMX_U32 nBitrate; + float nFramerate; + char* cInFileName; + char* cOutFileName; + OMX_U32 nUserProfile; +}; + +enum MsgId +{ + MSG_ID_OUTPUT_FRAME_DONE, + MSG_ID_INPUT_FRAME_DONE, + MSG_ID_MAX +}; +union MsgData +{ + struct + { + OMX_BUFFERHEADERTYPE* pBuffer; + } sBitstreamData; +}; +struct Msg +{ + MsgId id; + MsgData data; +}; +struct MsgQ +{ + Msg q[MAX_MSG]; + int head; + int size; +}; + +enum Mode +{ + MODE_PREVIEW, + MODE_DISPLAY, + MODE_PROFILE, + MODE_FILE_ENCODE, + MODE_LIVE_ENCODE +}; + +enum ResyncMarkerType +{ + RESYNC_MARKER_NONE, ///< No resync marker + RESYNC_MARKER_BYTE, ///< BYTE Resync marker for MPEG4, H.264 + RESYNC_MARKER_MB, ///< MB resync marker for MPEG4, H.264 + RESYNC_MARKER_GOB ///< GOB resync marker for H.263 +}; + +union DynamicConfigData +{ + OMX_VIDEO_CONFIG_BITRATETYPE bitrate; + OMX_CONFIG_FRAMERATETYPE framerate; + QOMX_VIDEO_INTRAPERIODTYPE intraperiod; + OMX_CONFIG_INTRAREFRESHVOPTYPE intravoprefresh; + OMX_CONFIG_ROTATIONTYPE rotation; + float f_framerate; +}; + +struct DynamicConfig +{ + bool pending; + unsigned frame_num; + OMX_INDEXTYPE config_param; + union DynamicConfigData config_data; +}; + +#ifdef USE_ION +struct enc_ion +{ + int ion_device_fd; + struct ion_allocation_data alloc_data; + struct ion_fd_data ion_alloc_fd; +}; +#endif + +////////////////////////// +// MODULE VARS +////////////////////////// +static pthread_mutex_t m_mutex; +static pthread_cond_t m_signal; +static MsgQ m_sMsgQ; + +//#warning determine how many buffers we really have +OMX_STATETYPE m_eState = OMX_StateInvalid; +OMX_COMPONENTTYPE m_sComponent; +OMX_HANDLETYPE m_hHandle = NULL; +OMX_BUFFERHEADERTYPE* m_pOutBuffers[NUM_OUT_BUFFERS] = {NULL}; +OMX_BUFFERHEADERTYPE* m_pInBuffers[NUM_IN_BUFFERS] = {NULL}; +OMX_BOOL m_bInFrameFree[NUM_IN_BUFFERS]; + +ProfileType m_sProfile; + +static int m_nFramePlay = 0; +static int m_eMode = MODE_PREVIEW; +static int m_nInFd = -1; +static int m_nOutFd = -1; +static int m_nTimeStamp = 0; +static int m_nFrameIn = 0; // frames pushed to encoder +static int m_nFrameOut = 0; // frames returned by encoder +static int m_nAVCSliceMode = 0; +static bool m_bWatchDogKicked = false; +FILE *m_pDynConfFile = NULL; +static struct DynamicConfig dynamic_config; + +/* Statistics Logging */ +static long long tot_bufsize = 0; +int ebd_cnt=0, fbd_cnt=0; + +#ifdef USE_ION +static const char* PMEM_DEVICE = "/dev/ion"; +#elif MAX_RES_720P +static const char* PMEM_DEVICE = "/dev/pmem_adsp"; +#elif MAX_RES_1080P_EBI +static const char* PMEM_DEVICE = "/dev/pmem_adsp"; +#elif MAX_RES_1080P +static const char* PMEM_DEVICE = "/dev/pmem_smipool"; +#else +#error PMEM_DEVICE cannot be determined. +#endif + +#ifdef USE_ION +struct enc_ion ion_data; +#endif +////////////////////////// +// MODULE FUNCTIONS +////////////////////////// + +void* PmemMalloc(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, int nSize) +{ + void *pvirt = NULL; + int rc = 0; + + if (!pMem) + return NULL; + +#ifdef USE_ION + ion_data.ion_device_fd = open (PMEM_DEVICE, O_RDONLY); + if(ion_data.ion_device_fd < 0) + { + E("\nERROR: ION Device open() Failed"); + return NULL; + } + nSize = (nSize + 4095) & (~4095); + ion_data.alloc_data.len = nSize; + ion_data.alloc_data.heap_mask = 0x1 << ION_CP_MM_HEAP_ID; + ion_data.alloc_data.align = 4096; + ion_data.alloc_data.flags = ION_SECURE; + + rc = ioctl(ion_data.ion_device_fd,ION_IOC_ALLOC,&ion_data.alloc_data); + if(rc || !ion_data.alloc_data.handle) { + E("\n ION ALLOC memory failed rc: %d, handle: %p", rc, ion_data.alloc_data.handle); + ion_data.alloc_data.handle=NULL; + return NULL; + } + + ion_data.ion_alloc_fd.handle = ion_data.alloc_data.handle; + rc = ioctl(ion_data.ion_device_fd,ION_IOC_MAP,&ion_data.ion_alloc_fd); + if(rc) { + E("\n ION MAP failed "); + ion_data.ion_alloc_fd.fd =-1; + ion_data.ion_alloc_fd.fd =-1; + return NULL; + } + pMem->pmem_fd = ion_data.ion_alloc_fd.fd; +#else + pMem->pmem_fd = open(PMEM_DEVICE, O_RDWR); + if ((int)(pMem->pmem_fd) < 0) + return NULL; + nSize = (nSize + 4095) & (~4095); +#endif + pMem->offset = 0; + pvirt = mmap(NULL, nSize, + PROT_READ | PROT_WRITE, + MAP_SHARED, pMem->pmem_fd, pMem->offset); + if (pvirt == (void*) MAP_FAILED) + { + close(pMem->pmem_fd); + pMem->pmem_fd = -1; +#ifdef USE_ION + if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE, + &ion_data.alloc_data.handle)) { + E("ion recon buffer free failed"); + } + ion_data.alloc_data.handle = NULL; + ion_data.ion_alloc_fd.fd =-1; + close(ion_data.ion_device_fd); + ion_data.ion_device_fd =-1; +#endif + return NULL; + } + D("allocated pMem->fd = %lu pvirt=0x%p, pMem->phys=0x%lx, size = %d", pMem->pmem_fd, + pvirt, pMem->offset, nSize); + return pvirt; +} + +int PmemFree(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, void* pvirt, int nSize) +{ + if (!pMem || !pvirt) + return -1; + + nSize = (nSize + 4095) & (~4095); + munmap(pvirt, nSize); + close(pMem->pmem_fd); + pMem->pmem_fd = -1; +#ifdef USE_ION + if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE, + &ion_data.alloc_data.handle)) { + E("ion recon buffer free failed"); + } + ion_data.alloc_data.handle = NULL; + ion_data.ion_alloc_fd.fd =-1; + close(ion_data.ion_device_fd); + ion_data.ion_device_fd =-1; +#endif + return 0; +} +void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement) +{ + printf("id (%lu)\n", + framePackingArrangement.id); + printf("cancel_flag (%lu)\n", + framePackingArrangement.cancel_flag); + printf("type (%lu)\n", + framePackingArrangement.type); + printf("quincunx_sampling_flag (%lu)\n", + framePackingArrangement.quincunx_sampling_flag); + printf("content_interpretation_type (%lu)\n", + framePackingArrangement.content_interpretation_type); + printf("spatial_flipping_flag (%lu)\n", + framePackingArrangement.spatial_flipping_flag); + printf("frame0_flipped_flag (%lu)\n", + framePackingArrangement.frame0_flipped_flag); + printf("field_views_flag (%lu)\n", + framePackingArrangement.field_views_flag); + printf("current_frame_is_frame0_flag (%lu)\n", + framePackingArrangement.current_frame_is_frame0_flag); + printf("frame0_self_contained_flag (%lu)\n", + framePackingArrangement.frame0_self_contained_flag); + printf("frame1_self_contained_flag (%lu)\n", + framePackingArrangement.frame1_self_contained_flag); + printf("frame0_grid_position_x (%lu)\n", + framePackingArrangement.frame0_grid_position_x); + printf("frame0_grid_position_y (%lu)\n", + framePackingArrangement.frame0_grid_position_y); + printf("frame1_grid_position_x (%lu)\n", + framePackingArrangement.frame1_grid_position_x); + printf("frame1_grid_position_y (%lu)\n", + framePackingArrangement.frame1_grid_position_y); + printf("reserved_byte (%lu)\n", + framePackingArrangement.reserved_byte); + printf("repetition_period (%lu)\n", + framePackingArrangement.repetition_period); + printf("extension_flag (%lu)\n", + framePackingArrangement.extension_flag); +} +void SetState(OMX_STATETYPE eState) +{ +#define GOTO_STATE(eState) \ + case eState: \ + { \ + D("Going to state " # eState"..."); \ + OMX_SendCommand(m_hHandle, \ + OMX_CommandStateSet, \ + (OMX_U32) eState, \ + NULL); \ + while (m_eState != eState) \ + { \ + sleep(1); \ + } \ + D("Now in state " # eState); \ + break; \ + } + + switch (eState) + { + GOTO_STATE(OMX_StateLoaded); + GOTO_STATE(OMX_StateIdle); + GOTO_STATE(OMX_StateExecuting); + GOTO_STATE(OMX_StateInvalid); + GOTO_STATE(OMX_StateWaitForResources); + GOTO_STATE(OMX_StatePause); + } +} +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE ConfigureEncoder() +{ + OMX_ERRORTYPE result = OMX_ErrorNone; + unsigned const int *profile_tbl = (unsigned int const *)mpeg4_profile_level_table; + OMX_U32 mb_per_sec, mb_per_frame; + bool profile_level_found = false; + OMX_U32 eProfile,eLevel; + + OMX_PARAM_PORTDEFINITIONTYPE portdef; // OMX_IndexParamPortDefinition +#ifdef QCOM_EXT + OMX_QCOM_PARAM_PORTDEFINITIONTYPE qPortDefnType; +#endif + portdef.nPortIndex = (OMX_U32) 0; // input + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamPortDefinition, + &portdef); + E("\n OMX_IndexParamPortDefinition Get Paramter on input port"); + CHK(result); + portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth; + portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight; + + E ("\n Height %lu width %lu bit rate %lu",portdef.format.video.nFrameHeight + ,portdef.format.video.nFrameWidth,portdef.format.video.nBitrate); + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamPortDefinition, + &portdef); + E("\n OMX_IndexParamPortDefinition Set Paramter on input port"); + CHK(result); + // once more to get proper buffer size + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamPortDefinition, + &portdef); + E("\n OMX_IndexParamPortDefinition Get Paramter on input port, 2nd pass"); + CHK(result); + // update size accordingly + m_sProfile.nFrameBytes = portdef.nBufferSize; + portdef.nPortIndex = (OMX_U32) 1; // output + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamPortDefinition, + &portdef); + E("\n OMX_IndexParamPortDefinition Get Paramter on output port"); + CHK(result); + portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth; + portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight; + portdef.format.video.nBitrate = m_sProfile.nBitrate; + FractionToQ16(portdef.format.video.xFramerate,(int) (m_sProfile.nFramerate * 2),2); + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamPortDefinition, + &portdef); + E("\n OMX_IndexParamPortDefinition Set Paramter on output port"); + CHK(result); + +#ifdef QCOM_EXT + +qPortDefnType.nPortIndex = PORT_INDEX_IN; +qPortDefnType.nMemRegion = OMX_QCOM_MemRegionEBI1; +qPortDefnType.nSize = sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE); + +result = OMX_SetParameter(m_hHandle, + (OMX_INDEXTYPE)OMX_QcomIndexPortDefn, + &qPortDefnType); + +#endif + if (!m_sProfile.nUserProfile) // profile not set by user, go ahead with table calculation + { + //validate the ht,width,fps,bitrate and set the appropriate profile and level + if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) + { + profile_tbl = (unsigned int const *)mpeg4_profile_level_table; + } + else if(m_sProfile.eCodec == OMX_VIDEO_CodingAVC) + { + profile_tbl = (unsigned int const *)h264_profile_level_table; + } + else if(m_sProfile.eCodec == OMX_VIDEO_CodingH263) + { + profile_tbl = (unsigned int const *)h263_profile_level_table; + } +#ifdef _MSM8974_ + else if(m_sProfile.eCodec == OMX_VIDEO_CodingVPX) + { + profile_tbl = (unsigned int const *)VP8_profile_level_table; + } +#endif + mb_per_frame = ((m_sProfile.nFrameHeight+15)>>4)* + ((m_sProfile.nFrameWidth+15)>>4); + + mb_per_sec = mb_per_frame*(m_sProfile.nFramerate); + + do{ + if(mb_per_frame <= (unsigned int)profile_tbl[0]) + { + if(mb_per_sec <= (unsigned int)profile_tbl[1]) + { + if(m_sProfile.nBitrate <= (unsigned int)profile_tbl[2]) + { + eLevel = (int)profile_tbl[3]; + eProfile = (int)profile_tbl[4]; + E("\n profile/level found: %lu/%lu\n",eProfile, eLevel); + profile_level_found = true; + break; + } + } + } + profile_tbl = profile_tbl + 5; + }while(profile_tbl[0] != 0); + + if ( profile_level_found != true ) + { + E("\n Error: Unsupported profile/level\n"); + return OMX_ErrorNone; + } + } + else // Profile set by user! + { + eProfile = m_sProfile.nUserProfile; + eLevel = 0; + } + if (m_sProfile.eCodec == OMX_VIDEO_CodingH263) + { + D("Configuring H263..."); + + OMX_VIDEO_PARAM_H263TYPE h263; + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoH263, + &h263); + CHK(result); + h263.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + h263.nPFrames = m_sProfile.nFramerate * 2 - 1; // intra period + h263.nBFrames = 0; + h263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile; + h263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel; + h263.bPLUSPTYPEAllowed = OMX_FALSE; + h263.nAllowedPictureTypes = 2; + h263.bForceRoundingTypeToZero = OMX_TRUE; + h263.nPictureHeaderRepetition = 0; + h263.nGOBHeaderInterval = 1; + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoH263, + &h263); + } + else + { + D("Configuring MP4/H264..."); + + OMX_VIDEO_PARAM_PROFILELEVELTYPE profileLevel; // OMX_IndexParamVideoProfileLevelCurrent + profileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + profileLevel.eProfile = eProfile; + profileLevel.eLevel = eLevel; + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoProfileLevelCurrent, + &profileLevel); + E("\n OMX_IndexParamVideoProfileLevelCurrent Set Paramter port"); + CHK(result); + //profileLevel.eLevel = (OMX_U32) m_sProfile.eLevel; + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoProfileLevelCurrent, + &profileLevel); + E("\n OMX_IndexParamVideoProfileLevelCurrent Get Paramter port"); + D ("\n Profile = %lu level = %lu",profileLevel.eProfile,profileLevel.eLevel); + CHK(result); + + if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) + { + OMX_VIDEO_PARAM_MPEG4TYPE mp4; // OMX_IndexParamVideoMpeg4 + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoMpeg4, + &mp4); + CHK(result); + mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + mp4.nTimeIncRes = 1000; + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoMpeg4, + &mp4); + CHK(result); + } + } + if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC) + { +#if 1 +/////////////C A B A C ///A N D/////D E B L O C K I N G ///////////////// + + OMX_VIDEO_PARAM_AVCTYPE avcdata; + avcdata.nPortIndex = (OMX_U32)PORT_INDEX_OUT; + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoAvc, + &avcdata); + CHK(result); +// TEST VALUES (CHANGE FOR DIFF CONFIG's) + avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; +// avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisable; +// avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisableSliceBoundary; + avcdata.bEntropyCodingCABAC = OMX_FALSE; +// avcdata.bEntropyCodingCABAC = OMX_TRUE; + avcdata.nCabacInitIdc = 1; +/////////////////////////////////////////////// + + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoAvc, + &avcdata); + CHK(result); + +/////////////C A B A C ///A N D/////D E B L O C K I N G ///////////////// +#endif + } + + OMX_VIDEO_PARAM_BITRATETYPE bitrate; // OMX_IndexParamVideoBitrate + bitrate.nPortIndex = (OMX_U32)PORT_INDEX_OUT; + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoBitrate, + &bitrate); + E("\n OMX_IndexParamVideoBitrate Get Paramter port"); + CHK(result); + bitrate.eControlRate = m_sProfile.eControlRate; + bitrate.nTargetBitrate = m_sProfile.nBitrate; + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoBitrate, + &bitrate); + E("\n OMX_IndexParamVideoBitrate Set Paramter port"); + CHK(result); + + OMX_VIDEO_PARAM_PORTFORMATTYPE framerate; // OMX_IndexParamVidePortFormat + framerate.nPortIndex = 0; + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoPortFormat, + &framerate); + E("\n OMX_IndexParamVideoPortFormat Get Paramter port"); + CHK(result); + FractionToQ16(framerate.xFramerate,(int) (m_sProfile.nFramerate * 2),2); + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoPortFormat, + &framerate); + E("\n OMX_IndexParamVideoPortFormat Set Paramter port"); + CHK(result); + +#if 1 +///////////////////I N T R A P E R I O D /////////////////// + + QOMX_VIDEO_INTRAPERIODTYPE intra; + + intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output + result = OMX_GetConfig(m_hHandle, + (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod, + (OMX_PTR) &intra); + + if (result == OMX_ErrorNone) + { + intra.nPFrames = (OMX_U32) (2 * m_sProfile.nFramerate - 1); //setting I + //frame interval to + //2 x framerate + intra.nIDRPeriod = 1; //every I frame is an IDR + intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT; + result = OMX_SetConfig(m_hHandle, + (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod, + (OMX_PTR) &intra); + } + else + { + E("failed to get state", 0, 0, 0); + } + + +///////////////////I N T R A P E R I O D /////////////////// +#endif + +#if 1 +///////////////////E R R O R C O R R E C T I O N /////////////////// + + ResyncMarkerType eResyncMarkerType = RESYNC_MARKER_NONE; + unsigned long int nResyncMarkerSpacing = 0; + OMX_BOOL enableHEC = OMX_FALSE; + +//For Testing ONLY + if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) + { +// MPEG4 +// eResyncMarkerType = RESYNC_MARKER_BYTE; +// nResyncMarkerSpacing = 1920; + eResyncMarkerType = RESYNC_MARKER_MB; + nResyncMarkerSpacing = 50; + enableHEC = OMX_TRUE; + } + else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263) + { +//H263 + //eResyncMarkerType = RESYNC_MARKER_GOB; + eResyncMarkerType = RESYNC_MARKER_NONE; + nResyncMarkerSpacing = 0; + } + else if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC) + { +//H264 +// eResyncMarkerType = RESYNC_MARKER_BYTE; +// nResyncMarkerSpacing = 1920; + + //nResyncMarkerSpacing sets the slice size in venc_set_multislice_cfg + // + //As of 9/24/10, it is known that the firmware has a bitstream + //corruption issue when RateControl and multislice are enabled for 720P + //So, disabling multislice for 720P when ratecontrol is enabled until + //the firmware issue is resolved. + + if ( ( (m_sProfile.nFrameWidth == 1280) && (m_sProfile.nFrameHeight = 720) ) && + (m_sProfile.eControlRate != OMX_Video_ControlRateDisable) ) + { + eResyncMarkerType = RESYNC_MARKER_NONE; + nResyncMarkerSpacing = 0; + } + else + { + eResyncMarkerType = RESYNC_MARKER_NONE; + nResyncMarkerSpacing = 0; + } + } + + OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrection; //OMX_IndexParamVideoErrorCorrection + errorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output + result = OMX_GetParameter(m_hHandle, + (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection, + (OMX_PTR) &errorCorrection); + + errorCorrection.bEnableRVLC = OMX_FALSE; + errorCorrection.bEnableDataPartitioning = OMX_FALSE; + + if ((eResyncMarkerType == RESYNC_MARKER_BYTE) && + (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)){ + errorCorrection.bEnableResync = OMX_TRUE; + errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing; + errorCorrection.bEnableHEC = enableHEC; + } + else if ((eResyncMarkerType == RESYNC_MARKER_BYTE) && + (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)){ + errorCorrection.bEnableResync = OMX_TRUE; + errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing; + } + else if ((eResyncMarkerType == RESYNC_MARKER_GOB) && + (m_sProfile.eCodec == OMX_VIDEO_CodingH263)){ + errorCorrection.bEnableResync = OMX_FALSE; + errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing; + errorCorrection.bEnableDataPartitioning = OMX_TRUE; + } + + result = OMX_SetParameter(m_hHandle, + (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection, + (OMX_PTR) &errorCorrection); + CHK(result); + + if (eResyncMarkerType == RESYNC_MARKER_MB){ + if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC){ + OMX_VIDEO_PARAM_AVCTYPE avcdata; + avcdata.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoAvc, + (OMX_PTR) &avcdata); + CHK(result); + if (result == OMX_ErrorNone) + { + avcdata.nSliceHeaderSpacing = nResyncMarkerSpacing; + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoAvc, + (OMX_PTR) &avcdata); + CHK(result); + + } + } + else if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4){ + OMX_VIDEO_PARAM_MPEG4TYPE mp4; + mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoMpeg4, + (OMX_PTR) &mp4); + CHK(result); + + if (result == OMX_ErrorNone) + { + mp4.nSliceHeaderSpacing = nResyncMarkerSpacing; + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoMpeg4, + (OMX_PTR) &mp4); + CHK(result); + } + } + } + +///////////////////E R R O R C O R R E C T I O N /////////////////// +#endif + +#if 1 +///////////////////I N T R A R E F R E S H/////////////////// + bool bEnableIntraRefresh = OMX_TRUE; + + if (result == OMX_ErrorNone) + { + OMX_VIDEO_PARAM_INTRAREFRESHTYPE ir; // OMX_IndexParamVideoIntraRefresh + ir.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output + result = OMX_GetParameter(m_hHandle, + OMX_IndexParamVideoIntraRefresh, + (OMX_PTR) &ir); + if (result == OMX_ErrorNone) + { + if (bEnableIntraRefresh) + { + ir.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; + ir.nCirMBs = 5; + result = OMX_SetParameter(m_hHandle, + OMX_IndexParamVideoIntraRefresh, + (OMX_PTR) &ir); + CHK(result); + } + } + } +#endif +#if 1 +///////////////////FRAMEPACKING DATA/////////////////// + OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement; + FILE *m_pConfigFile; + char m_configFilename [128] = "/data/configFile.cfg"; + memset(&framePackingArrangement, 0, sizeof(framePackingArrangement)); + m_pConfigFile = fopen(m_configFilename, "r"); + if (m_pConfigFile != NULL) + { + //read all frame packing data + framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT; + int totalSizeToRead = FRAME_PACK_SIZE * sizeof(OMX_U32); + char *pFramePack = (char *) &(framePackingArrangement.id); + while ( ( (fscanf(m_pConfigFile, "%d", pFramePack)) != EOF ) && + (totalSizeToRead != 0) ) + { + //printf("Addr = %p, Value read = %d, sizeToRead remaining=%d\n", + // pFramePack, *pFramePack, totalSizeToRead); + pFramePack += sizeof(OMX_U32); + totalSizeToRead -= sizeof(OMX_U32); + } + //close the file. + fclose(m_pConfigFile); + + printf("Frame Packing data from config file:\n"); + PrintFramePackArrangement(framePackingArrangement); + } + else + { + D("\n Config file does not exist or could not be opened."); + //set the default values + framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT; + framePackingArrangement.id = 123; + framePackingArrangement.cancel_flag = false; + framePackingArrangement.type = 3; + framePackingArrangement.quincunx_sampling_flag = false; + framePackingArrangement.content_interpretation_type = 0; + framePackingArrangement.spatial_flipping_flag = true; + framePackingArrangement.frame0_flipped_flag = false; + framePackingArrangement.field_views_flag = false; + framePackingArrangement.current_frame_is_frame0_flag = false; + framePackingArrangement.frame0_self_contained_flag = true; + framePackingArrangement.frame1_self_contained_flag = false; + framePackingArrangement.frame0_grid_position_x = 3; + framePackingArrangement.frame0_grid_position_y = 15; + framePackingArrangement.frame1_grid_position_x = 11; + framePackingArrangement.frame1_grid_position_y = 7; + framePackingArrangement.reserved_byte = 0; + framePackingArrangement.repetition_period = 16381; + framePackingArrangement.extension_flag = false; + + printf("Frame Packing Defaults :\n"); + PrintFramePackArrangement(framePackingArrangement); + } + result = OMX_SetConfig(m_hHandle, + (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement, + (OMX_PTR) &framePackingArrangement); + CHK(result); + +//////////////////////OMX_VIDEO_PARAM_INTRAREFRESHTYPE/////////////////// +#endif + + OMX_CONFIG_FRAMERATETYPE enc_framerate; // OMX_IndexConfigVideoFramerate + enc_framerate.nPortIndex = (OMX_U32)PORT_INDEX_OUT; + result = OMX_GetConfig(m_hHandle, + OMX_IndexConfigVideoFramerate, + &enc_framerate); + CHK(result); + FractionToQ16(enc_framerate.xEncodeFramerate,(int) (m_sProfile.nFramerate * 2),2); + result = OMX_SetConfig(m_hHandle, + OMX_IndexConfigVideoFramerate, + &enc_framerate); + CHK(result); + return OMX_ErrorNone; +} +//////////////////////////////////////////////////////////////////////////////// +void SendMessage(MsgId id, MsgData* data) +{ + pthread_mutex_lock(&m_mutex); + if (m_sMsgQ.size >= MAX_MSG) + { + E("main msg m_sMsgQ is full"); + return; + } + m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].id = id; + if (data) + m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].data = *data; + ++m_sMsgQ.size; + pthread_cond_signal(&m_signal); + pthread_mutex_unlock(&m_mutex); +} +//////////////////////////////////////////////////////////////////////////////// +void PopMessage(Msg* msg) +{ + pthread_mutex_lock(&m_mutex); + while (m_sMsgQ.size == 0) + { + pthread_cond_wait(&m_signal, &m_mutex); + } + *msg = m_sMsgQ.q[m_sMsgQ.head]; + --m_sMsgQ.size; + m_sMsgQ.head = (m_sMsgQ.head + 1) % MAX_MSG; + pthread_mutex_unlock(&m_mutex); +} +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE EVT_CB(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_EVENTTYPE eEvent, + OMX_IN OMX_U32 nData1, + OMX_IN OMX_U32 nData2, + OMX_IN OMX_PTR pEventData) +{ +#define SET_STATE(eState) \ + case eState: \ + { \ + D("" # eState " complete"); \ + m_eState = eState; \ + break; \ + } + + if (eEvent == OMX_EventCmdComplete) + { + if ((OMX_COMMANDTYPE) nData1 == OMX_CommandStateSet) + { + switch ((OMX_STATETYPE) nData2) + { + SET_STATE(OMX_StateLoaded); + SET_STATE(OMX_StateIdle); + SET_STATE(OMX_StateExecuting); + SET_STATE(OMX_StateInvalid); + SET_STATE(OMX_StateWaitForResources); + SET_STATE(OMX_StatePause); + default: + E("invalid state %d", (int) nData2); + } + } + } + + else if (eEvent == OMX_EventError) + { + E("OMX_EventError"); + } + + else + { + E("unexpected event %d", (int) eEvent); + } + return OMX_ErrorNone; +} +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE EBD_CB(OMX_IN OMX_HANDLETYPE hComponent, + OMX_IN OMX_PTR pAppData, + OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) +{ + D("Got EBD callback ts=%lld", pBuffer->nTimeStamp); + + for (int i = 0; i < num_in_buffers; i++) + { + // mark this buffer ready for use again + if (m_pInBuffers[i] == pBuffer) + { + + D("Marked input buffer idx %d as free, buf %p", i, pBuffer->pBuffer); + m_bInFrameFree[i] = OMX_TRUE; + break; + } + } + + if (m_eMode == MODE_LIVE_ENCODE) + { + CameraTest_ReleaseFrame(pBuffer->pBuffer, + ((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)pBuffer->pAppPrivate)); + } + else + { + // wake up main thread and tell it to send next frame + MsgData data; + data.sBitstreamData.pBuffer = pBuffer; + SendMessage(MSG_ID_INPUT_FRAME_DONE, + &data); + + } + return OMX_ErrorNone; +} +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE FBD_CB(OMX_OUT OMX_HANDLETYPE hComponent, + OMX_OUT OMX_PTR pAppData, + OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) +{ + D("Got FBD callback ts=%lld", pBuffer->nTimeStamp); + + static long long prevTime = 0; + long long currTime = GetTimeStamp(); + + m_bWatchDogKicked = true; + + /* Empty Buffers should not be counted */ + if(pBuffer->nFilledLen !=0) + { + /* Counting Buffers supplied from OpneMax Encoder */ + fbd_cnt++; + tot_bufsize += pBuffer->nFilledLen; + } + if (prevTime != 0) + { + long long currTime = GetTimeStamp(); + D("FBD_DELTA = %lld\n", currTime - prevTime); + } + prevTime = currTime; + + if (m_eMode == MODE_PROFILE) + { + // if we are profiling we are not doing file I/O + // so just give back to encoder + if (OMX_FillThisBuffer(m_hHandle, pBuffer) != OMX_ErrorNone) + { + E("empty buffer failed for profiling"); + } + } + else + { + // wake up main thread and tell it to write to file + MsgData data; + data.sBitstreamData.pBuffer = pBuffer; + SendMessage(MSG_ID_OUTPUT_FRAME_DONE, + &data); + } + return OMX_ErrorNone; +} +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE VencTest_Initialize() +{ + OMX_ERRORTYPE result = OMX_ErrorNone; + static OMX_CALLBACKTYPE sCallbacks = {EVT_CB, EBD_CB, FBD_CB}; + int i; + + for (i = 0; i < num_in_buffers; i++) + { + m_pInBuffers[i] = NULL; + } + + result = OMX_Init(); + CHK(result); + + if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) + { + result = OMX_GetHandle(&m_hHandle, + "OMX.qcom.video.encoder.mpeg4", + NULL, + &sCallbacks); + // CHK(result); + } + else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263) + { + result = OMX_GetHandle(&m_hHandle, + "OMX.qcom.video.encoder.h263", + NULL, + &sCallbacks); + CHK(result); + } +#ifdef _MSM8974_ + else if (m_sProfile.eCodec == OMX_VIDEO_CodingVPX) + { + result = OMX_GetHandle(&m_hHandle, + "OMX.qcom.video.encoder.vp8", + NULL, + &sCallbacks); + CHK(result); + } +#endif + else + { + result = OMX_GetHandle(&m_hHandle, + "OMX.qcom.video.encoder.avc", + NULL, + &sCallbacks); + CHK(result); + } + + + result = ConfigureEncoder(); + CHK(result); + + return result; +} + +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE VencTest_RegisterYUVBuffer(OMX_BUFFERHEADERTYPE** ppBufferHeader, + OMX_U8 *pBuffer, + OMX_PTR pAppPrivate) +{ + OMX_ERRORTYPE result = OMX_ErrorNone; +#if 0 + D("register buffer"); + if ((result = OMX_AllocateBuffer(m_hHandle, + ppBufferHeader, + (OMX_U32) PORT_INDEX_IN, + pAppPrivate, + m_sProfile.nFrameBytes + )) != OMX_ErrorNone) + { + E("use buffer failed"); + } + else + { + E("Allocate Buffer Success %x", (*ppBufferHeader)->pBuffer); + } + #endif + D("register buffer"); + D("Calling UseBuffer for Input port"); + if ((result = OMX_UseBuffer(m_hHandle, + ppBufferHeader, + (OMX_U32) PORT_INDEX_IN, + pAppPrivate, + m_sProfile.nFrameBytes, + pBuffer)) != OMX_ErrorNone) + { + E("use buffer failed"); + } + + return result; +} +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE VencTest_EncodeFrame(void* pYUVBuff, + long long nTimeStamp) +{ + OMX_ERRORTYPE result = OMX_ErrorUndefined; + D("calling OMX empty this buffer"); + for (int i = 0; i < num_in_buffers; i++) + { + if (pYUVBuff == m_pInBuffers[i]->pBuffer) + { + m_pInBuffers[i]->nTimeStamp = nTimeStamp; + D("Sending Buffer - %x", m_pInBuffers[i]->pBuffer); + result = OMX_EmptyThisBuffer(m_hHandle, + m_pInBuffers[i]); + /* Counting Buffers supplied to OpenMax Encoder */ + if(OMX_ErrorNone == result) + ebd_cnt++; + CHK(result); + break; + } + } + return result; +} +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE VencTest_Exit(void) +{ + int i; + OMX_ERRORTYPE result = OMX_ErrorNone; + D("trying to exit venc"); + + D("going to idle state"); + SetState(OMX_StateIdle); + + + D("going to loaded state"); + //SetState(OMX_StateLoaded); + OMX_SendCommand(m_hHandle, + OMX_CommandStateSet, + (OMX_U32) OMX_StateLoaded, + NULL); + + for (i = 0; i < num_in_buffers; i++) + { + D("free buffer"); + if (m_pInBuffers[i]->pBuffer) + { + // free(m_pInBuffers[i]->pBuffer); + result = OMX_FreeBuffer(m_hHandle, + PORT_INDEX_IN, + m_pInBuffers[i]); + CHK(result); + } + else + { + E("buffer %d is null", i); + result = OMX_ErrorUndefined; + CHK(result); + } + } + for (i = 0; i < num_out_buffers; i++) + { + D("free buffer"); + if (m_pOutBuffers[i]->pBuffer) + { + free(m_pOutBuffers[i]->pBuffer); + result = OMX_FreeBuffer(m_hHandle, + PORT_INDEX_OUT, + m_pOutBuffers[i]); + CHK(result); + + } + else + { + E("buffer %d is null", i); + result = OMX_ErrorUndefined; + CHK(result); + } + } + + while (m_eState != OMX_StateLoaded) + { + sleep(1); + } + D("component_deinit..."); + result = OMX_Deinit(); + CHK(result); + + D("venc is exiting..."); + return result; +} +//////////////////////////////////////////////////////////////////////////////// + +void VencTest_ReadDynamicConfigMsg() +{ + char frame_n[8], config[16], param[8]; + char *dest = frame_n; + bool end = false; + int cntr, nparam = 0; + memset(&dynamic_config, 0, sizeof(struct DynamicConfig)); + do + { + cntr = -1; + do + { + dest[++cntr] = fgetc(m_pDynConfFile); + } while(dest[cntr] != ' ' && dest[cntr] != '\t' && dest[cntr] != '\n' && dest[cntr] != '\r' && !feof(m_pDynConfFile)); + if (dest[cntr] == '\n' || dest[cntr] == '\r') + end = true; + dest[cntr] = NULL; + if (dest == frame_n) + dest = config; + else if (dest == config) + dest = param; + else + end = true; + nparam++; + } while (!end && !feof(m_pDynConfFile)); + + if (nparam > 1) + { + dynamic_config.pending = true; + dynamic_config.frame_num = atoi(frame_n); + if (!strcmp(config, "bitrate")) + { + dynamic_config.config_param = OMX_IndexConfigVideoBitrate; + dynamic_config.config_data.bitrate.nPortIndex = PORT_INDEX_OUT; + dynamic_config.config_data.bitrate.nEncodeBitrate = strtoul(param, NULL, 10); + } + else if (!strcmp(config, "framerate")) + { + dynamic_config.config_param = OMX_IndexConfigVideoFramerate; + dynamic_config.config_data.framerate.nPortIndex = PORT_INDEX_OUT; + dynamic_config.config_data.f_framerate = atof(param); + } + else if (!strcmp(config, "iperiod")) + { + dynamic_config.config_param = (OMX_INDEXTYPE)QOMX_IndexConfigVideoIntraperiod; + dynamic_config.config_data.intraperiod.nPortIndex = PORT_INDEX_OUT; + dynamic_config.config_data.intraperiod.nPFrames = strtoul(param, NULL, 10) - 1; + dynamic_config.config_data.intraperiod.nIDRPeriod = 1; // This value is ignored in OMX component + } + else if (!strcmp(config, "ivoprefresh")) + { + dynamic_config.config_param = OMX_IndexConfigVideoIntraVOPRefresh; + dynamic_config.config_data.intravoprefresh.nPortIndex = PORT_INDEX_OUT; + dynamic_config.config_data.intravoprefresh.IntraRefreshVOP = OMX_TRUE; + } + else if (!strcmp(config, "rotation")) + { + dynamic_config.config_param = OMX_IndexConfigCommonRotate; + dynamic_config.config_data.rotation.nPortIndex = PORT_INDEX_OUT; + dynamic_config.config_data.rotation.nRotation = strtoul(param, NULL, 10); + } + else + { + E("UNKNOWN CONFIG PARAMETER: %s!", config); + dynamic_config.pending = false; + } + } + else if (feof(m_pDynConfFile)) + { + fclose(m_pDynConfFile); + m_pDynConfFile = NULL; + } +} + +void VencTest_ProcessDynamicConfigurationFile() +{ + do + { + if (dynamic_config.pending) + { + if(m_nFrameIn == dynamic_config.frame_num) + { + if (dynamic_config.config_param == OMX_IndexConfigVideoFramerate) + { + m_sProfile.nFramerate = dynamic_config.config_data.f_framerate; + FractionToQ16(dynamic_config.config_data.framerate.xEncodeFramerate, + (int)(m_sProfile.nFramerate * 2), 2); + } + if (OMX_SetConfig(m_hHandle, dynamic_config.config_param, + &dynamic_config.config_data) != OMX_ErrorNone) + E("ERROR: Setting dynamic config to OMX param[0x%x]", dynamic_config.config_param); + dynamic_config.pending = false; + } + else if (m_nFrameIn > dynamic_config.frame_num) + { + E("WARNING: Config change requested in passed frame(%d)", dynamic_config.frame_num); + dynamic_config.pending = false; + } + } + if (!dynamic_config.pending) + VencTest_ReadDynamicConfigMsg(); + } while (!dynamic_config.pending && m_pDynConfFile); +} + +//////////////////////////////////////////////////////////////////////////////// +OMX_ERRORTYPE VencTest_ReadAndEmpty(OMX_BUFFERHEADERTYPE* pYUVBuffer) +{ + OMX_ERRORTYPE result = OMX_ErrorNone; +#ifdef T_ARM +#if defined(MAX_RES_720P) && !defined(_MSM8974_) + if (read(m_nInFd, + pYUVBuffer->pBuffer, + m_sProfile.nFrameBytes) != m_sProfile.nFrameBytes) + { + return OMX_ErrorUndefined; + } +#elif _MSM8974_ + int i, lscanl, lstride, cscanl, cstride, height, width; + int bytes = 0, read_bytes = 0; + OMX_U8 *yuv = pYUVBuffer->pBuffer; + height = m_sProfile.nFrameHeight; + width = m_sProfile.nFrameWidth; + lstride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width); + lscanl = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height); + cstride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width); + cscanl = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height); + + for(i = 0; i < height; i++) { + bytes = read(m_nInFd, yuv, width); + if (bytes != width) { + E("read failed: %d != %d\n", read, width); + return OMX_ErrorUndefined; + } + read_bytes += bytes; + yuv += lstride; + } + yuv = pYUVBuffer->pBuffer + (lscanl * lstride); + for (i = 0; i < ((height + 1) >> 1); i++) { + bytes = read(m_nInFd, yuv, width); + if (bytes != width) { + E("read failed: %d != %d\n", read, width); + return OMX_ErrorUndefined; + } + read_bytes += bytes; + yuv += cstride; + } + m_sProfile.nFrameRead = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); + E("\n\nActual read bytes: %d, NV12 buffer size: %d\n\n\n", read_bytes, m_sProfile.nFrameRead); +#else + OMX_U32 bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight; + // read Y first + if (read(m_nInFd, + pYUVBuffer->pBuffer, + bytestoread) != bytestoread) + return OMX_ErrorUndefined; + + // check alignment for offset to C + OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight; + + const OMX_U32 C_2K = (1024*2), + MASK_2K = C_2K-1, + IMASK_2K = ~MASK_2K; + + if (offset_to_c & MASK_2K) + { + // offset to C is not 2k aligned, adjustment is required + offset_to_c = (offset_to_c & IMASK_2K) + C_2K; + } + + bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2; + // read C + if (read(m_nInFd, + pYUVBuffer->pBuffer + offset_to_c, + bytestoread)!= bytestoread) + return OMX_ErrorUndefined; +#endif +#else + { + char * pInputbuf = (char *)(pYUVBuffer->pBuffer) ; + read(m_nInFd,pInputbuf,m_sProfile.nFrameBytes) ; + + } +#endif + if (m_pDynConfFile) + VencTest_ProcessDynamicConfigurationFile(); + D("about to call VencTest_EncodeFrame..."); + pthread_mutex_lock(&m_mutex); + ++m_nFrameIn; +#ifdef _MSM8974_ + pYUVBuffer->nFilledLen = m_sProfile.nFrameRead; +#else + pYUVBuffer->nFilledLen = m_sProfile.nFrameBytes; +#endif + D("Called Buffer with Data filled length %d",pYUVBuffer->nFilledLen); + + result = VencTest_EncodeFrame(pYUVBuffer->pBuffer, + m_nTimeStamp); + + m_nTimeStamp += (1000000) / m_sProfile.nFramerate; + CHK(result); + pthread_mutex_unlock(&m_mutex); + return result; +} +//////////////////////////////////////////////////////////////////////////////// +void PreviewCallback(int nFD, + int nOffset, + void* pPhys, + void* pVirt, + long long nTimeStamp) +{ + + D("================= preview frame %d, phys=0x%x, nTimeStamp(millis)=%lld", + m_nFrameIn+1, pPhys, (nTimeStamp / 1000)); + + if (m_nFrameIn == m_nFramePlay && + m_nFramePlay != 0) + { + // we will stop camera after last frame is encoded. + // for now just ignore input frames + + CameraTest_ReleaseFrame(pPhys, pVirt); + return; + } + + // see if we should stop + pthread_mutex_lock(&m_mutex); + ++m_nFrameIn; + pthread_mutex_unlock(&m_mutex); + + + if (m_eMode == MODE_LIVE_ENCODE) + { + + OMX_ERRORTYPE result; + + // register new camera buffers with encoder + int i; + for (i = 0; i < num_in_buffers; i++) + { + if (m_pInBuffers[i] != NULL && + m_pInBuffers[i]->pBuffer == pPhys) + { + break; + } + else if (m_pInBuffers[i] == NULL) + { + D("registering buffer..."); + result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i], + (OMX_U8*) pPhys, + (OMX_PTR) pVirt); // store virt in app private field + D("register done"); + CHK(result); + break; + } + } + + if (i == num_in_buffers) + { + E("There are more camera buffers than we thought"); + CHK(1); + } + + // encode the yuv frame + + D("StartEncodeTime=%lld", GetTimeStamp()); + result = VencTest_EncodeFrame(pPhys, + nTimeStamp); + CHK(result); + // FBTest_DisplayImage(nFD, nOffset); + } + else + { + // FBTest_DisplayImage(nFD, nOffset); + CameraTest_ReleaseFrame(pPhys, pVirt); + } +} +//////////////////////////////////////////////////////////////////////////////// +void usage(char* filename) +{ + char* fname = strrchr(filename, (int) '/'); + fname = (fname == NULL) ? filename : fname; + + fprintf(stderr, "usage: %s LIVE \n", fname); + fprintf(stderr, "usage: %s FILE ", fname); + fprintf(stderr, " \n", fname); + fprintf(stderr, "usage: %s PROFILE \n", fname); + fprintf(stderr, "usage: %s PREVIEW \n", fname); + fprintf(stderr, "usage: %s DISPLAY \n", fname); + fprintf(stderr, "\n BITRATE - bitrate in kbps\n"); + fprintf(stderr, " FPS - frames per second\n"); + fprintf(stderr, " NFRAMES - number of frames to play, 0 for infinite\n"); + fprintf(stderr, " RateControl (Values 0 - 4 for RC_OFF, RC_CBR_CFR, RC_CBR_VFR, RC_VBR_CFR, RC_VBR_VFR\n"); + exit(1); +} + +bool parseWxH(char *str, OMX_U32 *width, OMX_U32 *height) +{ + bool parseOK = false; + const char delimiters[] = " x*,"; + char *token, *dupstr, *temp; + OMX_U32 w, h; + + dupstr = strdup(str); + token = strtok_r(dupstr, delimiters, &temp); + if (token) + { + w = strtoul(token, NULL, 10); + token = strtok_r(NULL, delimiters, &temp); + if (token) + { + h = strtoul(token, NULL, 10); + if (w != ULONG_MAX && h != ULONG_MAX) + { +#ifdef MAX_RES_720P + if ((w * h >> 8) <= 3600) + { + parseOK = true; + *width = w; + *height = h; + } +#else + if ((w * h >> 8) <= 8160) + { + parseOK = true; + *width = w; + *height = h; + } +#endif + else + E("\nInvalid dimensions %dx%d",w,h); + } + } + } + free(dupstr); + return parseOK; +} + +//////////////////////////////////////////////////////////////////////////////// +void parseArgs(int argc, char** argv) +{ + int dyn_file_arg = argc; + if (argc == 1) + { + usage(argv[0]); + } + else if (strcmp("PREVIEW", argv[1]) == 0 || + strcmp("preview", argv[1]) == 0) + { + m_eMode = MODE_PREVIEW; + if (argc != 5) + { + usage(argv[0]); + } + } + else if (strcmp("DISPLAY", argv[1]) == 0 || + strcmp("display", argv[1]) == 0) + { + m_eMode = MODE_DISPLAY; + if (argc != 6) + { + usage(argv[0]); + } + m_sProfile.cInFileName = argv[5]; + m_sProfile.cOutFileName = NULL; + } + else if (strcmp("LIVE", argv[1]) == 0 || + strcmp("live", argv[1]) == 0) + {//263 + m_eMode = MODE_LIVE_ENCODE; + if (argc != 8) + { + usage(argv[0]); + } + m_sProfile.cInFileName = NULL; + m_sProfile.cOutFileName = argv[7]; + } + else if (strcmp("FILE", argv[1]) == 0 || + strcmp("file", argv[1]) == 0) + {//263 + m_eMode = MODE_FILE_ENCODE; + + if(argc < 9 || argc > 13) + { + usage(argv[0]); + } + else + { + if (argc > 9) + dyn_file_arg = 9; + + if (argc > 10) + { + m_sProfile.eControlRate = OMX_Video_ControlRateVariable; + int RC = atoi(argv[10]); + + switch (RC) + { + case 0: + m_sProfile.eControlRate = OMX_Video_ControlRateDisable ;//VENC_RC_NONE + break; + case 1: + m_sProfile.eControlRate = OMX_Video_ControlRateConstant;//VENC_RC_CBR_CFR + break; + + case 2: + m_sProfile.eControlRate = OMX_Video_ControlRateConstantSkipFrames;//VENC_RC_CBR_VFR + break; + + case 3: + m_sProfile.eControlRate =OMX_Video_ControlRateVariable ;//VENC_RC_VBR_CFR + break; + + case 4: + m_sProfile.eControlRate = OMX_Video_ControlRateVariableSkipFrames;//VENC_RC_VBR_VFR + break; + + default: + E("invalid rate control selection"); + m_sProfile.eControlRate = OMX_Video_ControlRateVariable; //VENC_RC_VBR_CFR + break; + } + } + + if (argc > 11) + { + int profile_argi = 11; + if(!strcmp(argv[3], "H264") || !strcmp(argv[3], "h264")) + { + profile_argi = 12; + D("\nSetting AVCSliceMode ... "); + int AVCSliceMode = atoi(argv[11]); + switch(AVCSliceMode) + { + case 0: + m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; + break; + + case 1: + m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCMBSlice; + break; + + case 2: + m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCByteSlice; + break; + + default: + E("invalid Slice Mode"); + m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; + break; + } + } + if (profile_argi < argc) + { + if (!strncmp(argv[profile_argi], "0x", 2) || !strncmp(argv[profile_argi], "0x", 2)) + { + m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 16); + } + else + { + m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 10); + } + if (!m_sProfile.nUserProfile || m_sProfile.nUserProfile == ULONG_MAX) + { + E("invalid specified Profile %s, using default", argv[profile_argi]); + m_sProfile.nUserProfile = 0; + } + } + } + } + m_sProfile.cInFileName = argv[7]; + m_sProfile.cOutFileName = argv[8]; + } + else if (strcmp("PROFILE", argv[1]) == 0 || + strcmp("profile", argv[1]) == 0) + {//263 + m_eMode = MODE_PROFILE; + if (argc != 8) + { + usage(argv[0]); + } + m_sProfile.cInFileName = argv[7]; + m_sProfile.cOutFileName = NULL; + } + else + { + usage(argv[0]); + } + + + if (strcmp("QCIF", argv[2]) == 0 || + strcmp("qcif", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 176; + m_sProfile.nFrameHeight = 144; + m_sProfile.nFrameBytes = 176*144*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level0; + } + else if (strcmp("QVGA", argv[2]) == 0 || + strcmp("qvga", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 320; + m_sProfile.nFrameHeight = 240; + m_sProfile.nFrameBytes = 320*240*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } + + + else if (strcmp("VGA", argv[2]) == 0 || + strcmp("vga", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 640; + m_sProfile.nFrameHeight = 480; + m_sProfile.nFrameBytes = 640*480*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } + + else if (strcmp("WVGA", argv[2]) == 0 || + strcmp("wvga", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 800; + m_sProfile.nFrameHeight = 480; + m_sProfile.nFrameBytes = 800*480*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } + else if (strcmp("CIF", argv[2]) == 0 || + strcmp("cif", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 352; + m_sProfile.nFrameHeight = 288; + m_sProfile.nFrameBytes = 352*288*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } + else if (strcmp("720", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 1280; + m_sProfile.nFrameHeight = 720; + m_sProfile.nFrameBytes = 720*1280*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } + else if (strcmp("1080", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 1920; + m_sProfile.nFrameHeight = 1080; + m_sProfile.nFrameBytes = 1920*1080*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } +#ifdef _MSM8974_ + else if (strcmp("4K2K", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 4096; + m_sProfile.nFrameHeight = 2160; + m_sProfile.nFrameBytes = 4096*2160*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } + else if (strcmp("2160P", argv[2]) == 0) + { + m_sProfile.nFrameWidth = 3840; + m_sProfile.nFrameHeight = 2160; + m_sProfile.nFrameBytes = 3840*2160*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } +#endif + else if (parseWxH(argv[2], &m_sProfile.nFrameWidth, &m_sProfile.nFrameHeight)) + { + m_sProfile.nFrameBytes = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight*3/2; + m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; + } + else + { + usage(argv[0]); + } + +#ifdef _MSM8974_ + m_sProfile.nFramestride = (m_sProfile.nFrameWidth + 31) & (~31); + m_sProfile.nFrameScanlines = (m_sProfile.nFrameHeight + 31) & (~31); + m_sProfile.nFrameBytes = ((m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2) + 4095) & (~4095); + m_sProfile.nFrameRead = m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2; +#endif + if (m_eMode == MODE_DISPLAY || + m_eMode == MODE_PREVIEW) + { + m_sProfile.nFramerate = atof(argv[3]); + m_nFramePlay = atoi(argv[4]); + + } + else if (m_eMode == MODE_LIVE_ENCODE || + m_eMode == MODE_FILE_ENCODE || + m_eMode == MODE_PROFILE) + { + if ((!strcmp(argv[3], "MP4")) || (!strcmp(argv[3], "mp4"))) + { + m_sProfile.eCodec = OMX_VIDEO_CodingMPEG4; + } + else if ((!strcmp(argv[3], "H263")) || (!strcmp(argv[3], "h263"))) + { + m_sProfile.eCodec = OMX_VIDEO_CodingH263; + } + else if ((!strcmp(argv[3], "H264")) || (!strcmp(argv[3], "h264"))) + { + m_sProfile.eCodec = OMX_VIDEO_CodingAVC; + } +#ifdef _MSM8974_ + else if ((!strcmp(argv[3], "VP8")) || (!strcmp(argv[3], "vp8"))) + { + m_sProfile.eCodec = OMX_VIDEO_CodingVPX; + } +#endif + else + { + usage(argv[0]); + } + + m_sProfile.nFramerate = atof(argv[4]); + m_sProfile.nBitrate = atoi(argv[5]); +// m_sProfile.eControlRate = OMX_Video_ControlRateVariable; + m_nFramePlay = atoi(argv[6]); + if (dyn_file_arg < argc) + { + m_pDynConfFile = fopen(argv[dyn_file_arg], "r"); + if (!m_pDynConfFile) + E("ERROR: Cannot open dynamic config file: %s", argv[dyn_file_arg]); + else + { + memset(&dynamic_config, 0, sizeof(struct DynamicConfig)); + } + } + } +} + +void* Watchdog(void* data) +{ + while (1) + { + sleep(1000); + if (m_bWatchDogKicked == true) + m_bWatchDogKicked = false; + else + E("watchdog has not been kicked. we may have a deadlock"); + } + return NULL; +} + +int main(int argc, char** argv) +{ + OMX_U8* pvirt = NULL; + int result; + float enc_time_sec=0.0,enc_time_usec=0.0; + + m_nInFd = -1; + m_nOutFd = -1; + m_nTimeStamp = 0; + m_nFrameIn = 0; + m_nFrameOut = 0; + + memset(&m_sMsgQ, 0, sizeof(MsgQ)); + memset(&m_sProfile, 0, sizeof(m_sProfile)); + parseArgs(argc, argv); + + D("fps=%f, bitrate=%u, width=%u, height=%u, frame bytes=%u", + m_sProfile.nFramerate, + m_sProfile.nBitrate, + m_sProfile.nFrameWidth, + m_sProfile.nFrameHeight, + m_sProfile.nFrameBytes); +#ifdef _MSM8974_ + D("Frame stride=%u, scanlines=%u, read=%u", + m_sProfile.nFramestride, + m_sProfile.nFrameScanlines, + m_sProfile.nFrameRead); +#endif + + + //if (m_eMode != MODE_PREVIEW && m_eMode != MODE_DISPLAY) + //{ + // pthread_t wd; + // pthread_create(&wd, NULL, Watchdog, NULL); + //} + + for (int x = 0; x < num_in_buffers; x++) + { + // mark all buffers as ready to use + m_bInFrameFree[x] = OMX_TRUE; + } + + + if (m_eMode != MODE_PROFILE) + { + #if T_ARM + m_nOutFd = open(m_sProfile.cOutFileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); + #else + m_nOutFd = open(m_sProfile.cOutFileName,0); + #endif + if (m_nOutFd < 0) + { + E("could not open output file %s", m_sProfile.cOutFileName); + CHK(1); + } + } + + pthread_mutex_init(&m_mutex, NULL); + pthread_cond_init(&m_signal, NULL); + + if (m_eMode != MODE_PREVIEW) + { + VencTest_Initialize(); + } + + //////////////////////////////////////// + // Camera + Encode + //////////////////////////////////////// + if (m_eMode == MODE_LIVE_ENCODE) + { + CameraTest_Initialize(m_sProfile.nFramerate, + m_sProfile.nFrameWidth, + m_sProfile.nFrameHeight, + PreviewCallback); + CameraTest_Run(); + } + + if (m_eMode == MODE_FILE_ENCODE || + m_eMode == MODE_PROFILE) + { + int i; + #if T_ARM + m_nInFd = open(m_sProfile.cInFileName, O_RDONLY); + #else + m_nInFd = open(m_sProfile.cInFileName,1); + #endif + if (m_nInFd < 0) + { + E("could not open input file"); + CHK(1); + + } + D("going to idle state"); + //SetState(OMX_StateIdle); + OMX_SendCommand(m_hHandle, + OMX_CommandStateSet, + (OMX_U32) OMX_StateIdle, + NULL); + + OMX_PARAM_PORTDEFINITIONTYPE portDef; + + portDef.nPortIndex = 0; + result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef); + CHK(result); + + D("allocating Input buffers"); + num_in_buffers = portDef.nBufferCountActual; + for (i = 0; i < portDef.nBufferCountActual; i++) + { + OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem = new OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO; + pvirt = (OMX_U8*)PmemMalloc(pMem, m_sProfile.nFrameBytes); + + if(pvirt == NULL) + { + CHK(1); + } + result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i], + (OMX_U8*) pvirt, + (OMX_PTR) pMem); + CHK(result); + } + } + else if (m_eMode == MODE_LIVE_ENCODE) + { + D("going to idle state"); + //SetState(OMX_StateIdle); + OMX_SendCommand(m_hHandle, + OMX_CommandStateSet, + (OMX_U32) OMX_StateIdle, + NULL); + } + + int i; + OMX_PARAM_PORTDEFINITIONTYPE portDef; + + portDef.nPortIndex = 1; + result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef); + CHK(result); + + D("allocating & calling usebuffer for Output port"); + num_out_buffers = portDef.nBufferCountActual; + for (i = 0; i < portDef.nBufferCountActual; i++) + { + void* pBuff; + + pBuff = malloc(portDef.nBufferSize); + D("portDef.nBufferSize = %d ",portDef.nBufferSize); + result = OMX_UseBuffer(m_hHandle, + &m_pOutBuffers[i], + (OMX_U32) PORT_INDEX_OUT, + NULL, + portDef.nBufferSize, + (OMX_U8*) pBuff); + CHK(result); + } + D("allocate done"); + + // D("Going to state " # eState"..."); + + while (m_eState != OMX_StateIdle) + { + sleep(1); + } + //D("Now in state " # eState); + + + D("going to executing state"); + SetState(OMX_StateExecuting); + for (i = 0; i < num_out_buffers; i++) + { + D("filling buffer %d", i); + result = OMX_FillThisBuffer(m_hHandle, m_pOutBuffers[i]); + //sleep(1000); + CHK(result); + } + + if (m_eMode == MODE_FILE_ENCODE) + { + // encode the first frame to kick off the whole process + VencTest_ReadAndEmpty(m_pInBuffers[0]); + // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[0]->pAppPrivate)->fd,0); + } + + if (m_eMode == MODE_PROFILE) + { + int i; + + // read several frames into memory + D("reading frames into memory"); + for (i = 0; i < num_in_buffers; i++) + { + D("[%d] address 0x%x",i, m_pInBuffers[i]->pBuffer); +#ifdef MAX_RES_720P + read(m_nInFd, + m_pInBuffers[i]->pBuffer, + m_sProfile.nFrameBytes); +#else + // read Y first + read(m_nInFd, + m_pInBuffers[i]->pBuffer, + m_sProfile.nFrameWidth*m_sProfile.nFrameHeight); + + // check alignment for offset to C + OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight; + + const OMX_U32 C_2K = (1024*2), + MASK_2K = C_2K-1, + IMASK_2K = ~MASK_2K; + + if (offset_to_c & MASK_2K) + { + // offset to C is not 2k aligned, adjustment is required + offset_to_c = (offset_to_c & IMASK_2K) + C_2K; + } + + // read C + read(m_nInFd, + m_pInBuffers[i]->pBuffer + offset_to_c, + m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2); +#endif + + } + + // FBTest_Initialize(m_sProfile.nFrameWidth, m_sProfile.nFrameHeight); + + // loop over the mem-resident frames and encode them + D("beging playing mem-resident frames..."); + for (i = 0; m_nFramePlay == 0 || i < m_nFramePlay; i++) + { + int idx = i % num_in_buffers; + if (m_bInFrameFree[idx] == OMX_FALSE) + { + int j; + E("the expected buffer is not free, but lets find another"); + + idx = -1; + + // lets see if we can find another free buffer + for (j = 0; j < num_in_buffers; j++) + { + if(m_bInFrameFree[j]) + { + idx = j; + break; + } + } + } + + // if we have a free buffer let's encode it + if (idx >= 0) + { + D("encode frame %d...m_pInBuffers[idx]->pBuffer=0x%x", i,m_pInBuffers[idx]->pBuffer); + m_bInFrameFree[idx] = OMX_FALSE; + VencTest_EncodeFrame(m_pInBuffers[idx]->pBuffer, + m_nTimeStamp); + D("display frame %d...", i); + // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[idx]->pAppPrivate)->fd,0); + m_nTimeStamp += 1000000 / m_sProfile.nFramerate; + } + else + { + E("wow, no buffers are free, performance " + "is not so good. lets just sleep some more"); + + } + D("sleep for %d microsec", 1000000/m_sProfile.nFramerate); + sleep (1000000 / m_sProfile.nFramerate); + } + // FBTest_Exit(); + } + + Msg msg; + bool bQuit = false; + while ((m_eMode == MODE_FILE_ENCODE || m_eMode == MODE_LIVE_ENCODE) && + !bQuit) + { + PopMessage(&msg); + switch (msg.id) + { + ////////////////////////////////// + // FRAME IS ENCODED + ////////////////////////////////// + case MSG_ID_INPUT_FRAME_DONE: + /*pthread_mutex_lock(&m_mutex); + ++m_nFrameOut; + if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0) + { + bQuit = true; + } + pthread_mutex_unlock(&m_mutex);*/ + + if (!bQuit && m_eMode == MODE_FILE_ENCODE) + { + D("pushing another frame down to encoder"); + if (VencTest_ReadAndEmpty(msg.data.sBitstreamData.pBuffer)) + { + // we have read the last frame + D("main is exiting..."); + bQuit = true; + } + } + break; + case MSG_ID_OUTPUT_FRAME_DONE: + D("================ writing frame %d = %d bytes to output file", + m_nFrameOut+1, + msg.data.sBitstreamData.pBuffer->nFilledLen); + D("StopEncodeTime=%lld", GetTimeStamp()); + + + write(m_nOutFd, + msg.data.sBitstreamData.pBuffer->pBuffer, + msg.data.sBitstreamData.pBuffer->nFilledLen); + + + result = OMX_FillThisBuffer(m_hHandle, + msg.data.sBitstreamData.pBuffer); + + if (result != OMX_ErrorNone) + { + CHK(result); + } + + pthread_mutex_lock(&m_mutex); + ++m_nFrameOut; + if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0) + { + bQuit = true; + } + pthread_mutex_unlock(&m_mutex); + break; + + default: + E("invalid msg id %d", (int) msg.id); + } // end switch (msg.id) + +/* // TO UNCOMMENT FOR PAUSE TESTINGS + if(m_nFrameOut == 10) + { + E("\nGoing to Pause state\n"); + SetState(OMX_StatePause); + sleep(3); +//REQUEST AN I FRAME AFTER PAUSE + OMX_CONFIG_INTRAREFRESHVOPTYPE voprefresh; + voprefresh.nPortIndex = (OMX_U32)PORT_INDEX_OUT; + voprefresh.IntraRefreshVOP = OMX_TRUE; + result = OMX_SetConfig(m_hHandle, + OMX_IndexConfigVideoIntraVOPRefresh, + &voprefresh); + E("\n OMX_IndexConfigVideoIntraVOPRefresh Set Paramter port"); + CHK(result); + E("\nGoing to executing state\n"); + SetState(OMX_StateExecuting); + } +*/ + } // end while (!bQuit) + + + if (m_eMode == MODE_LIVE_ENCODE) + { + CameraTest_Exit(); + close(m_nOutFd); + } + else if (m_eMode == MODE_FILE_ENCODE || + m_eMode == MODE_PROFILE) + { + // deallocate pmem buffers + for (int i = 0; i < num_in_buffers; i++) + { + PmemFree((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)m_pInBuffers[i]->pAppPrivate, + m_pInBuffers[i]->pBuffer, + m_sProfile.nFrameBytes); + delete (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*) m_pInBuffers[i]->pAppPrivate; + } + close(m_nInFd); + + if (m_eMode == MODE_FILE_ENCODE) + { + close(m_nOutFd); + } + if (m_pDynConfFile) + { + fclose(m_pDynConfFile); + m_pDynConfFile = NULL; + } + } + + if (m_eMode != MODE_PREVIEW) + { + D("exit encoder test"); + VencTest_Exit(); + } + + pthread_mutex_destroy(&m_mutex); + pthread_cond_destroy(&m_signal); + + /* Time Statistics Logging */ + if(0 != m_sProfile.nFramerate) + { + enc_time_usec = m_nTimeStamp - (1000000 / m_sProfile.nFramerate); + enc_time_sec =enc_time_usec/1000000; + if(0 != enc_time_sec) + { + printf("Total Frame Rate: %f",ebd_cnt/enc_time_sec); + printf("\nEncoder Bitrate :%lf Kbps",(tot_bufsize*8)/(enc_time_sec*1000)); + } + } + else + { + printf("\n\n Encode Time is zero"); + } + printf("\nTotal Number of Frames :%d",ebd_cnt); + printf("\nNumber of dropped frames during encoding:%d\n",ebd_cnt-fbd_cnt); + /* End of Time Statistics Logging */ + + D("main has exited"); + return 0; +} diff --git a/mm-video-v4l2/vidc/venc/test/venc_util.c b/mm-video-v4l2/vidc/venc/test/venc_util.c new file mode 100755 index 00000000..4e4688e8 --- /dev/null +++ b/mm-video-v4l2/vidc/venc/test/venc_util.c @@ -0,0 +1,51 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +/*============================================================================ + V E N C _ U T I L. C + +DESCRIPTION + + +REFERENCES + +============================================================================*/ + +#include "venc_util.h" +#include +#include + +long long GetTimeStamp() +{ + struct timeval tv; + long long microsec; + gettimeofday(&tv, NULL); + microsec = (tv.tv_sec * 1000000) + (tv.tv_usec); + return microsec; + +} + diff --git a/mm-video-v4l2/vidc/venc/test/video_encoder_test.c b/mm-video-v4l2/vidc/venc/test/video_encoder_test.c new file mode 100755 index 00000000..567d081b --- /dev/null +++ b/mm-video-v4l2/vidc/venc/test/video_encoder_test.c @@ -0,0 +1,1064 @@ +/*-------------------------------------------------------------------------- +Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of The Linux Foundation nor + the names of its contributors may be used to endorse or promote + products derived from this software without specific prior written + permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------*/ +#include "video_encoder_test.h" + +#define DEBUG_PRINT printf +/************************************************************************/ +/* #DEFINES */ +/************************************************************************/ + +#define VOP_START_CODE 0x000001B6 +#define SHORT_HEADER_START_CODE 0x00008000 +#define H264_START_CODE 0x00000001 + +/************************************************************************/ +/* STATIC VARIABLES */ +/************************************************************************/ + +static int Code_type; +static int total_frames = 0; +static unsigned int header_code = 0; +static pthread_mutex_t read_lock; + +static unsigned int read_frame ( unsigned char *dataptr,unsigned int length, + FILE * inputBufferFile + ); +static unsigned clp2(unsigned x) +{ + x = x - 1; + x = x | (x >> 1); + x = x | (x >> 2); + x = x | (x >> 4); + x = x | (x >> 8); + x = x | (x >>16); + return x + 1; +} + + +static void* video_thread (void *); +static void* async_thread (void *); + + + +int main (int argc, char **argv) +{ + struct video_encoder_context *encoder_context = NULL; + char *file_name = NULL; + FILE *file_ptr = NULL; + int temp1 =0,temp2 =0; + int error = 1; + unsigned int i = 0; + + file_name = argv [1]; + file_ptr = fopen (file_name,"rb"); + + if (file_ptr == NULL) + { + DEBUG_PRINT("\n File is not located "); + return -1; + } + + + encoder_context = (struct video_encoder_context *) \ + calloc (sizeof (struct video_encoder_context),1); + if (encoder_context == NULL) + { + return -1; + } + encoder_context->outputBufferFile = NULL; + encoder_context->inputBufferFile = NULL; + encoder_context->video_driver_fd = -1; + encoder_context->inputBufferFile = file_ptr; + encoder_context->input_width = 176; + encoder_context->input_height = 144; + encoder_context->codectype = VEN_CODEC_MPEG4; + encoder_context->fps_num = 60; + encoder_context->fps_den = 2; + encoder_context->inputformat = VEN_INPUTFMT_NV12; + encoder_context->targetbitrate = 128000; + + file_ptr = fopen ("/data/output.m4v","wb"); + if (file_ptr == NULL) + { + DEBUG_PRINT("\n File can't be created"); + free (encoder_context); + return -1; + } + encoder_context->outputBufferFile = file_ptr; + + switch (atoi(argv[2])) + { + case 0: + DEBUG_PRINT("\n MPEG4 codec selected"); + encoder_context->codectype = VEN_CODEC_MPEG4; + Code_type = 0; + break; + case 1: + DEBUG_PRINT("\n H.263"); + encoder_context->codectype = VEN_CODEC_H263; + Code_type = 0; + break; + case 2: + DEBUG_PRINT("\n H.264"); + encoder_context->codectype = VEN_CODEC_H264; + Code_type = 1; + break; + default: + DEBUG_PRINT("\n Wrong codec type"); + error = -1; + break; + } + + if (error != -1) + { + temp1 = atoi(argv[3]); + temp2 = atoi(argv[4]); + + if (((temp1%16) != 0) || ((temp2%16) != 0)) + { + error = -1; + } + else + { + encoder_context->input_width = temp1; + encoder_context->input_height = temp2; + } + } + + switch (atoi(argv[5])) + { + case 0: + DEBUG_PRINT("\n No Sink"); + encoder_context->outputBufferFile = NULL; + break; + } + + if (error != -1) + { + encoder_context->targetbitrate = atoi (argv[6]); + } + + if ( error != -1 && (init_encoder (encoder_context) == -1 )) + { + DEBUG_PRINT("\n Init decoder fails "); + error = -1; + } + DEBUG_PRINT("\n Decoder open successfull"); + + + /*Allocate input and output buffers*/ + if (error != -1 && (allocate_buffer (0,encoder_context)== -1)) + { + DEBUG_PRINT("\n Error in input Buffer allocation"); + error = -1; + } + + if (error != -1 && (allocate_buffer (1,encoder_context)== -1)) + { + DEBUG_PRINT("\n Error in output Buffer allocation"); + error = -1; + } + + + if (error != -1 && (start_encoding (encoder_context) == -1)) + { + DEBUG_PRINT("\n Error in start decoding call"); + error = -1; + } + + if (error != -1 && (stop_encoding (encoder_context) == -1)) + { + DEBUG_PRINT("\n Error in stop decoding call"); + error = -1; + } + + DEBUG_PRINT("\n De-init the decoder"); + if ((deinit_encoder (encoder_context) == -1)) + { + error = -1; + } + + + (void)free_buffer (INPUT_BUFFER,encoder_context); + (void)free_buffer (OUTPUT_BUFFER,encoder_context); + + if (encoder_context->inputBufferFile != NULL) + { + fclose (encoder_context->inputBufferFile); + } + if (encoder_context->outputBufferFile != NULL) + { + fclose (encoder_context->outputBufferFile); + } + DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames); + DEBUG_PRINT("\n closing the driver"); + free (encoder_context); + + return error; +} + +int init_encoder ( struct video_encoder_context *init_decode ) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_basecfg basecfg; + struct video_queue_context *queue_ptr = NULL; + struct venc_ratectrlcfg ratecrl; + pthread_mutexattr_t init_values; + struct venc_profile profile; + struct ven_profilelevel profilelevel; + + DEBUG_PRINT("\n Before calling the open"); + + init_decode->video_driver_fd = open ("/dev/msm_vidc_enc", \ + O_RDWR | O_NONBLOCK); + + + + if (init_decode->video_driver_fd < 0) + { + DEBUG_PRINT("\n Open failed"); + return -1; + } + + basecfg.codectype = init_decode->codectype; + basecfg.dvs_height = 0; + basecfg.dvs_width = 0; + basecfg.fps_den = init_decode->fps_den; + basecfg.fps_num = init_decode->fps_num; + basecfg.input_height = init_decode->input_height; + basecfg.input_width = init_decode->input_width; + basecfg.inputformat = init_decode->inputformat; + basecfg.targetbitrate = init_decode->targetbitrate; + + /*Initialize Decoder with codec type and resolution*/ + ioctl_msg.in = &basecfg; + ioctl_msg.out = NULL; + + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_BASE_CFG, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set base config type failed"); + return -1; + } + + /*Initialize Decoder with codec type and resolution*/ + DEBUG_PRINT ("\n Switch off rate control"); + ioctl_msg.in = &ratecrl; + ioctl_msg.out = NULL; + ratecrl.rcmode = VEN_RC_OFF; + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set rate control failed"); + return -1; + } + + if (basecfg.codectype == VEN_CODEC_H264) + { + DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); + ioctl_msg.in = &profile; + ioctl_msg.out = NULL; + profile.profile = VEN_PROFILE_H264_BASELINE; + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); + return -1; + } + + DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); + ioctl_msg.in = &profilelevel; + ioctl_msg.out = NULL; + profilelevel.level = VEN_LEVEL_H264_1p1; + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); + return -1; + } + + if (basecfg.input_width > 720) + { + DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); + ioctl_msg.in = &profile; + ioctl_msg.out = NULL; + profile.profile = VEN_PROFILE_H264_HIGH; + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); + return -1; + } + + DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); + ioctl_msg.in = &profilelevel; + ioctl_msg.out = NULL; + profilelevel.level = VEN_LEVEL_H264_3p1; + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); + return -1; + } + } + } + + DEBUG_PRINT("\n Query Input bufffer requirements"); + /*Get the Buffer requirements for input and output ports*/ + + + + ioctl_msg.in = NULL; + ioctl_msg.out = &init_decode->input_buffer; + + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Requesting for input buffer requirements failed"); + return -1; + } + + DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \ + (int)init_decode->input_buffer.datasize,\ + (int)init_decode->input_buffer.mincount,\ + (int)init_decode->input_buffer.actualcount); + + + ioctl_msg.in = &init_decode->input_buffer; + ioctl_msg.out = NULL; + init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2; + + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Set Buffer Requirements Failed"); + return -1; + } + + + DEBUG_PRINT("\n Query output bufffer requirements"); + ioctl_msg.in = NULL; + ioctl_msg.out = &init_decode->output_buffer; + + if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ, + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Requesting for output buffer requirements failed"); + return -1; + } + + DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \ + (int)init_decode->output_buffer.datasize,\ + (int)init_decode->output_buffer.mincount,\ + (int)init_decode->output_buffer.actualcount); + + /*Create Queue related data structures*/ + queue_ptr = &init_decode->queue_context; + queue_ptr->commandq_size = 50; + queue_ptr->dataq_size = 50; + + sem_init(&queue_ptr->sem_message,0, 0); + sem_init(&init_decode->sem_synchronize,0, 0); + + pthread_mutexattr_init (&init_values); + pthread_mutex_init (&queue_ptr->mutex,&init_values); + pthread_mutex_init (&read_lock,&init_values); + DEBUG_PRINT("\n create Queues"); + queue_ptr->ptr_cmdq = (struct video_msgq*) \ + calloc (sizeof (struct video_msgq), + queue_ptr->commandq_size); + queue_ptr->ptr_dataq = (struct video_msgq*) \ + calloc (sizeof (struct video_msgq), + queue_ptr->dataq_size + ); + + if ( queue_ptr->ptr_cmdq == NULL || + queue_ptr->ptr_dataq == NULL + ) + { + return -1; + } + DEBUG_PRINT("\n create Threads"); + /*Create two threads*/ + if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread, + init_decode) < 0) || + (pthread_create (&init_decode->asyncthread_id,NULL,async_thread, + init_decode) < 0) + ) + { + return -1; + } + + return 1; +} + + + +int free_buffer ( unsigned int buffer_dir, + struct video_encoder_context *encoder_context + ) +{ + unsigned int buffercount = 0,i=0; + struct venc_bufferpayload **ptemp = NULL; + + if (encoder_context == NULL) + { + return -1; + } + + if (buffer_dir == INPUT_BUFFER && encoder_context->ptr_inputbuffer) + { + buffercount = encoder_context->input_buffer.actualcount; + ptemp = encoder_context->ptr_inputbuffer; + + for (i=0;ifd != -1) + { + munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size); + ptemp [i]->pbuffer = NULL; + close (ptemp [i]->fd); + } + free (ptemp [i]); + ptemp [i] = NULL; + } + } + free (encoder_context->ptr_inputbuffer); + encoder_context->ptr_inputbuffer = NULL; + } + else if ( buffer_dir == OUTPUT_BUFFER && encoder_context->ptr_outputbuffer ) + { + buffercount = encoder_context->output_buffer.actualcount; + ptemp = encoder_context->ptr_outputbuffer; + + if (ptemp) + { + for (i=0;ifd != -1) + { + munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size); + ptemp [i]->pbuffer = NULL; + close (ptemp [i]->fd); + } + free (ptemp [i]); + ptemp [i] = NULL; + } + } + free (ptemp); + encoder_context->ptr_outputbuffer = NULL; + } + } + + return 1; +} + +int allocate_buffer ( unsigned int buffer_dir, + struct video_encoder_context *encoder_context + ) +{ + struct venc_bufferpayload **ptemp = NULL; + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + unsigned int buffercount = 0,i=0,alignedsize=0; + unsigned int buffersize = 0; + + if ( encoder_context == NULL) + { + DEBUG_PRINT ("\nallocate_buffer: context is NULL"); + return -1; + } + + if ( buffer_dir == INPUT_BUFFER ) + { + /*Check if buffers are allocated*/ + if (encoder_context->ptr_inputbuffer != NULL) + { + DEBUG_PRINT ("\nallocate_buffer: encoder_context->ptr_inputbuffer is set"); + return -1; + } + + buffercount = encoder_context->input_buffer.actualcount; + alignedsize = encoder_context->input_buffer.alignment; + buffersize = encoder_context->input_buffer.datasize; + buffersize = (buffersize + alignedsize) & (~alignedsize); + } + else if (buffer_dir == OUTPUT_BUFFER) + { + /*Check if buffers are allocated*/ + if (encoder_context->ptr_outputbuffer != NULL) + { + DEBUG_PRINT ("\nallocate_buffer: Double allcoate output"); + return -1; + } + + buffercount = encoder_context->output_buffer.actualcount; + alignedsize = encoder_context->output_buffer.alignment; + buffersize = encoder_context->output_buffer.datasize; + buffersize = (buffersize + alignedsize) & (~alignedsize); + + } + else + { + DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions"); + return -1; + } + + ptemp = (struct venc_bufferpayload **)\ + calloc (sizeof (struct venc_bufferpayload *),buffercount); + + if (ptemp == NULL) + { + DEBUG_PRINT ("\nallocate_buffer: venc_bufferpayload failure"); + return -1; + } + + + if (buffer_dir == OUTPUT_BUFFER) + { + DEBUG_PRINT ("\nallocate_buffer: OUT"); + encoder_context->ptr_outputbuffer = ptemp; + } + else + { + DEBUG_PRINT ("\nallocate_buffer: IN"); + encoder_context->ptr_inputbuffer = ptemp; + } + + /*Allocate buffer headers*/ + for (i=0; i< buffercount; i++) + { + ptemp [i] = (struct venc_bufferpayload*)\ + calloc (sizeof (struct venc_bufferpayload),1); + + if (ptemp [i] == NULL) + { + DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure"); + return -1; + } + ptemp [i]->fd = -1; + } + + for (i=0; i< buffercount; i++) + { + ptemp [i]->fd = open ("/dev/pmem_adsp",O_RDWR); + + if (ptemp [i]->fd < 0) + { + DEBUG_PRINT ("\nallocate_buffer: open pmem_adsp failed"); + return -1; + } + + ptemp [i]->pbuffer = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE, + MAP_SHARED,ptemp [i]->fd,0); + DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->fd,\ + ptemp [i]->pbuffer); + if (ptemp [i]->pbuffer == MAP_FAILED) + { + ptemp [i]->pbuffer = NULL; + DEBUG_PRINT ("\nallocate_buffer: MMAP failed"); + return -1; + } + ptemp [i]->sz = buffersize; + ptemp [i]->maped_size = clp2 (buffersize); + + ioctl_msg.in = ptemp [i]; + ioctl_msg.out = NULL; + + if (buffer_dir == OUTPUT_BUFFER) + { + if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER, + &ioctl_msg) < 0) + { + DEBUG_PRINT ("\nallocate_buffer: Set Output Buffer IOCTL failed"); + return -1; + } + } + else + { + if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER, + &ioctl_msg) < 0) + { + DEBUG_PRINT ("\nallocate_buffer: Set input Buffer IOCTL failed"); + return -1; + } + } + + } + DEBUG_PRINT ("\nallocate_buffer: Success"); + return 1; +} + + + +int start_encoding (struct video_encoder_context *encoder_context) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_buffer enc_buffer; + unsigned int i = 0; + unsigned int data_len =0; + + + if (encoder_context == NULL) + { + return -1; + } + + if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_START, + NULL) < 0) + { + DEBUG_PRINT("\n Start failed"); + return -1; + } + + DEBUG_PRINT("\n Start Issued successfully waiting for Start Done"); + /*Wait for Start command response*/ + sem_wait (&encoder_context->sem_synchronize); + + /*Push output Buffers*/ + i = 0; + while (i < encoder_context->output_buffer.actualcount) + { + enc_buffer.clientdata = (void *)encoder_context->ptr_outputbuffer [i]; + enc_buffer.flags = 0; + enc_buffer.sz = encoder_context->ptr_outputbuffer [i]->sz; + enc_buffer.len = 0; + enc_buffer.ptrbuffer = encoder_context->ptr_outputbuffer [i]->pbuffer; + enc_buffer.offset = 0; + enc_buffer.timestamp = 0; + + DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata); + ioctl_msg.in = &enc_buffer; + ioctl_msg.out = NULL; + + if (ioctl (encoder_context->video_driver_fd, + VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT("\n fill output frame failed"); + return -1; + } + i++; + } + + + /*push input buffers*/ + i = 0; + while (i < encoder_context->input_buffer.actualcount) + { + DEBUG_PRINT("\n Read Frame from File"); + + enc_buffer.clientdata = (void *)encoder_context->ptr_inputbuffer [i]; + enc_buffer.flags = 0; + enc_buffer.sz = encoder_context->ptr_inputbuffer [i]->sz; + enc_buffer.len = 0; + enc_buffer.ptrbuffer = encoder_context->ptr_inputbuffer [i]->pbuffer; + enc_buffer.offset = 0; + enc_buffer.timestamp = total_frames * + ((encoder_context->fps_den * 1000000)/encoder_context->fps_num); + enc_buffer.len = (encoder_context->input_height * + encoder_context->input_width *3)/2; + data_len = read_frame ( enc_buffer.ptrbuffer, + enc_buffer.len, + encoder_context->inputBufferFile); + if (data_len == 0) + { + DEBUG_PRINT("\n Length is zero error"); + return -1; + } + enc_buffer.len = data_len; + DEBUG_PRINT("\n Read Frame from File szie = %d",(int)data_len); + + DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata); + ioctl_msg.in = &enc_buffer; + ioctl_msg.out = NULL; + + if (ioctl (encoder_context->video_driver_fd, + VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Encode input frame failed"); + return -1; + } + total_frames++; + i++; + } + DEBUG_PRINT ("\n Wait for EOS"); + /*Wait for EOS or Error condition*/ + sem_wait (&encoder_context->sem_synchronize); + DEBUG_PRINT ("\n Reached EOS"); + + return 1; +} + +int stop_encoding (struct video_encoder_context *encoder_context) +{ + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_bufferflush buffer_flush; + + if (encoder_context == NULL) + { + return -1; + } + buffer_flush.flush_mode = VEN_FLUSH_INPUT; + ioctl_msg.in = &buffer_flush; + ioctl_msg.out = NULL; + + if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH, + &ioctl_msg) < 0) + { + DEBUG_PRINT("\n Flush input failed"); + } + else + { + sem_wait (&encoder_context->sem_synchronize); + } + + buffer_flush.flush_mode = VEN_FLUSH_OUTPUT; + ioctl_msg.in = &buffer_flush; + ioctl_msg.out = NULL; + + if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH, + &ioctl_msg) < 0) + { + DEBUG_PRINT("\n Flush output failed"); + } + else + { + sem_wait (&encoder_context->sem_synchronize); + } + + DEBUG_PRINT("\n Stop VEN_IOCTL_CMD_STOP"); + if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_STOP,NULL) < 0) + { + DEBUG_PRINT("\n Stop failed"); + } + else + { + sem_wait (&encoder_context->sem_synchronize); + } + return 1; +} + +int deinit_encoder (struct video_encoder_context *init_decode) +{ + if (init_decode == NULL) + { + return -1; + } + + /*Close the driver*/ + if (init_decode->video_driver_fd != -1) + { + close (init_decode->video_driver_fd); + } + + if (init_decode->queue_context.ptr_cmdq) + { + free (init_decode->queue_context.ptr_cmdq); + init_decode->queue_context.ptr_cmdq = NULL; + } + + if (init_decode->queue_context.ptr_dataq) + { + free (init_decode->queue_context.ptr_dataq); + init_decode->queue_context.ptr_dataq = NULL; + } + + sem_destroy (&init_decode->queue_context.sem_message); + sem_destroy (&init_decode->sem_synchronize); + + pthread_mutex_destroy(&init_decode->queue_context.mutex); + pthread_mutex_destroy (&read_lock); + + return 1; +} + +static void* video_thread (void *context) +{ + struct video_encoder_context *encoder_context = NULL; + struct video_msgq *queueitem = NULL; + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + struct venc_bufferpayload *tempbuffer = NULL; + struct venc_buffer enc_buffer; + unsigned int data_len =0; + + + if (context == NULL) + { + DEBUG_PRINT("\n video thread recieved NULL context"); + return NULL; + } + encoder_context = (struct video_encoder_context *) context; + + /* Thread function which will accept commands from async thread + * or main thread + */ + while (1) + { + queueitem = queue_get_cmd (&encoder_context ->queue_context); + if (queueitem != NULL) + { + switch (queueitem->cmd) + { + case VEN_MSG_START: + DEBUG_PRINT("\n recived start done command"); + sem_post (&encoder_context->sem_synchronize); + break; + + case VEN_MSG_STOP: + DEBUG_PRINT("\n recieved stop done"); + sem_post (&encoder_context->sem_synchronize); + break; + + case VEN_MSG_INPUT_BUFFER_DONE: + + tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata; + if (tempbuffer == NULL) + { + DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); + sem_post (&encoder_context->sem_synchronize); + break; + } + tempbuffer->filled_len = (encoder_context->input_height * + encoder_context->input_width *3)/2; + + data_len = read_frame ( tempbuffer->pbuffer, + tempbuffer->filled_len, + encoder_context->inputBufferFile); + + if (data_len == 0) + { + DEBUG_PRINT ("\n End of stream reached"); + sem_post (&encoder_context->sem_synchronize); + break; + } + enc_buffer.clientdata = (void *)tempbuffer; + enc_buffer.flags = 0; + enc_buffer.ptrbuffer = tempbuffer->pbuffer; + enc_buffer.sz = tempbuffer->sz; + enc_buffer.len = tempbuffer->filled_len; + enc_buffer.offset = 0; + enc_buffer.timestamp = total_frames * + ((encoder_context->fps_den * 1000000)/encoder_context->fps_num); + + /*TODO: Time stamp needs to be updated*/ + ioctl_msg.in = &enc_buffer; + ioctl_msg.out = NULL; + total_frames++; + if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_ENCODE_FRAME, + &ioctl_msg) < 0) + { + DEBUG_PRINT("\n Decoder frame failed"); + sem_post (&encoder_context->sem_synchronize); + } + DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\ + total_frames); + break; + + case VEN_MSG_OUTPUT_BUFFER_DONE: + + tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata; + if (tempbuffer == NULL) + { + DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); + sem_post (&encoder_context->sem_synchronize); + break; + } + + if (encoder_context->outputBufferFile != NULL) + { + fwrite (tempbuffer->pbuffer,1,tempbuffer->filled_len, + encoder_context->outputBufferFile); + } + + + DEBUG_PRINT("\n recieved output buffer consume outbuffer"); + DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\ + tempbuffer->pbuffer); + enc_buffer.clientdata = (void *)tempbuffer; + enc_buffer.flags = 0; + enc_buffer.sz = tempbuffer->sz; + enc_buffer.len = 0; + enc_buffer.ptrbuffer = tempbuffer->pbuffer; + enc_buffer.offset = 0; + enc_buffer.timestamp = 0; + + ioctl_msg.in = &enc_buffer; + ioctl_msg.out = NULL; + + if (ioctl (encoder_context->video_driver_fd, + VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Decoder frame failed"); + return NULL; + } + + break; + + case VEN_MSG_FLUSH_INPUT_DONE: + DEBUG_PRINT("\n Flush input complete"); + sem_post (&encoder_context->sem_synchronize); + break; + + case VEN_MSG_FLUSH_OUPUT_DONE: + DEBUG_PRINT("\n Flush output complete"); + sem_post (&encoder_context->sem_synchronize); + break; + } + + if (queueitem->cmd == VEN_MSG_STOP) + { + DEBUG_PRINT("\n Playback has ended thread will exit"); + return NULL; + } + } + else + { + DEBUG_PRINT("\n Error condition recieved NULL from Queue"); + } + + } +} + +static void* async_thread (void *context) +{ + struct video_encoder_context *encoder_context = NULL; + struct video_msgq queueitem ; + struct venc_msg venc_msg; + struct venc_bufferpayload *tempbuffer = NULL; + struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; + int result = -1; + + if (context == NULL) + { + DEBUG_PRINT("\n aynsc thread recieved NULL context"); + return NULL; + } + encoder_context = (struct video_encoder_context *) context; + DEBUG_PRINT("\n Entering the async thread"); + + while (1) + { + ioctl_msg.in = NULL; + ioctl_msg.out = (void*)&venc_msg; + DEBUG_PRINT ("\n Sizeof venc_msginfo = %d ",sizeof (venc_msg)); + DEBUG_PRINT("\n Address of Venc msg in async thread %p",\ + ioctl_msg.out); + if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,\ + (void*)&ioctl_msg) < 0) + { + DEBUG_PRINT("\n Error in ioctl read next msg"); + } + else + { + switch (venc_msg.msgcode) + { + case VEN_MSG_START: + case VEN_MSG_STOP: + case VEN_MSG_INDICATION: + DEBUG_PRINT("\nSTOP/START Indiacation"); + queueitem.cmd = venc_msg.msgcode; + queueitem.status = venc_msg.statuscode; + queueitem.clientdata = NULL; + break; + + case VEN_MSG_INPUT_BUFFER_DONE: + DEBUG_PRINT("\nINPUT buffer done Indiacation"); + queueitem.cmd = venc_msg.msgcode; + queueitem.status = venc_msg.statuscode; + queueitem.clientdata = (void *)venc_msg.buf.clientdata; + DEBUG_PRINT("\nInput Client data pointer is %p",queueitem.clientdata); + tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata; + DEBUG_PRINT ("\n Input Address of tempbuffer %p",tempbuffer); + tempbuffer->filled_len = venc_msg.buf.len; + DEBUG_PRINT ("\n Input value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len); + break; + case VEN_MSG_OUTPUT_BUFFER_DONE: + DEBUG_PRINT("\nOUPUT buffer done Indiacation"); + queueitem.cmd = venc_msg.msgcode; + queueitem.status = venc_msg.statuscode; + queueitem.clientdata = (void *)venc_msg.buf.clientdata; + DEBUG_PRINT("\nOutput Client data pointer is %p",queueitem.clientdata); + tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata; + DEBUG_PRINT ("\n Output Address of tempbuffer %p",tempbuffer); + tempbuffer->filled_len = venc_msg.buf.len; + DEBUG_PRINT ("\n Output value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len); + break; + + default: + DEBUG_PRINT("\nIn Default of get next message %d",(int)venc_msg.msgcode); + queueitem.cmd = venc_msg.msgcode; + queueitem.status = venc_msg.statuscode; + queueitem.clientdata = NULL; + break; + } + result = queue_post_cmdq (&encoder_context->queue_context,&queueitem); + while (result == 0) + { + result = queue_post_cmdq (&encoder_context->queue_context,&queueitem); + } + + if (result == -1) + { + DEBUG_PRINT("\n FATAL ERROR WITH Queue"); + } + } + if (venc_msg.msgcode == VEN_MSG_STOP) + { + /*Thread can exit at this point*/ + return NULL; + } + } +} + + +static unsigned int read_frame (unsigned char *dataptr, unsigned int length, + FILE * inputBufferFile) +{ + + unsigned int readOffset = 0; + int bytes_read = 0; + unsigned int code = 0; + int found = 0; + + DEBUG_PRINT ("\n Inside the readframe"); + + if (dataptr == NULL && length == 0) + { + DEBUG_PRINT ("\n dataptr = %p length = %d",dataptr,(int)length); + return 0; + } + + pthread_mutex_lock(&read_lock); + bytes_read = fread(&dataptr[readOffset],1,length,inputBufferFile); + pthread_mutex_unlock(&read_lock); + + return bytes_read; +} diff --git a/mm-video/Android.mk b/mm-video/Android.mk deleted file mode 100755 index 2d0a5335..00000000 --- a/mm-video/Android.mk +++ /dev/null @@ -1,6 +0,0 @@ -OMX_VIDEO_PATH := $(call my-dir) -include $(CLEAR_VARS) - -include $(OMX_VIDEO_PATH)/vidc/vdec/Android.mk -include $(OMX_VIDEO_PATH)/vidc/venc/Android.mk -include $(OMX_VIDEO_PATH)/DivxDrmDecrypt/Android.mk diff --git a/mm-video/DivxDrmDecrypt/Android.mk b/mm-video/DivxDrmDecrypt/Android.mk deleted file mode 100755 index 0af340a9..00000000 --- a/mm-video/DivxDrmDecrypt/Android.mk +++ /dev/null @@ -1,29 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -#=============================================================================== -# Deploy the headers that can be exposed -#=============================================================================== - -LOCAL_COPY_HEADERS_TO := mm-video/DivxDrmDecrypt -LOCAL_COPY_HEADERS := inc/DivXDrmDecrypt.h - -LOCAL_CFLAGS := \ - -D_ANDROID_ - -LOCAL_SRC_FILES:= \ - src/DivXDrmDecrypt.cpp - -LOCAL_C_INCLUDES:= \ - $(LOCAL_PATH)/inc \ - $(TARGET_OUT_HEADERS)/mm-core/omxcore - -LOCAL_PRELINK_MODULE:= false - -LOCAL_MODULE:= libdivxdrmdecrypt -LOCAL_MODULE_TAGS := optional - -LOCAL_SHARED_LIBRARIES := liblog libdl - -LOCAL_LDLIBS += -include $(BUILD_SHARED_LIBRARY) diff --git a/mm-video/DivxDrmDecrypt/inc/DivXDrmDecrypt.h b/mm-video/DivxDrmDecrypt/inc/DivXDrmDecrypt.h deleted file mode 100755 index 4b0b707d..00000000 --- a/mm-video/DivxDrmDecrypt/inc/DivXDrmDecrypt.h +++ /dev/null @@ -1,49 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#ifndef __DIVXDRMDECRYPT_H__ -#define __DIVXDRMDECRYPT_H__ - -#include - -//Abstract base class of API to decrypt DRM content. -class DivXDrmDecrypt -{ -public: - static DivXDrmDecrypt* Create(); - virtual OMX_ERRORTYPE Init() = 0; - virtual OMX_ERRORTYPE Decrypt(OMX_BUFFERHEADERTYPE* buffer) = 0; - inline virtual ~DivXDrmDecrypt() {} -}; - -//.so file should provide a function with the name createDivXDrmDecrypt with -//prototype of DivXDrmDecryptFactory. -static const char* MEDIA_CREATE_DIVX_DRM_DECRYPT = "createDivXDrmDecrypt"; -typedef DivXDrmDecrypt* (*DivXDrmDecryptFactory)(); - -#endif //__DIVXDRMDECRYPT_H__ diff --git a/mm-video/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp b/mm-video/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp deleted file mode 100755 index ff4a382a..00000000 --- a/mm-video/DivxDrmDecrypt/src/DivXDrmDecrypt.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#include "DivXDrmDecrypt.h" -#include // for dlopen/dlclose - -//#define LOG_NDEBUG 0 -#define LOG_TAG "DivXDrmDecrypt" -#ifdef _ANDROID_ -#include -#else -#include -#define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args) -#endif /* _ANDROID_ */ - -static const char* DIVX_DRM_SHIM_LIB = "libSHIMDivxDrm.so"; - -void* getDecryptHandle() { - static void* decryptLib = NULL; - static bool decryptLibOpened = false; - - if(decryptLibOpened) { - return decryptLib; - } - - decryptLib = ::dlopen(DIVX_DRM_SHIM_LIB, RTLD_NOW); - decryptLibOpened = true; - - if (decryptLib == NULL) { - ALOGE("Failed to open DIVX_DRM_SHIM_LIB \n"); - } - - return decryptLib; -} - -DivXDrmDecryptFactory DrmDecryptFactoryFunction() { - static DivXDrmDecryptFactory drmDecryptFactoryFunction = NULL; - static bool alreadyTriedToFindFactoryFunction = false; - - if(alreadyTriedToFindFactoryFunction) { - return drmDecryptFactoryFunction; - } - - void *pDecryptLib = getDecryptHandle(); - if (pDecryptLib == NULL) { - return NULL; - } - - drmDecryptFactoryFunction = (DivXDrmDecryptFactory) dlsym(pDecryptLib, MEDIA_CREATE_DIVX_DRM_DECRYPT); - alreadyTriedToFindFactoryFunction = true; - - if(!drmDecryptFactoryFunction) { - ALOGE(" dlsym for DrmDecrypt factory function failed \n"); - } - - return drmDecryptFactoryFunction; -} - - - -DivXDrmDecrypt* DivXDrmDecrypt::Create() { - DivXDrmDecryptFactory drmCreateFunc = DrmDecryptFactoryFunction(); - if( drmCreateFunc == NULL ) { - return NULL; - } - - DivXDrmDecrypt* decrypt = drmCreateFunc(); - if( decrypt == NULL ) { - ALOGE(" failed to instantiate DrmDecoder \n"); - } - return decrypt; -} - diff --git a/mm-video/vidc/common/inc/extra_data_handler.h b/mm-video/vidc/common/inc/extra_data_handler.h deleted file mode 100644 index c7b6e7bb..00000000 --- a/mm-video/vidc/common/inc/extra_data_handler.h +++ /dev/null @@ -1,114 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#ifndef __EXTRA_DATA_HANDLER_H__ -#define __EXTRA_DATA_HANDLER_H__ - -#include -#include -#include -#include -#include "OMX_QCOMExtns.h" -#include -#include - - -#ifdef _ANDROID_ -extern "C"{ -#include -} -#ifdef ENABLE_DEBUG_LOW -#undef DEBUG_PRINT_LOW -#define DEBUG_PRINT_LOW ALOGE -#else -#undef DEBUG_PRINT_LOW -#define DEBUG_PRINT_LOW -#endif -#ifdef ENABLE_DEBUG_HIGH -#undef DEBUG_PRINT_HIGH -#define DEBUG_PRINT_HIGH ALOGE -#else -#undef DEBUG_PRINT_HIGH -#define DEBUG_PRINT_HIGH -#endif -#ifdef ENABLE_DEBUG_ERROR -#undef DEBUG_PRINT_ERROR -#define DEBUG_PRINT_ERROR ALOGE -#else -#undef DEBUG_PRINT_ERROR -#define DEBUG_PRINT_ERROR -#endif - -#else //_ANDROID_ -#undef DEBUG_PRINT_LOW -#undef DEBUG_PRINT_HIGH -#undef DEBUG_PRINT_ERROR -#define DEBUG_PRINT_LOW printf -#define DEBUG_PRINT_HIGH printf -#define DEBUG_PRINT_ERROR printf -#endif // _ANDROID_ - -#define SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT 0x2D -#define H264_START_CODE 0x01 -#define NAL_TYPE_SEI 0x06 -#define VDEC_OMX_SEI 0x7F000007 -#define FRAME_PACK_SIZE 18 -#define H264_EMULATION_BYTE 0x03 -class extra_data_handler -{ -public: - extra_data_handler(); - ~extra_data_handler(); - OMX_U32 parse_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr); - OMX_U32 create_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr); - OMX_U32 get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); - OMX_U32 set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); -private: - OMX_QCOM_FRAME_PACK_ARRANGEMENT frame_packing_arrangement; - OMX_U8 *rbsp_buf; - OMX_U32 bit_ptr; - OMX_U32 byte_ptr; - OMX_U32 pack_sei; - OMX_U32 sei_payload_type; - OMX_U32 d_u(OMX_U32 num_bits); - OMX_U32 d_ue(); - OMX_U32 parse_frame_pack(OMX_U32 payload_size); - OMX_S32 parse_rbsp(OMX_U8 *buf, OMX_U32 len); - OMX_S32 parse_sei(OMX_U8 *buffer, OMX_U32 buffer_length); - OMX_U32 e_u(OMX_U32 symbol, OMX_U32 num_bits); - OMX_U32 e_ue(OMX_U32 symbol); - OMX_U32 create_frame_pack(); - OMX_S32 create_rbsp(OMX_U8 *buf, OMX_U32 nalu_type); - OMX_U32 create_sei(OMX_U8 *buffer); - OMX_S32 parse_sliceinfo(OMX_BUFFERHEADERTYPE *pBufHdr, - OMX_OTHER_EXTRADATATYPE *pExtra); - OMX_S32 parse_ltrinfo(OMX_BUFFERHEADERTYPE *pBufHdr, - OMX_OTHER_EXTRADATATYPE *pExtra); -}; - -#endif diff --git a/mm-video/vidc/common/inc/vidc_color_converter.h b/mm-video/vidc/common/inc/vidc_color_converter.h deleted file mode 100644 index bbfbdaea..00000000 --- a/mm-video/vidc/common/inc/vidc_color_converter.h +++ /dev/null @@ -1,53 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include -#include "C2DColorConverter.h" - -using namespace android; -class omx_c2d_conv { -public: - omx_c2d_conv(); - ~omx_c2d_conv(); - bool init(); - void destroy(); - bool open(unsigned int height,unsigned int width, - ColorConvertFormat src, - ColorConvertFormat dest); - bool convert(int src_fd, void *src_base, void *src_viraddr, - int dest_fd, void *dest_base, void *dest_viraddr); - bool get_buffer_size(int port,unsigned int &buf_size); - int get_src_format(); - void close(); -private: - C2DColorConverterBase *c2dcc; - void *mLibHandle; - ColorConvertFormat src_format; - createC2DColorConverter_t *mConvertOpen; - destroyC2DColorConverter_t *mConvertClose; -}; diff --git a/mm-video/vidc/common/src/extra_data_handler.cpp b/mm-video/vidc/common/src/extra_data_handler.cpp deleted file mode 100644 index aa3b563b..00000000 --- a/mm-video/vidc/common/src/extra_data_handler.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#include "extra_data_handler.h" - -extra_data_handler::extra_data_handler() -{ - rbsp_buf = (OMX_U8 *) calloc(1,100); - memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement)); - frame_packing_arrangement.cancel_flag = 1; - pack_sei = false; - sei_payload_type = -1; -} - -extra_data_handler::~extra_data_handler() -{ - if(rbsp_buf) { - free(rbsp_buf); - rbsp_buf = NULL; - } -} - -OMX_U32 extra_data_handler::d_u(OMX_U32 num_bits) -{ - OMX_U32 rem_bits = num_bits, bins = 0, shift = 0; - - while(rem_bits >= bit_ptr) { - DEBUG_PRINT_LOW("\nIn %s() bit_ptr/byte_ptr :%d/%d/%x", __func__, bit_ptr, - byte_ptr, rbsp_buf[byte_ptr]); - bins <<= shift; - shift = (8-bit_ptr); - bins |= ((rbsp_buf[byte_ptr] << shift) & 0xFF) >> shift; - rem_bits -= bit_ptr; - bit_ptr = 8; - byte_ptr ++; - } - DEBUG_PRINT_LOW("\nIn %s() bit_ptr/byte_ptr :%d/%d/%x", __func__, bit_ptr, - byte_ptr, rbsp_buf[byte_ptr]); - - if (rem_bits) { - bins <<= rem_bits; - bins |= ((rbsp_buf[byte_ptr] << (8-bit_ptr)) & 0xFF) >> (8-rem_bits); - bit_ptr -= rem_bits; - if (bit_ptr == 0) { - bit_ptr = 8; - byte_ptr++; - } - } - DEBUG_PRINT_LOW("\nIn %s() bit_ptr/byte_ptr :%d/%d/%x", __func__, bit_ptr, - byte_ptr, rbsp_buf[byte_ptr]); - - DEBUG_PRINT_LOW("\nIn %s() bin/num_bits : %x/%d", __func__, bins, num_bits); - return bins; -} - -OMX_U32 extra_data_handler::d_ue() -{ - OMX_S32 lead_zeros = -1; - OMX_U32 symbol, bit; - do{ - bit = d_u(1); - lead_zeros++; - }while (!bit); - - symbol = ((1 << lead_zeros) - 1) + d_u(lead_zeros); - - DEBUG_PRINT_LOW("\nIn %s() symbol : %d", __func__,symbol); - return symbol; -} - -OMX_U32 extra_data_handler::parse_frame_pack(OMX_U32 payload_size) -{ - frame_packing_arrangement.id = d_ue(); - frame_packing_arrangement.cancel_flag = d_u(1); - if(!frame_packing_arrangement.cancel_flag) { - frame_packing_arrangement.type = d_u(7); - frame_packing_arrangement.quincunx_sampling_flag = d_u(1); - frame_packing_arrangement.content_interpretation_type = d_u(6); - frame_packing_arrangement.spatial_flipping_flag = d_u(1); - frame_packing_arrangement.frame0_flipped_flag = d_u(1); - frame_packing_arrangement.field_views_flag = d_u(1); - frame_packing_arrangement.current_frame_is_frame0_flag = d_u(1); - frame_packing_arrangement.frame0_self_contained_flag = d_u(1); - frame_packing_arrangement.frame1_self_contained_flag = d_u(1); - - if(!frame_packing_arrangement.quincunx_sampling_flag && - frame_packing_arrangement.type != 5) { - frame_packing_arrangement.frame0_grid_position_x = d_u(4); - frame_packing_arrangement.frame0_grid_position_y = d_u(4); - frame_packing_arrangement.frame1_grid_position_x = d_u(4); - frame_packing_arrangement.frame1_grid_position_y = d_u(4); - } - frame_packing_arrangement.reserved_byte = d_u(8); - frame_packing_arrangement.repetition_period = d_ue(); - } - frame_packing_arrangement.extension_flag = d_u(1); - - return 1; -} - -OMX_S32 extra_data_handler::parse_rbsp(OMX_U8 *buf, OMX_U32 len) -{ - OMX_U32 i = 3, j=0, startcode; - OMX_U32 nal_unit_type, nal_ref_idc, forbidden_zero_bit; - - bit_ptr = 8; - byte_ptr = 0; - - startcode = buf[0] << 16 | buf[1] <<8 | buf[2]; - - if (!startcode) { - startcode |= buf[i++]; - } - if(startcode != H264_START_CODE) { - DEBUG_PRINT_ERROR("\nERROR: In %s() Start code not found", __func__); - return -1; - } - forbidden_zero_bit = (buf[i] & 0x80) >>7; - if(forbidden_zero_bit) { - DEBUG_PRINT_ERROR("\nERROR: In %s() Non-zero forbidden bit", __func__); - return -1; - } - nal_ref_idc = (buf[i] & 0x60) >>5; - DEBUG_PRINT_LOW("\nIn %s() nal_ref_idc ; %d", __func__, nal_ref_idc); - - nal_unit_type = (buf[i++] & 0x1F); - - while(ieType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoLTRInfo; - pLTR = (OMX_U32* )pExtra + 5; - DEBUG_PRINT_HIGH("ExtraData LTR ID %d", *pLTR, 0, 0); - return 0; -} -/*====================================================================== - Slice Information will be available as below (each line is of 4 bytes) - | number of slices | - | 1st slice offset | - | 1st slice size | - | .. | - | Nth slice offset | - | Nth slice size | -======================================================================*/ -OMX_S32 extra_data_handler::parse_sliceinfo( - OMX_BUFFERHEADERTYPE *pBufHdr, OMX_OTHER_EXTRADATATYPE *pExtra) -{ - OMX_U32 slice_offset = 0, slice_size = 0, total_size = 0; - OMX_U8 *pBuffer = (OMX_U8 *)pBufHdr->pBuffer; - OMX_U32 *data = (OMX_U32 *)pExtra->data; - OMX_U32 num_slices = *data; - DEBUG_PRINT_LOW("number of slices = %d", num_slices); - if ((4 + num_slices * 8) != (OMX_U32)pExtra->nDataSize) { - DEBUG_PRINT_ERROR("unknown error in slice info extradata"); - return -1; - } - for (int i = 0; i < num_slices; i++) { - slice_offset = (OMX_U32)(*(data + (i*2 + 1))); - if ((*(pBuffer + slice_offset + 0) != 0x00) || - (*(pBuffer + slice_offset + 1) != 0x00) || - (*(pBuffer + slice_offset + 2) != 0x00) || - (*(pBuffer + slice_offset + 3) != H264_START_CODE)) { - DEBUG_PRINT_ERROR("found 0x%x instead of start code at offset[%d] " - "for slice[%d]", (OMX_U32)(*(OMX_U32 *)(pBuffer + slice_offset)), - slice_offset, i); - return -1; - } - if (slice_offset != total_size) { - DEBUG_PRINT_ERROR("offset of slice number %d is not correct " - "or previous slice size is not correct", i); - return -1; - } - slice_size = (OMX_U32)(*(data + (i*2 + 2))); - total_size += slice_size; - DEBUG_PRINT_LOW("slice number %d offset/size = %d/%d", - i, slice_offset, slice_size); - } - if (pBufHdr->nFilledLen != total_size) { - DEBUG_PRINT_ERROR("frame_size[%d] is not equal to " - "total slices size[%d]", pBufHdr->nFilledLen, total_size); - return -1; - } - return 0; -} - -OMX_U32 extra_data_handler::parse_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr) -{ - DEBUG_PRINT_LOW("In %s() flags: 0x%x", __func__,buf_hdr->nFlags); - - if (buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) { - - OMX_OTHER_EXTRADATATYPE *extra_data = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(buf_hdr->pBuffer + buf_hdr->nOffset + - buf_hdr->nFilledLen + 3)&(~3)); - - while(extra_data && - ((OMX_U32)extra_data > (OMX_U32)buf_hdr->pBuffer) && - ((OMX_U32)extra_data < (OMX_U32)buf_hdr->pBuffer + buf_hdr->nAllocLen)) { - - DEBUG_PRINT_LOW("extradata(0x%x): nSize = 0x%x, eType = 0x%x," - " nDataSize = 0x%x", (unsigned)extra_data, extra_data->nSize, - extra_data->eType, extra_data->nDataSize); - - if ((extra_data->eType == VDEC_EXTRADATA_NONE) || - (extra_data->eType == VEN_EXTRADATA_NONE)) { - DEBUG_PRINT_LOW("No more extradata available"); - extra_data->eType = OMX_ExtraDataNone; - break; - } - else if (extra_data->eType == VDEC_EXTRADATA_SEI) { - DEBUG_PRINT_LOW("Extradata SEI of size %d found, " - "parsing it", extra_data->nDataSize); - parse_sei(extra_data->data, extra_data->nDataSize); - } - else if (extra_data->eType == VEN_EXTRADATA_QCOMFILLER) { - DEBUG_PRINT_LOW("Extradata Qcom Filler found, skip %d bytes", - extra_data->nSize); - } - else if (extra_data->eType == VEN_EXTRADATA_SLICEINFO) { - DEBUG_PRINT_LOW("Extradata SliceInfo of size %d found, " - "parsing it", extra_data->nDataSize); - parse_sliceinfo(buf_hdr, extra_data); - } -#ifndef _MSM8974_ - else if (extra_data->eType == VEN_EXTRADATA_LTRINFO) { - DEBUG_PRINT_LOW("Extradata LTRInfo of size %d found, " - "parsing it", extra_data->nDataSize); - parse_ltrinfo(buf_hdr, extra_data); - } -#endif - else { - DEBUG_PRINT_ERROR("Unknown extradata(0x%x) found, nSize = 0x%x, " - "eType = 0x%x, nDataSize = 0x%x", (unsigned)extra_data, - extra_data->nSize, extra_data->eType, extra_data->nDataSize); - buf_hdr->nFlags &= ~(OMX_BUFFERFLAG_EXTRADATA); - break; - } - extra_data = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) extra_data) + - extra_data->nSize); - } - } - return 1; -} - -OMX_U32 extra_data_handler::get_frame_pack_data( - OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack) -{ - DEBUG_PRINT_LOW("\n%s:%d get frame data", __func__, __LINE__); - memcpy(&frame_pack->id,&frame_packing_arrangement.id, - FRAME_PACK_SIZE*sizeof(OMX_U32)); - return 1; -} - -OMX_U32 extra_data_handler::set_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT - *frame_pack) -{ - DEBUG_PRINT_LOW("\n%s:%d set frame data", __func__, __LINE__); - memcpy(&frame_packing_arrangement.id, &frame_pack->id, - FRAME_PACK_SIZE*sizeof(OMX_U32)); - pack_sei = true; - sei_payload_type = SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT; - return 1; -} - -OMX_U32 extra_data_handler::e_u(OMX_U32 symbol, OMX_U32 num_bits) -{ - OMX_U32 rem_bits = num_bits, shift; - - DEBUG_PRINT_LOW("\n%s bin : %x/%d", __func__, symbol, num_bits); - - while(rem_bits >= bit_ptr) { - shift = rem_bits - bit_ptr; - rbsp_buf[byte_ptr] |= (symbol >> shift); - symbol = (symbol << (32 - shift)) >> (32 - shift); - rem_bits -= bit_ptr; - DEBUG_PRINT_LOW("\n%sstream byte/rem_bits %x/%d", __func__, - rbsp_buf[byte_ptr], rem_bits); - byte_ptr ++; - bit_ptr = 8; - } - - if(rem_bits) { - shift = bit_ptr - rem_bits; - rbsp_buf[byte_ptr] |= (symbol << shift); - bit_ptr -= rem_bits; - DEBUG_PRINT_LOW("\n%s 2 stream byte/rem_bits %x", __func__, - rbsp_buf[byte_ptr], rem_bits); - if(bit_ptr == 0) { - bit_ptr = 8; - byte_ptr++; - } - } - return 1; -} - -OMX_U32 extra_data_handler::e_ue(OMX_U32 symbol) -{ - OMX_U32 i, sym_len, sufix_len, info; - OMX_U32 nn =(symbol + 1) >> 1; - - DEBUG_PRINT_LOW("\n%s bin : %x", __func__, symbol); - - for(i=0; i < 33 && nn != 0; i++) - nn >>= 1; - - sym_len = ((i << 1) + 1); - info = symbol + 1 - (1 << i); - sufix_len = (1 << (sym_len >>1)); - info = sufix_len | (info & (sufix_len - 1)); - e_u(info, sym_len); - return 1; -} - -OMX_U32 extra_data_handler::create_frame_pack() -{ - e_ue(frame_packing_arrangement.id); - e_u(frame_packing_arrangement.cancel_flag, 1); - if(!frame_packing_arrangement.cancel_flag) { - e_u(frame_packing_arrangement.type, 7); - e_u(frame_packing_arrangement.quincunx_sampling_flag, 1); - e_u(frame_packing_arrangement.content_interpretation_type, 6); - e_u(frame_packing_arrangement.spatial_flipping_flag, 1); - e_u(frame_packing_arrangement.frame0_flipped_flag, 1); - e_u(frame_packing_arrangement.field_views_flag, 1); - e_u(frame_packing_arrangement.current_frame_is_frame0_flag, 1); - e_u(frame_packing_arrangement.frame0_self_contained_flag, 1); - e_u(frame_packing_arrangement.frame1_self_contained_flag, 1); - if(!frame_packing_arrangement.quincunx_sampling_flag && - frame_packing_arrangement.type != 5) { - e_u(frame_packing_arrangement.frame0_grid_position_x, 4); - e_u(frame_packing_arrangement.frame0_grid_position_y, 4); - e_u(frame_packing_arrangement.frame1_grid_position_x, 4); - e_u(frame_packing_arrangement.frame1_grid_position_y, 4); - } - e_u(frame_packing_arrangement.reserved_byte, 8); - e_ue(frame_packing_arrangement.repetition_period); - } - e_u(frame_packing_arrangement.extension_flag, 1); - return 1; -} - -OMX_S32 extra_data_handler::create_rbsp(OMX_U8 *buf, OMX_U32 nalu_type) -{ - OMX_U32 i, j = 7; - for(i = 0;i < 3;i++) - *buf++ = 0x00; - *buf++ = H264_START_CODE; - *buf++ = nalu_type; - *buf++ = (sei_payload_type & 0x000000FF); - *buf++ = byte_ptr - 1; //payload will contain 1 byte of rbsp_trailing_bits - //that shouldn't be taken into account - - for(i = 0;i < byte_ptr ;i += 2) { - *buf++ = rbsp_buf[i]; - j++; - if(i+1 < byte_ptr) { - *buf++ = rbsp_buf[i+1]; - j++; - if(!(rbsp_buf[i] + rbsp_buf[i+1])) { - *buf++ = H264_EMULATION_BYTE; - j++; - } - } - } - - DEBUG_PRINT_LOW("\n%s rbsp length %d", __func__, j); - return j; -} - -OMX_U32 extra_data_handler::create_sei(OMX_U8 *buffer) -{ - OMX_U32 i, ret_val = 0; - - byte_ptr = 0; - bit_ptr = 8; - - if(sei_payload_type == SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT) { - create_frame_pack(); - - if(bit_ptr != 8) { - e_u(1,1); - if(bit_ptr != 8) - e_u(0,bit_ptr); - } - - //Payload will have been byte aligned by now, - //insert the rbsp trailing bits - e_u(1, 1); - e_u(0, 7); - - ret_val = create_rbsp(buffer, NAL_TYPE_SEI); - } - - pack_sei = false; - sei_payload_type = -1; - - return ret_val; -} - -OMX_U32 extra_data_handler::create_extra_data(OMX_BUFFERHEADERTYPE *buf_hdr) -{ - OMX_U8 *buffer = (OMX_U8 *) ((unsigned)(buf_hdr->pBuffer + - buf_hdr->nOffset + buf_hdr->nFilledLen)); - OMX_U32 msg_size; - - if(buf_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { - DEBUG_PRINT_LOW("\n%s:%d create extra data with config", __func__, - __LINE__); - if(pack_sei) { - msg_size = create_sei(buffer); - if( msg_size > 0) - buf_hdr->nFilledLen += msg_size; - } - } - return 1; -} - diff --git a/mm-video/vidc/common/src/vidc_color_converter.cpp b/mm-video/vidc/common/src/vidc_color_converter.cpp deleted file mode 100644 index e75dd3ca..00000000 --- a/mm-video/vidc/common/src/vidc_color_converter.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include -#include -#include "vidc_color_converter.h" -#undef DEBUG_PRINT_LOW -#undef DEBUG_PRINT_HIGH -#undef DEBUG_PRINT_ERROR - -#define DEBUG_PRINT_LOW ALOGV -#define DEBUG_PRINT_HIGH ALOGE -#define DEBUG_PRINT_ERROR ALOGE - -omx_c2d_conv::omx_c2d_conv() -{ - c2dcc = NULL; - mLibHandle = NULL; - mConvertOpen = NULL; - mConvertClose = NULL; - src_format = NV12_2K; -} - -bool omx_c2d_conv::init() { - bool status = true; - if(mLibHandle || mConvertOpen || mConvertClose) { - DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice"); - status = false; - } - if(status) { - mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); - if(mLibHandle){ - mConvertOpen = (createC2DColorConverter_t *) - dlsym(mLibHandle,"createC2DColorConverter"); - mConvertClose = (destroyC2DColorConverter_t *) - dlsym(mLibHandle,"destroyC2DColorConverter"); - if(!mConvertOpen || !mConvertClose) - status = false; - } else - status = false; - } - if(!status && mLibHandle){ - dlclose(mLibHandle); - mLibHandle = NULL; - mConvertOpen = NULL; - mConvertClose = NULL; - } - return status; -} - -bool omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, - int dest_fd, void *dest_base, void *dest_viraddr) -{ - int result; - if(!src_viraddr || !dest_viraddr || !c2dcc || !dest_base || !src_base){ - DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); - return false; - } - result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, - dest_fd, dest_base, dest_viraddr); - DEBUG_PRINT_LOW("\n Color convert status %d",result); - return ((result < 0)?false:true); -} - -bool omx_c2d_conv::open(unsigned int height,unsigned int width, - ColorConvertFormat src, ColorConvertFormat dest) -{ - bool status = false; - if(!c2dcc) { - c2dcc = mConvertOpen(width, height, width, height, - src,dest,0,0); - if(c2dcc) { - src_format = src; - status = true; - } else - DEBUG_PRINT_ERROR("\n mConvertOpen failed"); - } - return status; -} -void omx_c2d_conv::close() -{ - if(mLibHandle) { - if(mConvertClose && c2dcc) - mConvertClose(c2dcc); - c2dcc = NULL; - } -} - -void omx_c2d_conv::destroy() -{ - DEBUG_PRINT_ERROR("\n Destroy C2D instance"); - if(mLibHandle) { - if(mConvertClose && c2dcc) - mConvertClose(c2dcc); - dlclose(mLibHandle); - } - c2dcc = NULL; - mLibHandle = NULL; - mConvertOpen = NULL; - mConvertClose = NULL; -} -omx_c2d_conv::~omx_c2d_conv() -{ - destroy(); -} -int omx_c2d_conv::get_src_format() -{ - int format = -1; - if(src_format == NV12_2K) { - format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; - } else if(src_format == RGBA8888) { - format = HAL_PIXEL_FORMAT_RGBA_8888; - } - return format; -} -bool omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) -{ - int cret = 0; - bool ret = false; - C2DBuffReq bufferreq; - if(c2dcc){ - bufferreq.size = 0; - cret = c2dcc->getBuffReq(port,&bufferreq); - DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret); - ret = (cret)?false:true; - buf_size = bufferreq.size; - } - return ret; -} diff --git a/mm-video/vidc/vdec/Android.mk b/mm-video/vidc/vdec/Android.mk deleted file mode 100755 index 97ff2973..00000000 --- a/mm-video/vidc/vdec/Android.mk +++ /dev/null @@ -1,230 +0,0 @@ -ifneq ($(BUILD_TINY_ANDROID),true) - -ROOT_DIR := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_PATH:= $(ROOT_DIR) - -# --------------------------------------------------------------------------------- -# Common definitons -# --------------------------------------------------------------------------------- - -libOmxVdec-def := -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\) -libOmxVdec-def += -D__align=__alignx -libOmxVdec-def += -Dinline=__inline -libOmxVdec-def += -g -O3 -libOmxVdec-def += -DIMAGE_APPS_PROC -libOmxVdec-def += -D_ANDROID_ -libOmxVdec-def += -DCDECL -libOmxVdec-def += -DT_ARM -libOmxVdec-def += -DNO_ARM_CLZ -libOmxVdec-def += -UENABLE_DEBUG_LOW -libOmxVdec-def += -DENABLE_DEBUG_HIGH -libOmxVdec-def += -DENABLE_DEBUG_ERROR -libOmxVdec-def += -UINPUT_BUFFER_LOG -libOmxVdec-def += -UOUTPUT_BUFFER_LOG -ifeq ($(TARGET_BOARD_PLATFORM),msm8660) -libOmxVdec-def += -DMAX_RES_1080P -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libOmxVdec-def += -DTEST_TS_FROM_SEI -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8960) -libOmxVdec-def += -DMAX_RES_1080P -libOmxVdec-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libOmxVdec-def += -D_MSM8960_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8974) -libOmxVdec-def += -DMAX_RES_1080P -libOmxVdec-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libOmxVdec-def += -D_MSM8974_ -libOmxVdec-def += -D_HEVC_USE_ADSP_HEAP_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm7627a) -libOmxVdec-def += -DMAX_RES_720P -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm7630_surf) -libOmxVdec-def += -DMAX_RES_720P -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8610) -libOmxVdec-def += -DMAX_RES_1080P -libOmxVdec-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libOmxVdec-def += -DSMOOTH_STREAMING_DISABLED -libOmxVdec-def += -DH264_PROFILE_LEVEL_CHECK -libOmxVdec-def += -D_MSM8974_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8226) -libOmxVdec-def += -DMAX_RES_1080P -libOmxVdec-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libOmxVdec-def += -D_MSM8974_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),apq8084) -libOmxVdec-def += -DMAX_RES_1080P -libOmxVdec-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libOmxVdec-def += -D_MSM8974_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),mpq8092) -libOmxVdec-def += -DMAX_RES_1080P -libOmxVdec-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libOmxVdec-def += -D_MSM8974_ -endif -libOmxVdec-def += -D_ANDROID_ICS_ - -ifeq ($(TARGET_USES_ION),true) -libOmxVdec-def += -DUSE_ION -endif - -ifneq ($(call is-platform-sdk-version-at-least,18),true) -libOmxVdec-def += -DANDROID_JELLYBEAN_MR1=1 -endif - -vdec-inc = $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include - -# --------------------------------------------------------------------------------- -# Make the Shared library (libOmxVdec) -# --------------------------------------------------------------------------------- - -include $(CLEAR_VARS) -LOCAL_PATH:= $(ROOT_DIR) - -libmm-vdec-inc := bionic/libc/include -libmm-vdec-inc += bionic/libstdc++/include -libmm-vdec-inc += $(LOCAL_PATH)/inc -libmm-vdec-inc += $(OMX_VIDEO_PATH)/vidc/common/inc -libmm-vdec-inc += hardware/qcom/media/mm-core/inc -#DRM include - Interface which loads the DRM library -libmm-vdec-inc += $(OMX_VIDEO_PATH)/DivxDrmDecrypt/inc -libmm-vdec-inc += hardware/qcom/display/libgralloc -libmm-vdec-inc += hardware/qcom/display/libgenlock -libmm-vdec-inc += frameworks/native/include/media/openmax -libmm-vdec-inc += frameworks/native/include/media/hardware -libmm-vdec-inc += $(vdec-inc) -libmm-vdec-inc += hardware/qcom/display/libqdutils -libmm-vdec-inc += hardware/qcom/media/libc2dcolorconvert -libmm-vdec-inc += hardware/qcom/display/libcopybit -libmm-vdec-inc += frameworks/av/include/media/stagefright - - -LOCAL_MODULE := libOmxVdec -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := $(libOmxVdec-def) -LOCAL_C_INCLUDES += $(libmm-vdec-inc) - -LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils libdl - -LOCAL_SHARED_LIBRARIES += libgenlock -LOCAL_SHARED_LIBRARIES += libdivxdrmdecrypt -LOCAL_SHARED_LIBRARIES += libqdMetaData - -LOCAL_SRC_FILES := src/frameparser.cpp -LOCAL_SRC_FILES += src/h264_utils.cpp -LOCAL_SRC_FILES += src/ts_parser.cpp -LOCAL_SRC_FILES += src/mp4_utils.cpp -ifeq ($(call is-board-platform-in-list,msm8974 msm8610 msm8226 apq8084 mpq8092),true) -LOCAL_SRC_FILES += src/omx_vdec_msm8974.cpp -else -LOCAL_SHARED_LIBRARIES += libhardware -libmm-vdec-inc += hardware/qcom/display/libhwcomposer -LOCAL_SRC_FILES += src/power_module.cpp -LOCAL_SRC_FILES += src/omx_vdec.cpp -endif - -LOCAL_SRC_FILES += ../common/src/extra_data_handler.cpp -LOCAL_SRC_FILES += ../common/src/vidc_color_converter.cpp -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr - -include $(BUILD_SHARED_LIBRARY) - - -# --------------------------------------------------------------------------------- -# Make the Shared library (libOmxVdecHevc) -# --------------------------------------------------------------------------------- - -include $(CLEAR_VARS) -LOCAL_PATH:= $(ROOT_DIR) - -ifeq ($(call is-board-platform-in-list,msm8974 msm8610 apq8084 mpq8092),true) - -LOCAL_MODULE := libOmxVdecHevc -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := $(libOmxVdec-def) -LOCAL_C_INCLUDES += $(libmm-vdec-inc) - -LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils libdl - -LOCAL_SHARED_LIBRARIES += libgenlock -LOCAL_SHARED_LIBRARIES += libdivxdrmdecrypt -LOCAL_SHARED_LIBRARIES += libqdMetaData - -LOCAL_SRC_FILES := src/frameparser.cpp -LOCAL_SRC_FILES += src/h264_utils.cpp -LOCAL_SRC_FILES += src/ts_parser.cpp -LOCAL_SRC_FILES += src/mp4_utils.cpp - -LOCAL_SRC_FILES += src/omx_vdec_hevc.cpp -LOCAL_SRC_FILES += src/hevc_utils.cpp - -LOCAL_SRC_FILES += ../common/src/extra_data_handler.cpp -LOCAL_SRC_FILES += ../common/src/vidc_color_converter.cpp -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr - -include $(BUILD_SHARED_LIBRARY) - -endif - -# --------------------------------------------------------------------------------- -# Make the apps-test (mm-vdec-omx-test) -# --------------------------------------------------------------------------------- -include $(CLEAR_VARS) - -mm-vdec-test-inc := hardware/qcom/media/mm-core/inc -mm-vdec-test-inc += $(LOCAL_PATH)/inc -mm-vdec-test-inc += $(vdec-inc) - -LOCAL_MODULE := mm-vdec-omx-test -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := $(libOmxVdec-def) -LOCAL_C_INCLUDES := $(mm-vdec-test-inc) - -LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := libutils libOmxCore libOmxVdec libbinder libcutils - -LOCAL_SRC_FILES := src/queue.c -LOCAL_SRC_FILES += test/omx_vdec_test.cpp -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr - -include $(BUILD_EXECUTABLE) - -# --------------------------------------------------------------------------------- -# Make the driver-test (mm-video-driver-test) -# --------------------------------------------------------------------------------- -include $(CLEAR_VARS) - -mm-vdec-drv-test-inc := hardware/qcom/media/mm-core/inc -mm-vdec-drv-test-inc += $(LOCAL_PATH)/inc -mm-vdec-drv-test-inc += $(vdec-inc) - -LOCAL_MODULE := mm-video-driver-test -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := $(libOmxVdec-def) -LOCAL_C_INCLUDES := $(mm-vdec-drv-test-inc) -LOCAL_PRELINK_MODULE := false - -LOCAL_SRC_FILES := src/message_queue.c -LOCAL_SRC_FILES += test/decoder_driver_test.c -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr - -include $(BUILD_EXECUTABLE) - -endif #BUILD_TINY_ANDROID - -# --------------------------------------------------------------------------------- -# END -# --------------------------------------------------------------------------------- diff --git a/mm-video/vidc/vdec/inc/Map.h b/mm-video/vidc/vdec/inc/Map.h deleted file mode 100755 index 6d5873e0..00000000 --- a/mm-video/vidc/vdec/inc/Map.h +++ /dev/null @@ -1,237 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef _MAP_H_ -#define _MAP_H_ - -#include -using namespace std; - -template -class Map -{ - struct node - { - T data; - T2 data2; - node* prev; - node* next; - node(T t, T2 t2,node* p, node* n) : - data(t), data2(t2), prev(p), next(n) {} - }; - node* head; - node* tail; - node* tmp; - unsigned size_of_list; - static Map *m_self; -public: - Map() : head( NULL ), tail ( NULL ),tmp(head),size_of_list(0) {} - bool empty() const { return ( !head || !tail ); } - operator bool() const { return !empty(); } - void insert(T,T2); - void show(); - int size(); - T2 find(T); // Return VALUE - T find_ele(T);// Check if the KEY is present or not - T2 begin(); //give the first ele - bool erase(T); - bool eraseall(); - bool isempty(); - ~Map() - { - while(head) - { - node* temp(head); - head=head->next; - size_of_list--; - delete temp; - } - } -}; - -template -T2 Map::find(T d1) -{ - tmp = head; - while(tmp) - { - if(tmp->data == d1) - { - return tmp->data2; - } - tmp = tmp->next; - } - return 0; -} - -template -T Map::find_ele(T d1) -{ - tmp = head; - while(tmp) - { - if(tmp->data == d1) - { - return tmp->data; - } - tmp = tmp->next; - } - return 0; -} - -template -T2 Map::begin() -{ - tmp = head; - if(tmp) - { - return (tmp->data2); - } - return 0; -} - -template -void Map::show() -{ - tmp = head; - while(tmp) - { - printf("%d-->%d\n",tmp->data,tmp->data2); - tmp = tmp->next; - } -} - -template -int Map::size() -{ - int count =0; - tmp = head; - while(tmp) - { - tmp = tmp->next; - count++; - } - return count; -} - -template -void Map::insert(T data, T2 data2) -{ - tail = new node(data, data2,tail, NULL); - if( tail->prev ) - tail->prev->next = tail; - - if( empty() ) - { - head = tail; - tmp=head; - } - tmp = head; - size_of_list++; -} - -template -bool Map::erase(T d) -{ - bool found = false; - tmp = head; - node* prevnode = tmp; - node *tempnode; - - while(tmp) - { - if((head == tail) && (head->data == d)) - { - found = true; - tempnode = head; - head = tail = NULL; - delete tempnode; - break; - } - if((tmp ==head) && (tmp->data ==d)) - { - found = true; - tempnode = tmp; - tmp = tmp->next; - tmp->prev = NULL; - head = tmp; - tempnode->next = NULL; - delete tempnode; - break; - } - if((tmp == tail) && (tmp->data ==d)) - { - found = true; - tempnode = tmp; - prevnode->next = NULL; - tmp->prev = NULL; - tail = prevnode; - delete tempnode; - break; - } - if(tmp->data == d) - { - found = true; - prevnode->next = tmp->next; - tmp->next->prev = prevnode->next; - tempnode = tmp; - //tmp = tmp->next; - delete tempnode; - break; - } - prevnode = tmp; - tmp = tmp->next; - } - if(found)size_of_list--; - return found; -} - -template -bool Map::eraseall() -{ - node *tempnode; - tmp = head; - while(head) - { - tempnode = head; - tempnode->next = NULL; - head = head->next; - delete tempnode; - } - tail = head = NULL; - return true; -} - - -template -bool Map::isempty() -{ - if(!size_of_list) return true; - else return false; -} - -#endif // _MAP_H_ diff --git a/mm-video/vidc/vdec/inc/decoder_driver_test.h b/mm-video/vidc/vdec/inc/decoder_driver_test.h deleted file mode 100755 index b3afafeb..00000000 --- a/mm-video/vidc/vdec/inc/decoder_driver_test.h +++ /dev/null @@ -1,70 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include -#include -#include "message_queue.h" -#include -#include -#include -#include -#include -#include -#include -#include - -struct video_decoder_context -{ - enum vdec_codec decoder_format; - enum vdec_output_fromat output_format; - struct vdec_picsize video_resoultion; - struct vdec_allocatorproperty input_buffer; - struct vdec_allocatorproperty output_buffer; - struct vdec_bufferpayload **ptr_inputbuffer; - struct vdec_bufferpayload **ptr_outputbuffer; - struct vdec_output_frameinfo **ptr_respbuffer; - struct video_queue_context queue_context; - int video_driver_fd; - - FILE * inputBufferFile; - FILE * outputBufferFile; - - pthread_t videothread_id; - pthread_t asyncthread_id; - sem_t sem_synchronize; -}; - -int init_decoder ( struct video_decoder_context *init_decode ); -int allocate_buffer ( enum vdec_buffer, - struct video_decoder_context *decode_context - ); -int free_buffer ( enum vdec_buffer, - struct video_decoder_context *decode_context - ); -int start_decoding (struct video_decoder_context *decode_context); -int stop_decoding (struct video_decoder_context *decode_context); -int deinit_decoder (struct video_decoder_context *init_decode); diff --git a/mm-video/vidc/vdec/inc/frameparser.h b/mm-video/vidc/vdec/inc/frameparser.h deleted file mode 100755 index 186c0397..00000000 --- a/mm-video/vidc/vdec/inc/frameparser.h +++ /dev/null @@ -1,105 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef FRAMEPARSER_H -#define FRAMEPARSER_H - -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "h264_utils.h" -//#include - -enum codec_type -{ - CODEC_TYPE_MPEG4 = 0, - CODEC_TYPE_DIVX = 0, - CODEC_TYPE_H263 = 1, - CODEC_TYPE_H264 = 2, - CODEC_TYPE_VC1 = 3, - CODEC_TYPE_MPEG2 = 4, -#ifdef _MSM8974_ - CODEC_TYPE_VP8 = 5, - CODEC_TYPE_HEVC, -#endif - CODEC_TYPE_MAX -}; - -enum state_start_code_parse -{ - A0, - A1, - A2, - A3, - A4, - A5 -}; - -enum state_nal_parse -{ - NAL_LENGTH_ACC, - NAL_PARSING -}; - -class frame_parse -{ - -public: - H264_Utils *mutils; - int init_start_codes (codec_type codec_type_parse); - int parse_sc_frame (OMX_BUFFERHEADERTYPE *source, - OMX_BUFFERHEADERTYPE *dest , - OMX_U32 *partialframe); - int init_nal_length (unsigned int nal_length); - int parse_h264_nallength (OMX_BUFFERHEADERTYPE *source, - OMX_BUFFERHEADERTYPE *dest , - OMX_U32 *partialframe); - void flush (); - frame_parse (); - ~frame_parse (); - -private: - /*Variables for Start code based Parsing*/ - enum state_start_code_parse parse_state; - unsigned char *start_code; - unsigned char *mask_code; - unsigned char last_byte_h263; - unsigned char last_byte; - bool header_found; - bool skip_frame_boundary; - - /*Variables for NAL Length Parsing*/ - enum state_nal_parse state_nal; - unsigned int nal_length; - unsigned int accum_length; - unsigned int bytes_tobeparsed; - /*Functions to support additional start code parsing*/ - void parse_additional_start_code(OMX_U8 *psource, OMX_U32 *parsed_length); - void check_skip_frame_boundary(OMX_U32 *partial_frame); - void update_skip_frame(); -}; - -#endif /* FRAMEPARSER_H */ diff --git a/mm-video/vidc/vdec/inc/h264_utils.h b/mm-video/vidc/vdec/inc/h264_utils.h deleted file mode 100755 index 8006bb2a..00000000 --- a/mm-video/vidc/vdec/inc/h264_utils.h +++ /dev/null @@ -1,479 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef H264_UTILS_H -#define H264_UTILS_H - -/*======================================================================== - - O p e n M M - U t i l i t i e s a n d H e l p e r R o u t i n e s - -*//** @file H264_Utils.h -This module contains H264 video decoder utilities and helper routines. - -*//*====================================================================== */ - -/* ======================================================================= - - INCLUDE FILES FOR MODULE - -========================================================================== */ -#include -#include "Map.h" -#include "qtypes.h" -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" - -#define STD_MIN(x,y) (((x) < (y)) ? (x) : (y)) - -#define OMX_CORE_720P_HEIGHT 720 -#define OMX_CORE_720P_WIDTH 1280 - -#define PANSCAN_HDLR - -/* ======================================================================= - - DATA DECLARATIONS - -========================================================================== */ - -/* ----------------------------------------------------------------------- -** Constant / Define Declarations -** ----------------------------------------------------------------------- */ -// Common format block header definitions -#define MT_VIDEO_META_STREAM_HEADER 0x00 -#define MT_VIDEO_MEDIA_STREAM_HEADER 0x01 -#define MT_VIDEO_META_MEDIA_STREAM_HEADER 0x02 - -// H.264 format block header definitions -#define MT_VIDEO_H264_ACCESS_UNIT_FORMAT 0x00 -#define MT_VIDEO_H264_NAL_FORMT 0x01 -#define MT_VIDEO_H264_BYTE_FORMAT 0x02 -#define MT_VIDEO_H264_BYTE_STREAM_FORMAT 0x00 -#define MT_VIDEO_H264_NAL_UNIT_STREAM_FORMAT 0x01 -#define MT_VIDEO_H264_FORMAT_BLOCK_HEADER_SIZE 18 - -// MPEG-4 format block header definitions -#define MT_VIDEO_MPEG4_VOP_FORMAT 0x00 -#define MT_VIDEO_MPEG4_SLICE_FORMAT 0x01 -#define MT_VIDEO_MPEG4_BYTE_FORMAT 0x02 -#define MT_VIDEO_MPEG4_FORMAT_BLOCK_HEADER_SIZE 15 - -// H.263 format block header definitions -#define MT_VIDEO_H263_PICTURE_FORMAT 0x00 -#define MT_VIDEO_H263_GOB_FORMAT 0x01 -#define MT_VIDEO_H263_SLICE_STRUCTURED_FORMAT 0x02 -#define MT_VIDEO_H263_BYTE_FORMAT 0x03 -#define MT_VIDEO_H263_FORMAT_BLOCK_HEADER_SIZE 16 - -/* ======================================================================= -** Function Declarations -** ======================================================================= */ - -/* ----------------------------------------------------------------------- -** Type Declarations -** ----------------------------------------------------------------------- */ - -// This type is used when parsing an H.264 bitstream to collect H.264 NAL -// units that need to go in the meta data. -struct H264ParamNalu { - uint32 picSetID; - uint32 seqSetID; - uint32 picOrderCntType; - bool frameMbsOnlyFlag; - bool picOrderPresentFlag; - uint32 picWidthInMbsMinus1; - uint32 picHeightInMapUnitsMinus1; - uint32 log2MaxFrameNumMinus4; - uint32 log2MaxPicOrderCntLsbMinus4; - bool deltaPicOrderAlwaysZeroFlag; - //std::vector nalu; - uint32 nalu; - uint32 crop_left; - uint32 crop_right; - uint32 crop_top; - uint32 crop_bot; -}; -//typedef map H264ParamNaluSet; -typedef Map H264ParamNaluSet; - -typedef enum { - NALU_TYPE_UNSPECIFIED = 0, - NALU_TYPE_NON_IDR, - NALU_TYPE_PARTITION_A, - NALU_TYPE_PARTITION_B, - NALU_TYPE_PARTITION_C, - NALU_TYPE_IDR, - NALU_TYPE_SEI, - NALU_TYPE_SPS, - NALU_TYPE_PPS, - NALU_TYPE_ACCESS_DELIM, - NALU_TYPE_EOSEQ, - NALU_TYPE_EOSTREAM, - NALU_TYPE_FILLER_DATA, - NALU_TYPE_RESERVED, -} NALU_TYPE; - -// NAL header information -typedef struct { - uint32 nal_ref_idc; - uint32 nalu_type; - uint32 forbidden_zero_bit; -} NALU; - -// This structure contains persistent information about an H.264 stream as it -// is parsed. -//struct H264StreamInfo { -// H264ParamNaluSet pic; -// H264ParamNaluSet seq; -//}; - -class extra_data_parser; - -class RbspParser -/****************************************************************************** - ** This class is used to convert an H.264 NALU (network abstraction layer - ** unit) into RBSP (raw byte sequence payload) and extract bits from it. - *****************************************************************************/ -{ -public: - RbspParser (const uint8 *begin, const uint8 *end); - - virtual ~RbspParser (); - - uint32 next (); - void advance (); - uint32 u (uint32 n); - uint32 ue (); - int32 se (); - -private: - const uint8 *begin, *end; - int32 pos; - uint32 bit; - uint32 cursor; - bool advanceNeeded; -}; - -class H264_Utils -{ -public: - H264_Utils(); - ~H264_Utils(); - void initialize_frame_checking_environment(); - void allocate_rbsp_buffer(uint32 inputBufferSize); - bool isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, - OMX_IN OMX_U32 size_of_nal_length_field, - OMX_OUT OMX_BOOL &isNewFrame); - uint32 nalu_type; - -private: - boolean extract_rbsp(OMX_IN OMX_U8 *buffer, - OMX_IN OMX_U32 buffer_length, - OMX_IN OMX_U32 size_of_nal_length_field, - OMX_OUT OMX_U8 *rbsp_bistream, - OMX_OUT OMX_U32 *rbsp_length, - OMX_OUT NALU *nal_unit); - - unsigned m_height; - unsigned m_width; - H264ParamNaluSet pic; - H264ParamNaluSet seq; - uint8 *m_rbspBytes; - NALU m_prv_nalu; - bool m_forceToStichNextNAL; - bool m_au_data; -}; - -class perf_metrics -{ - public: - perf_metrics() : - start_time(0), - proc_time(0), - active(false) - { - }; - ~perf_metrics() {}; - void start(); - void stop(); - void end(OMX_U32 units_cntr = 0); - void reset(); - OMX_U64 processing_time_us(); - private: - inline OMX_U64 get_act_time(); - OMX_U64 start_time; - OMX_U64 proc_time; - bool active; -}; - -#define EMULATION_PREVENTION_THREE_BYTE 0x03 -#define MAX_CPB_COUNT 32 -#define NO_PAN_SCAN_BIT 0x00000100 -#define MAX_PAN_SCAN_RECT 3 -#define VALID_TS(ts) ((ts < LLONG_MAX)? true : false) -#define NALU_TYPE_VUI (NALU_TYPE_RESERVED + 1) - -enum SEI_PAYLOAD_TYPE -{ - BUFFERING_PERIOD = 0, - PIC_TIMING, - PAN_SCAN_RECT, - FILLER_PAYLOAD, - USER_DATA_REGISTERED_ITU_T_T35, - USER_DATA_UNREGISTERED, - RECOVERY_POINT, - DEC_REF_PIC_MARKING_REPETITION, - SPARE_PIC, - SCENE_INFO, - SUB_SEQ_INFO, - SUB_SEQ_LAYER_CHARACTERISTICS, - SUB_SEQ_CHARACTERISTICS, - FULL_FRAME_FREEZE, - FULL_FRAME_FREEZE_RELEASE, - FULL_FRAME_SNAPSHOT, - PROGRESSIVE_REFINEMENT_SEGMENT_START, - PROGRESSIVE_REFINEMENT_SEGMENT_END, - SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT = 0x2D -}; - -typedef struct -{ - OMX_U32 cpb_cnt; - OMX_U8 bit_rate_scale; - OMX_U8 cpb_size_scale; - OMX_U32 bit_rate_value[MAX_CPB_COUNT]; - OMX_U32 cpb_size_value[MAX_CPB_COUNT]; - OMX_U8 cbr_flag[MAX_CPB_COUNT]; - OMX_U8 initial_cpb_removal_delay_length; - OMX_U8 cpb_removal_delay_length; - OMX_U8 dpb_output_delay_length; - OMX_U8 time_offset_length; -} h264_hrd_param; - -typedef struct -{ - OMX_U32 aspect_ratio_idc; - OMX_U32 aspect_ratio_x; - OMX_U32 aspect_ratio_y; -} h264_aspect_ratio_info; - -typedef struct -{ - OMX_U8 aspect_ratio_info_present_flag; - h264_aspect_ratio_info aspect_ratio_info; - OMX_U8 timing_info_present_flag; - OMX_U32 num_units_in_tick; - OMX_U32 time_scale; - OMX_U8 fixed_frame_rate_flag; - OMX_U8 nal_hrd_parameters_present_flag; - h264_hrd_param nal_hrd_parameters; - OMX_U8 vcl_hrd_parameters_present_flag; - h264_hrd_param vcl_hrd_parameters; - OMX_U8 low_delay_hrd_flag; - OMX_U8 pic_struct_present_flag; - OMX_S64 fixed_fps_prev_ts; -} h264_vui_param; - -typedef struct -{ - OMX_U32 cpb_removal_delay; - OMX_U32 dpb_output_delay; - OMX_U8 pic_struct; - OMX_U32 num_clock_ts; - bool clock_ts_flag; - OMX_U8 ct_type; - OMX_U32 nuit_field_based_flag; - OMX_U8 counting_type; - OMX_U8 full_timestamp_flag; - OMX_U8 discontinuity_flag; - OMX_U8 cnt_dropped_flag; - OMX_U32 n_frames; - OMX_U32 seconds_value; - OMX_U32 minutes_value; - OMX_U32 hours_value; - OMX_S32 time_offset; - bool is_valid; -} h264_sei_pic_timing; - -typedef struct -{ - OMX_U32 initial_cpb_removal_delay[MAX_CPB_COUNT]; - OMX_U32 initial_cpb_removal_delay_offset[MAX_CPB_COUNT]; - OMX_U32 au_cntr; - OMX_S64 reference_ts; - bool is_valid; -} h264_sei_buf_period; - -typedef struct -{ - OMX_U32 rect_id; - OMX_U8 rect_cancel_flag; - OMX_U32 cnt; - OMX_S32 rect_left_offset[MAX_PAN_SCAN_RECT]; - OMX_S32 rect_right_offset[MAX_PAN_SCAN_RECT]; - OMX_S32 rect_top_offset[MAX_PAN_SCAN_RECT]; - OMX_S32 rect_bottom_offset[MAX_PAN_SCAN_RECT]; - OMX_U32 rect_repetition_period; -} h264_pan_scan; - -#ifdef PANSCAN_HDLR -template -class omx_dl_list -{ -public: - omx_dl_list() { head = tail = NULL; } ; - ~omx_dl_list() {}; - void add_multiple(NODE_STRUCT *data_arr, int data_num); - NODE_STRUCT *remove_first(); - NODE_STRUCT *remove_last(); - void add_last(NODE_STRUCT *data_ptr); - NODE_STRUCT *watch_first(); - NODE_STRUCT *watch_last(); -private: - NODE_STRUCT *head, *tail; -}; - -class panscan_handler -{ -public: - panscan_handler(); - ~panscan_handler(); - bool initialize(int num_data); - h264_pan_scan *get_free(); - h264_pan_scan *get_populated(OMX_S64 frame_ts); - void update_last(OMX_S64 frame_ts); -private: - typedef struct PANSCAN_NODE - { - h264_pan_scan pan_scan_param; - OMX_S64 start_ts, end_ts; - bool active; - PANSCAN_NODE *next, *prev; - } PANSCAN_NODE; - omx_dl_list panscan_used; - omx_dl_list panscan_free; - PANSCAN_NODE *panscan_data; -}; - -#if 1 // Debug panscan data - -#define PRINT_PANSCAN_PARAM(H264_PARAM) -#define PRINT_PANSCAN_DATA(NODE) - -#else - -#define PRINT_PANSCAN_PARAM(H264_PARAM) \ -do {\ - ALOGE("%s(): left_off(%ld) right_off(%ld) top_off(%ld) bottom_off(%ld)",\ - __FUNCTION__,\ - (H264_PARAM).rect_left_offset[0],\ - (H264_PARAM).rect_right_offset[0],\ - (H264_PARAM).rect_top_offset[0],\ - (H264_PARAM).rect_bottom_offset[0]);\ -}while(0) - -#define PRINT_PANSCAN_DATA(NODE) \ -do {\ - if (NODE) {\ - ALOGE("%s(): PANSCAN DATA start_ts(%lld) end_ts(%lld)", __FUNCTION__,\ - (NODE)->start_ts, (NODE)->end_ts);\ - PRINT_PANSCAN_PARAM(NODE->pan_scan_param);\ - }\ -}while(0) - -#endif // End debug panscan data - -#endif - -class h264_stream_parser -{ - public: - h264_stream_parser(); - ~h264_stream_parser(); - void reset(); - void fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp); - void fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio); - void parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, - OMX_U32 nal_type = NALU_TYPE_UNSPECIFIED, - bool enable_emu_sc = true); - OMX_S64 process_ts_with_sei_vui(OMX_S64 timestamp); - void get_frame_pack_data(OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack); - bool is_mbaff(); - void get_frame_rate(OMX_U32 *frame_rate); -#ifdef PANSCAN_HDLR - void update_panscan_data(OMX_S64 timestamp); -#endif - private: - void init_bitstream(OMX_U8* data, OMX_U32 size); - OMX_U32 extract_bits(OMX_U32 n); - inline bool more_bits(); - void read_word(); - OMX_U32 uev(); - OMX_S32 sev(); - OMX_S32 iv(OMX_U32 n_bits); - void parse_sps(); - void parse_vui(bool vui_in_extradata = true); - void aspect_ratio_info(); - void hrd_parameters(h264_hrd_param *hrd_param); - void parse_sei(); - void sei_buffering_period(); - void sei_picture_timing(); - void sei_pan_scan(); - void scaling_list(OMX_U32 size_of_scaling_list); - - void print_pan_data(h264_pan_scan *pan_scan_param); - void print_frame_pack(); - - OMX_U32 get_nal_unit_type(OMX_U32 *nal_unit_type); - OMX_S64 calculate_buf_period_ts(OMX_S64 timestamp); - OMX_S64 calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor); - void parse_frame_pack(); - - OMX_U32 curr_32_bit; - OMX_U32 bits_read; - OMX_U32 zero_cntr; - OMX_U32 emulation_code_skip_cntr; - OMX_U8* bitstream; - OMX_U32 bitstream_bytes; - OMX_U32 frame_rate; - bool emulation_sc_enabled; - - h264_vui_param vui_param; - h264_sei_buf_period sei_buf_period; - h264_sei_pic_timing sei_pic_timing; -#ifdef PANSCAN_HDLR - panscan_handler *panscan_hdl; -#else - h264_pan_scan panscan_param; -#endif - OMX_QCOM_FRAME_PACK_ARRANGEMENT frame_packing_arrangement; - bool mbaff_flag; -}; - -#endif /* H264_UTILS_H */ diff --git a/mm-video/vidc/vdec/inc/hevc_utils.h b/mm-video/vidc/vdec/inc/hevc_utils.h deleted file mode 100644 index 6482ee47..00000000 --- a/mm-video/vidc/vdec/inc/hevc_utils.h +++ /dev/null @@ -1,146 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - - -#ifndef HEVC_UTILS_H -#define HEVC_UTILS_H - -/*======================================================================== - - O p e n M M - U t i l i t i e s a n d H e l p e r R o u t i n e s - -*//** @file HEVC_Utils.h -This module contains H264 video decoder utilities and helper routines. - -*//*====================================================================== */ - -/* ======================================================================= - - INCLUDE FILES FOR MODULE - -========================================================================== */ -#include -#include -#include "Map.h" -#include "qtypes.h" -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" - - -class HEVC_Utils -{ -public: - HEVC_Utils(); - ~HEVC_Utils(); - - enum { - NAL_UNIT_CODED_SLICE_TRAIL_N, // 0 - NAL_UNIT_CODED_SLICE_TRAIL_R, // 1 - NAL_UNIT_CODED_SLICE_TSA_N, // 2 - NAL_UNIT_CODED_SLICE_TLA, // 3 - NAL_UNIT_CODED_SLICE_STSA_N, // 4 - NAL_UNIT_CODED_SLICE_STSA_R, // 5 - NAL_UNIT_CODED_SLICE_RADL_N, // 6 - NAL_UNIT_CODED_SLICE_DLP, // 7 - NAL_UNIT_CODED_SLICE_RASL_N, // 8 - NAL_UNIT_CODED_SLICE_TFD, // 9 - NAL_UNIT_RESERVED_10, - NAL_UNIT_RESERVED_11, - NAL_UNIT_RESERVED_12, - NAL_UNIT_RESERVED_13, - NAL_UNIT_RESERVED_14, - NAL_UNIT_RESERVED_15, - NAL_UNIT_CODED_SLICE_BLA, // 16 - NAL_UNIT_CODED_SLICE_BLANT, // 17 - NAL_UNIT_CODED_SLICE_BLA_N_LP, // 18 - NAL_UNIT_CODED_SLICE_IDR, // 19 - NAL_UNIT_CODED_SLICE_IDR_N_LP, // 20 - NAL_UNIT_CODED_SLICE_CRA, // 21 - NAL_UNIT_RESERVED_22, - NAL_UNIT_RESERVED_23, - NAL_UNIT_RESERVED_24, - NAL_UNIT_RESERVED_25, - NAL_UNIT_RESERVED_26, - NAL_UNIT_RESERVED_27, - - NAL_UNIT_RESERVED_28, - NAL_UNIT_RESERVED_29, - NAL_UNIT_RESERVED_30, - NAL_UNIT_RESERVED_31, - - NAL_UNIT_VPS, // 32 - NAL_UNIT_SPS, // 33 - NAL_UNIT_PPS, // 34 - NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35 - NAL_UNIT_EOS, // 36 - NAL_UNIT_EOB, // 37 - NAL_UNIT_FILLER_DATA, // 38 - NAL_UNIT_SEI, // 39 Prefix SEI - NAL_UNIT_SEI_SUFFIX, // 40 Suffix SEI - - NAL_UNIT_RESERVED_41, - NAL_UNIT_RESERVED_42, - NAL_UNIT_RESERVED_43, - NAL_UNIT_RESERVED_44, - NAL_UNIT_RESERVED_45, - NAL_UNIT_RESERVED_46, - NAL_UNIT_RESERVED_47, - NAL_UNIT_UNSPECIFIED_48, - NAL_UNIT_UNSPECIFIED_49, - NAL_UNIT_UNSPECIFIED_50, - NAL_UNIT_UNSPECIFIED_51, - NAL_UNIT_UNSPECIFIED_52, - NAL_UNIT_UNSPECIFIED_53, - NAL_UNIT_UNSPECIFIED_54, - NAL_UNIT_UNSPECIFIED_55, - NAL_UNIT_UNSPECIFIED_56, - NAL_UNIT_UNSPECIFIED_57, - NAL_UNIT_UNSPECIFIED_58, - NAL_UNIT_UNSPECIFIED_59, - NAL_UNIT_UNSPECIFIED_60, - NAL_UNIT_UNSPECIFIED_61, - NAL_UNIT_UNSPECIFIED_62, - NAL_UNIT_UNSPECIFIED_63, - NAL_UNIT_INVALID, - }; - - - void initialize_frame_checking_environment(); - bool isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, - OMX_IN OMX_U32 size_of_nal_length_field, - OMX_OUT OMX_BOOL &isNewFrame); - -private: - - bool m_forceToStichNextNAL; - bool m_au_data; - uint32 nalu_type; -}; - -#endif /* HEVC_UTILS_H */ diff --git a/mm-video/vidc/vdec/inc/message_queue.h b/mm-video/vidc/vdec/inc/message_queue.h deleted file mode 100755 index d5924e6a..00000000 --- a/mm-video/vidc/vdec/inc/message_queue.h +++ /dev/null @@ -1,78 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef QUEUE_H -#define QUEUE_H - -#include -#include -#include -#include - -/* Message Queue structure */ -struct video_msgq -{ - /* Command to be executed */ - unsigned int cmd; - - unsigned int status; - - /* Client-specific data */ - void *clientdata; -}; - - -/* Thread & Message Queue information */ -struct video_queue_context -{ - /* Message Queue related members */ - pthread_mutex_t mutex; - sem_t sem_message; - int commandq_size; - int dataq_size; - struct video_msgq *ptr_dataq; - struct video_msgq *ptr_cmdq; - int write_dataq ; - int read_dataq; - int write_comq ; - int read_comq ; - -}; - -int check_if_queue_empty ( unsigned int queuetocheck,void* queuecontext ); - -struct video_msgq * queue_get_cmd ( void* queuecontext ); - -int queue_post_cmdq ( void *queuecontext, - struct video_msgq *post_msg - ); - -int queue_post_dataq ( void *queuecontext, - struct video_msgq *post_msg - ); - -#endif /* QUEUE_H */ diff --git a/mm-video/vidc/vdec/inc/mp4_utils.h b/mm-video/vidc/vdec/inc/mp4_utils.h deleted file mode 100644 index 9a435bf7..00000000 --- a/mm-video/vidc/vdec/inc/mp4_utils.h +++ /dev/null @@ -1,170 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef MP4_UTILS_H -#define MP4_UTILS_H -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -typedef signed long long int64; -typedef unsigned int uint32; /* Unsigned 32 bit value */ -typedef unsigned short uint16; /* Unsigned 16 bit value */ -typedef unsigned char uint8; /* Unsigned 8 bit value */ - -typedef int int32; /* Signed 32 bit value */ -typedef signed short int16; /* Signed 16 bit value */ -typedef signed char int8; /* Signed 8 bit value */ - -typedef unsigned char byte; /* Unsigned 8 bit value type. */ -#define SIMPLE_PROFILE_LEVEL0 0x08 -#define SIMPLE_PROFILE_LEVEL1 0x01 -#define SIMPLE_PROFILE_LEVEL2 0x02 -#define SIMPLE_PROFILE_LEVEL3 0x03 -#define SIMPLE_PROFILE_LEVEL4A 0x04 -#define SIMPLE_PROFILE_LEVEL5 0x05 -#define SIMPLE_PROFILE_LEVEL6 0x06 -#define SIMPLE_PROFILE_LEVEL0B 0x09 - -#define SIMPLE_SCALABLE_PROFILE_LEVEL0 0x10 -#define SIMPLE_SCALABLE_PROFILE_LEVEL1 0x11 -#define SIMPLE_SCALABLE_PROFILE_LEVEL2 0x12 - -#define SIMPLE_SCALABLE_PROFILE_LEVEL0 0x10 -#define SIMPLE_SCALABLE_PROFILE_LEVEL1 0x11 -#define SIMPLE_SCALABLE_PROFILE_LEVEL2 0x12 -#define ADVANCED_SIMPLE_PROFILE_LEVEL0 0xF0 -#define ADVANCED_SIMPLE_PROFILE_LEVEL1 0xF1 -#define ADVANCED_SIMPLE_PROFILE_LEVEL2 0xF2 -#define ADVANCED_SIMPLE_PROFILE_LEVEL3 0xF3 -#define ADVANCED_SIMPLE_PROFILE_LEVEL4 0xF4 -#define ADVANCED_SIMPLE_PROFILE_LEVEL5 0xF5 - -#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x000001B0 -#define MP4ERROR_SUCCESS 0 - -#define VIDEO_OBJECT_LAYER_START_CODE_MASK 0xFFFFFFF0 -#define VIDEO_OBJECT_LAYER_START_CODE 0x00000120 -#define VOP_START_CODE_MASK 0xFFFFFFFF -#define VOP_START_CODE 0x000001B6 -#define GOV_START_CODE 0x000001B3 -#define SHORT_HEADER_MASK 0xFFFFFC00 -#define SHORT_HEADER_START_MARKER 0x00008000 -#define SHORT_HEADER_START_CODE 0x00008000 -#define SPARK1_START_CODE 0x00008400 -#define MPEG4_SHAPE_RECTANGULAR 0x00 -#define EXTENDED_PAR 0xF -#define SHORT_VIDEO_START_MARKER 0x20 -#define MP4_INVALID_VOL_PARAM (0x0001) // unsupported VOL parameter -#define MP4ERROR_UNSUPPORTED_UFEP -1068 -#define MP4ERROR_UNSUPPORTED_SOURCE_FORMAT -1069 -#define MASK(x) (0xFFFFFFFF >> (32 - (x))) -#define VISUAL_OBJECT_TYPE_VIDEO_ID 0x1 -#define VISUAL_OBJECT_START_CODE 0x000001B5 -#define VIDEO_OBJECT_START_CODE_MASK 0xFFFFFFE0 -#define VIDEO_OBJECT_START_CODE 0x00000100 - -#define RESERVED_OBJECT_TYPE 0x0 -#define SIMPLE_OBJECT_TYPE 0x1 -#define SIMPLE_SCALABLE_OBJECT_TYPE 0x2 -#define CORE_OBJECT_TYPE 0x3 -#define MAIN_OBJECT_TYPE 0x4 -#define N_BIT_OBJECT_TYPE 0x5 -#define BASIC_ANIMATED_2D_TEXTURE 0x6 -#define ANIMATED_2D_MESH 0x7 -#define ADVANCED_SIMPLE 0x11 - - -#define SIMPLE_L1_MAX_VBVBUFFERSIZE 10 /* VBV Max Buffer size=10 (p. 498) */ -#define SIMPLE_L1_MAX_BITRATE 160 /* is is 64kpbs or 160 400bits/sec units */ -#define SIMPLE_L2_MAX_VBVBUFFERSIZE 40 /* VBV Max Buffer size = 40 */ -#define SIMPLE_L2_MAX_BITRATE 320 /* 320 400bps units = 128kpbs */ -#define SIMPLE_L3_MAX_VBVBUFFERSIZE 40 /* VBV Max Buffer size = 40 */ -#define SIMPLE_L3_MAX_BITRATE 960 /* 960 400bps units = 384kpbs */ - -/* The MP4 decoder currently supports Simple Profile@L3 */ -#define MAX_VBVBUFFERSIZE (SIMPLE_L3_MAX_VBVBUFFERSIZE) -#define MAX_BITRATE (SIMPLE_L3_MAX_BITRATE) - -#define MAX_QUANTPRECISION 9 -#define MIN_QUANTPRECISION 3 - -#define MP4_VGA_WIDTH 640 -#define MP4_VGA_HEIGHT 480 -#define MP4_WVGA_WIDTH 800 -#define MP4_WVGA_HEIGHT 480 -#define MP4_720P_WIDTH 1280 -#define MP4_720P_HEIGHT 720 - -#define MP4_MAX_DECODE_WIDTH MP4_720P_WIDTH -#define MP4_MAX_DECODE_HEIGHT MP4_720P_HEIGHT - -typedef struct { - unsigned char *data; - unsigned long int numBytes; -} mp4StreamType; - -#define MAX_FRAMES_IN_CHUNK 10 -#define VOP_START_CODE 0x000001B6 -#define VOL_START_CODE 0x000001B0 - -typedef enum VOPTYPE -{ - NO_VOP = -1, // bitstream contains no VOP. - MPEG4_I_VOP = 0, // bitstream contains an MPEG4 I-VOP - MPEG4_P_VOP = 1, // bitstream contains an MPEG4 P-VOP - MPEG4_B_VOP = 2, // bitstream contains an MPEG4 B-VOP - MPEG4_S_VOP = 3, // bitstream contains an MPEG4 S-VOP -} VOP_TYPE; - -typedef struct -{ - uint32 timestamp_increment; - uint32 offset; - uint32 size; - VOP_TYPE vopType; -} mp4_frame_info_type; - -class MP4_Utils { -private: - struct posInfoType { - uint8 *bytePtr; - uint8 bitPos; - }; - - posInfoType m_posInfo; - byte *m_dataBeginPtr; - unsigned int vop_time_resolution; - bool vop_time_found; - uint16 m_SrcWidth, m_SrcHeight; // Dimensions of the source clip -public: - MP4_Utils(); - ~MP4_Utils(); - int16 populateHeightNWidthFromShortHeader(mp4StreamType * psBits); - bool parseHeader(mp4StreamType * psBits); - static uint32 read_bit_field(posInfoType * posPtr, uint32 size); - bool is_notcodec_vop(unsigned char *pbuffer, unsigned int len); -}; -#endif diff --git a/mm-video/vidc/vdec/inc/omx_vdec.h b/mm-video/vidc/vdec/inc/omx_vdec.h deleted file mode 100644 index c7877549..00000000 --- a/mm-video/vidc/vdec/inc/omx_vdec.h +++ /dev/null @@ -1,989 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef __OMX_VDEC_H__ -#define __OMX_VDEC_H__ -/*============================================================================ - O p e n M A X Component - Video Decoder - -*//** @file comx_vdec.h - This module contains the class definition for openMAX decoder component. - -*//*========================================================================*/ - -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include - -static ptrdiff_t x; - -#ifdef _ANDROID_ -#ifdef MAX_RES_720P -#define LOG_TAG "OMX-VDEC-720P" -#elif MAX_RES_1080P -#define LOG_TAG "OMX-VDEC-1080P" -#else -#define LOG_TAG "OMX-VDEC" -#endif - -#ifdef USE_ION -#include -//#include -//#else -#endif -#include -#include -extern "C"{ -#include -} -#include -#include -#define TIMEOUT 5000 - -#else //_ANDROID_ -#define DEBUG_PRINT_LOW printf -#define DEBUG_PRINT_HIGH printf -#define DEBUG_PRINT_ERROR printf -#endif // _ANDROID_ - -#ifdef _MSM8974_ -#define DEBUG_PRINT_LOW -#define DEBUG_PRINT_HIGH printf -#define DEBUG_PRINT_ERROR printf -#endif - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -#include -#endif - -#include - -#if defined (_ANDROID_ICS_) -#include -#endif - -#include -#ifndef PC_DEBUG -#include -#endif -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "qc_omx_component.h" -#include -#include -#include "frameparser.h" -#ifdef MAX_RES_1080P -#include "mp4_utils.h" -#endif -#include -#include "extra_data_handler.h" -#include "ts_parser.h" -#include "vidc_color_converter.h" -extern "C" { - OMX_API void * get_omx_component_factory_fn(void); -} - -#ifdef _ANDROID_ - using namespace android; -#ifdef USE_ION - class VideoHeap : public MemoryHeapBase - { - public: - VideoHeap(int devicefd, size_t size, void* base,struct ion_handle *handle,int mapfd); - virtual ~VideoHeap() {} - private: - int m_ion_device_fd; - struct ion_handle *m_ion_handle; - }; -#else - // local pmem heap object - class VideoHeap : public MemoryHeapBase - { - public: - VideoHeap(int fd, size_t size, void* base); - virtual ~VideoHeap() {} - }; -#endif -#endif // _ANDROID_ -////////////////////////////////////////////////////////////////////////////// -// Module specific globals -////////////////////////////////////////////////////////////////////////////// -#define OMX_SPEC_VERSION 0x00000101 - - -////////////////////////////////////////////////////////////////////////////// -// Macros -////////////////////////////////////////////////////////////////////////////// -#define PrintFrameHdr(bufHdr) DEBUG_PRINT("bufHdr %x buf %x size %d TS %d\n",\ - (unsigned) bufHdr,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp) - -// BitMask Management logic -#define BITS_PER_BYTE 32 -#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE) -#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE) -#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE)) -#define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ - &= ~(BITMASK_FLAG(mIndex)) -#define BITMASK_SET(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ - |= BITMASK_FLAG(mIndex) -#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) -#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) == 0x0) -#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) -#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) == 0x0) - -#define OMX_CORE_CONTROL_CMDQ_SIZE 100 -#define OMX_CORE_QCIF_HEIGHT 144 -#define OMX_CORE_QCIF_WIDTH 176 -#define OMX_CORE_VGA_HEIGHT 480 -#define OMX_CORE_VGA_WIDTH 640 -#define OMX_CORE_WVGA_HEIGHT 480 -#define OMX_CORE_WVGA_WIDTH 800 - -#define DESC_BUFFER_SIZE (8192 * 16) - -#ifdef _ANDROID_ -#define MAX_NUM_INPUT_OUTPUT_BUFFERS 32 -#endif - -#define OMX_FRAMEINFO_EXTRADATA 0x00010000 -#define OMX_INTERLACE_EXTRADATA 0x00020000 -#define OMX_TIMEINFO_EXTRADATA 0x00040000 -#define OMX_PORTDEF_EXTRADATA 0x00080000 -#define OMX_EXTNUSER_EXTRADATA 0x00100000 -#define DRIVER_EXTRADATA_MASK 0x0000FFFF - -#define OMX_INTERLACE_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ - sizeof(OMX_STREAMINTERLACEFORMAT) + 3)&(~3)) -#define OMX_FRAMEINFO_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ - sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO) + 3)&(~3)) -#define OMX_PORTDEF_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ - sizeof(OMX_PARAM_PORTDEFINITIONTYPE) + 3)&(~3)) - -// Define next macro with required values to enable default extradata, -// VDEC_EXTRADATA_MB_ERROR_MAP -// OMX_INTERLACE_EXTRADATA -// OMX_FRAMEINFO_EXTRADATA -// OMX_TIMEINFO_EXTRADATA - -//#define DEFAULT_EXTRADATA (OMX_FRAMEINFO_EXTRADATA|OMX_INTERLACE_EXTRADATA) - -enum port_indexes -{ - OMX_CORE_INPUT_PORT_INDEX =0, - OMX_CORE_OUTPUT_PORT_INDEX =1 -}; -#ifdef USE_ION -struct vdec_ion -{ - int ion_device_fd; - struct ion_fd_data fd_ion_data; - struct ion_allocation_data ion_alloc_data; -}; -#endif - -#ifdef _MSM8974_ -struct extradata_buffer_info { - int buffer_size; - char* uaddr; - int count; - int size; -#ifdef USE_ION - struct vdec_ion ion; -#endif -}; -#endif - -struct video_driver_context -{ - int video_driver_fd; - enum vdec_codec decoder_format; - enum vdec_output_fromat output_format; - enum vdec_interlaced_format interlace; - enum vdec_output_order picture_order; - struct vdec_picsize video_resolution; - struct vdec_allocatorproperty ip_buf; - struct vdec_allocatorproperty op_buf; - struct vdec_bufferpayload *ptr_inputbuffer; - struct vdec_bufferpayload *ptr_outputbuffer; - struct vdec_output_frameinfo *ptr_respbuffer; -#ifdef USE_ION - struct vdec_ion *ip_buf_ion_info; - struct vdec_ion *op_buf_ion_info; - struct vdec_ion h264_mv; - struct vdec_ion meta_buffer; - struct vdec_ion meta_buffer_iommu; -#endif - struct vdec_framerate frame_rate; - unsigned extradata; - bool timestamp_adjust; - char kind[128]; - bool idr_only_decoding; - unsigned disable_dmx; -#ifdef _MSM8974_ - struct extradata_buffer_info extradata_info; - int num_planes; -#endif -}; - -#ifdef _ANDROID_ -class DivXDrmDecrypt; -#endif //_ANDROID_ - -struct video_decoder_capability { - unsigned int min_width; - unsigned int max_width; - unsigned int min_height; - unsigned int max_height; -}; -// OMX video decoder class -class omx_vdec: public qc_omx_component -{ - -public: - omx_vdec(); // constructor - virtual ~omx_vdec(); // destructor - - static int async_message_process (void *context, void* message); - static void process_event_cb(void *ctxt,unsigned char id); - - OMX_ERRORTYPE allocate_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes - ); - - - OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp); - - OMX_ERRORTYPE component_init(OMX_STRING role); - - OMX_ERRORTYPE component_role_enum( - OMX_HANDLETYPE hComp, - OMX_U8 *role, - OMX_U32 index - ); - - OMX_ERRORTYPE component_tunnel_request( - OMX_HANDLETYPE hComp, - OMX_U32 port, - OMX_HANDLETYPE peerComponent, - OMX_U32 peerPort, - OMX_TUNNELSETUPTYPE *tunnelSetup - ); - - OMX_ERRORTYPE empty_this_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - - - OMX_ERRORTYPE fill_this_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - - OMX_ERRORTYPE free_buffer( - OMX_HANDLETYPE hComp, - OMX_U32 port, - OMX_BUFFERHEADERTYPE *buffer - ); - - OMX_ERRORTYPE get_component_version( - OMX_HANDLETYPE hComp, - OMX_STRING componentName, - OMX_VERSIONTYPE *componentVersion, - OMX_VERSIONTYPE *specVersion, - OMX_UUIDTYPE *componentUUID - ); - - OMX_ERRORTYPE get_config( - OMX_HANDLETYPE hComp, - OMX_INDEXTYPE configIndex, - OMX_PTR configData - ); - - OMX_ERRORTYPE get_extension_index( - OMX_HANDLETYPE hComp, - OMX_STRING paramName, - OMX_INDEXTYPE *indexType - ); - - OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE paramIndex, - OMX_PTR paramData); - - OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp, - OMX_STATETYPE *state); - - - - OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp, - OMX_COMMANDTYPE cmd, - OMX_U32 param1, - OMX_PTR cmdData); - - - OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp, - OMX_CALLBACKTYPE *callbacks, - OMX_PTR appData); - - OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE configIndex, - OMX_PTR configData); - - OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE paramIndex, - OMX_PTR paramData); - - OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8 *buffer); - - OMX_ERRORTYPE use_input_heap_buffers( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8* buffer); - - OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - void * eglImage); - void complete_pending_buffer_done_cbs(); - struct video_driver_context drv_ctx; -#ifdef _MSM8974_ - OMX_ERRORTYPE allocate_extradata(); - void free_extradata(); - int update_resolution(int width, int height, int stride, int scan_lines); - OMX_ERRORTYPE is_video_session_supported(); -#endif - int m_pipe_in; - int m_pipe_out; - pthread_t msg_thread_id; - pthread_t async_thread_id; - bool is_component_secure(); - -private: - // Bit Positions - enum flags_bit_positions - { - // Defer transition to IDLE - OMX_COMPONENT_IDLE_PENDING =0x1, - // Defer transition to LOADING - OMX_COMPONENT_LOADING_PENDING =0x2, - // First Buffer Pending - OMX_COMPONENT_FIRST_BUFFER_PENDING =0x3, - // Second Buffer Pending - OMX_COMPONENT_SECOND_BUFFER_PENDING =0x4, - // Defer transition to Enable - OMX_COMPONENT_INPUT_ENABLE_PENDING =0x5, - // Defer transition to Enable - OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x6, - // Defer transition to Disable - OMX_COMPONENT_INPUT_DISABLE_PENDING =0x7, - // Defer transition to Disable - OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x8, - //defer flush notification - OMX_COMPONENT_OUTPUT_FLUSH_PENDING =0x9, - OMX_COMPONENT_INPUT_FLUSH_PENDING =0xA, - OMX_COMPONENT_PAUSE_PENDING =0xB, - OMX_COMPONENT_EXECUTE_PENDING =0xC, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING =0xD, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE - }; - - // Deferred callback identifiers - enum - { - //Event Callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_EVENT = 0x1, - //Buffer Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2, - //Frame Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3, - //Buffer Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_FTB = 0x4, - //Frame Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_ETB = 0x5, - //Command - OMX_COMPONENT_GENERATE_COMMAND = 0x6, - //Push-Pending Buffers - OMX_COMPONENT_PUSH_PENDING_BUFS = 0x7, - // Empty Buffer Done callbacks - OMX_COMPONENT_GENERATE_EBD = 0x8, - //Flush Event Callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_EVENT_FLUSH = 0x9, - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH = 0x0A, - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH = 0x0B, - OMX_COMPONENT_GENERATE_FBD = 0xc, - OMX_COMPONENT_GENERATE_START_DONE = 0xD, - OMX_COMPONENT_GENERATE_PAUSE_DONE = 0xE, - OMX_COMPONENT_GENERATE_RESUME_DONE = 0xF, - OMX_COMPONENT_GENERATE_STOP_DONE = 0x10, - OMX_COMPONENT_GENERATE_HARDWARE_ERROR = 0x11, - OMX_COMPONENT_GENERATE_ETB_ARBITRARY = 0x12, - OMX_COMPONENT_GENERATE_PORT_RECONFIG = 0x13, - OMX_COMPONENT_GENERATE_EOS_DONE = 0x14, - OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG = 0x15, - OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED = 0x16, - OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING = 0x17, - }; - - enum vc1_profile_type - { - VC1_SP_MP_RCV = 1, - VC1_AP = 2 - }; - -#ifdef _MSM8974_ - enum v4l2_ports - { - CAPTURE_PORT, - OUTPUT_PORT, - MAX_PORT - }; -#endif - - struct omx_event - { - unsigned param1; - unsigned param2; - unsigned id; - }; - - struct omx_cmd_queue - { - omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE]; - unsigned m_read; - unsigned m_write; - unsigned m_size; - - omx_cmd_queue(); - ~omx_cmd_queue(); - bool insert_entry(unsigned p1, unsigned p2, unsigned id); - bool pop_entry(unsigned *p1,unsigned *p2, unsigned *id); - // get msgtype of the first ele from the queue - unsigned get_q_msg_type(); - - }; - -#ifdef _ANDROID_ - struct ts_entry - { - OMX_TICKS timestamp; - bool valid; - }; - - struct ts_arr_list - { - ts_entry m_ts_arr_list[MAX_NUM_INPUT_OUTPUT_BUFFERS]; - - ts_arr_list(); - ~ts_arr_list(); - - bool insert_ts(OMX_TICKS ts); - bool pop_min_ts(OMX_TICKS &ts); - bool reset_ts_list(); - }; -#endif - - struct desc_buffer_hdr - { - OMX_U8 *buf_addr; - OMX_U32 desc_data_size; - }; - bool allocate_done(void); - bool allocate_input_done(void); - bool allocate_output_done(void); - - OMX_ERRORTYPE free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - OMX_ERRORTYPE free_input_buffer(unsigned int bufferindex, - OMX_BUFFERHEADERTYPE *pmem_bufferHdr); - OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - void free_output_buffer_header(); - void free_input_buffer_header(); - - OMX_ERRORTYPE allocate_input_heap_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes); - - - OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes); - - OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port,OMX_PTR appData, - OMX_U32 bytes); - OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8 *buffer); -#ifdef MAX_RES_720P - OMX_ERRORTYPE get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); -#endif -#ifdef MAX_RES_1080P - OMX_ERRORTYPE get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); -#endif - - OMX_ERRORTYPE allocate_desc_buffer(OMX_U32 index); - OMX_ERRORTYPE allocate_output_headers(); - bool execute_omx_flush(OMX_U32); - bool execute_output_flush(); - bool execute_input_flush(); - OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE * buffer); - - OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE * buffer); - OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer); - - OMX_ERRORTYPE empty_this_buffer_proxy_arbitrary(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - OMX_ERRORTYPE push_input_buffer (OMX_HANDLETYPE hComp); - OMX_ERRORTYPE push_input_sc_codec (OMX_HANDLETYPE hComp); - OMX_ERRORTYPE push_input_h264 (OMX_HANDLETYPE hComp); - OMX_ERRORTYPE push_input_vc1 (OMX_HANDLETYPE hComp); - - OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer); - bool release_done(); - - bool release_output_done(); - bool release_input_done(); - OMX_ERRORTYPE get_buffer_req(vdec_allocatorproperty *buffer_prop); - OMX_ERRORTYPE set_buffer_req(vdec_allocatorproperty *buffer_prop); - OMX_ERRORTYPE start_port_reconfig(); - OMX_ERRORTYPE update_picture_resolution(); - int stream_off(OMX_U32 port); - void adjust_timestamp(OMX_S64 &act_timestamp); - void set_frame_rate(OMX_S64 act_timestamp); - void handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr); - void handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr); - void print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra); -#ifdef _MSM8974_ - void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 interlaced_format_type); - OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool is_internal, - bool enable = true); - void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 num_conceal_mb, - OMX_U32 picture_type, - OMX_U32 frame_rate, - struct msm_vidc_panscan_window_payload *panscan_payload, - struct vdec_aspectratioinfo *aspect_ratio_info); -#else - void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 interlaced_format_type, OMX_U32 buf_index); - OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool enable = true); -#endif - void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 num_conceal_mb, - OMX_U32 picture_type, - OMX_S64 timestamp, - OMX_U32 frame_rate, - struct vdec_aspectratioinfo *aspect_ratio_info); - void fill_aspect_ratio_info(struct vdec_aspectratioinfo *aspect_ratio_info, - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info); - void append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra); - OMX_ERRORTYPE update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn); - void append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra); - void append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_extn); - void append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_user); - void insert_demux_addr_offset(OMX_U32 address_offset); - void extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr); - OMX_ERRORTYPE handle_demux_data(OMX_BUFFERHEADERTYPE *buf_hdr); - OMX_U32 count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra); - - bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, - OMX_U32 alignment); -#ifdef USE_ION - int alloc_map_ion_memory(OMX_U32 buffer_size, - OMX_U32 alignment, struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data,int flag); - void free_ion_memory(struct vdec_ion *buf_ion_info); -#endif - - - OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp, - OMX_COMMANDTYPE cmd, - OMX_U32 param1, - OMX_PTR cmdData); - bool post_event( unsigned int p1, - unsigned int p2, - unsigned int id - ); - inline int clip2(int x) - { - x = x -1; - x = x | x >> 1; - x = x | x >> 2; - x = x | x >> 4; - x = x | x >> 16; - x = x + 1; - return x; - } - -#ifdef MAX_RES_1080P - OMX_ERRORTYPE vdec_alloc_h264_mv(); - void vdec_dealloc_h264_mv(); - OMX_ERRORTYPE vdec_alloc_meta_buffers(); - void vdec_dealloc_meta_buffers(); -#endif - - inline void omx_report_error () - { - if (m_cb.EventHandler && !m_error_propogated) - { - ALOGE("\nERROR: Sending OMX_EventError to Client"); - m_error_propogated = true; - m_cb.EventHandler(&m_cmp,m_app_data, - OMX_EventError,OMX_ErrorHardware,0,NULL); - } - } - - inline void omx_report_unsupported_setting () - { - if (m_cb.EventHandler && !m_error_propogated) - { - DEBUG_PRINT_ERROR( - "\nERROR: Sending OMX_ErrorUnsupportedSetting to Client"); - m_error_propogated = true; - m_cb.EventHandler(&m_cmp,m_app_data, - OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL); - } - } -#ifdef _ANDROID_ - OMX_ERRORTYPE createDivxDrmContext(); -#endif //_ANDROID_ -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - OMX_ERRORTYPE use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data); -#endif -#if defined (_ANDROID_ICS_) - struct nativebuffer{ - native_handle_t *nativehandle; - private_handle_t *privatehandle; - int inuse; - }; - nativebuffer native_buffer[MAX_NUM_INPUT_OUTPUT_BUFFERS]; -#endif - - - //************************************************************* - //*******************MEMBER VARIABLES ************************* - //************************************************************* - pthread_mutex_t m_lock; - pthread_mutex_t c_lock; - //sem to handle the minimum procesing of commands - sem_t m_cmd_lock; - bool m_error_propogated; - // compression format - OMX_VIDEO_CODINGTYPE eCompressionFormat; - // OMX State - OMX_STATETYPE m_state; - // Application data - OMX_PTR m_app_data; - // Application callbacks - OMX_CALLBACKTYPE m_cb; - OMX_PRIORITYMGMTTYPE m_priority_mgm ; - OMX_PARAM_BUFFERSUPPLIERTYPE m_buffer_supplier; - // fill this buffer queue - omx_cmd_queue m_ftb_q; - // Command Q for rest of the events - omx_cmd_queue m_cmd_q; - omx_cmd_queue m_etb_q; - // Input memory pointer - OMX_BUFFERHEADERTYPE *m_inp_mem_ptr; - // Output memory pointer - OMX_BUFFERHEADERTYPE *m_out_mem_ptr; - // number of input bitstream error frame count - unsigned int m_inp_err_count; -#ifdef _ANDROID_ - // Timestamp list - ts_arr_list m_timestamp_list; -#endif - - bool input_flush_progress; - bool output_flush_progress; - bool input_use_buffer; - bool output_use_buffer; - bool ouput_egl_buffers; - OMX_BOOL m_use_output_pmem; - OMX_BOOL m_out_mem_region_smi; - OMX_BOOL m_out_pvt_entry_pmem; - - int pending_input_buffers; - int pending_output_buffers; - // bitmask array size for output side - unsigned int m_out_bm_count; - // bitmask array size for input side - unsigned int m_inp_bm_count; - //Input port Populated - OMX_BOOL m_inp_bPopulated; - //Output port Populated - OMX_BOOL m_out_bPopulated; - // encapsulate the waiting states. - unsigned int m_flags; - -#ifdef _ANDROID_ - // Heap pointer to frame buffers - struct vidc_heap - { - sp video_heap_ptr; - }; - struct vidc_heap *m_heap_ptr; - unsigned int m_heap_count; -#endif //_ANDROID_ - // store I/P PORT state - OMX_BOOL m_inp_bEnabled; - // store O/P PORT state - OMX_BOOL m_out_bEnabled; - OMX_U32 m_in_alloc_cnt; - OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE]; - // Platform specific details - OMX_QCOM_PLATFORM_PRIVATE_LIST *m_platform_list; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *m_platform_entry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *m_pmem_info; - // SPS+PPS sent as part of set_config - OMX_VENDOR_EXTRADATATYPE m_vendor_config; - - /*Variables for arbitrary Byte parsing support*/ - frame_parse m_frame_parser; - omx_cmd_queue m_input_pending_q; - omx_cmd_queue m_input_free_q; - bool arbitrary_bytes; - OMX_BUFFERHEADERTYPE h264_scratch; - OMX_BUFFERHEADERTYPE *psource_frame; - OMX_BUFFERHEADERTYPE *pdest_frame; - OMX_BUFFERHEADERTYPE *m_inp_heap_ptr; - OMX_BUFFERHEADERTYPE **m_phdr_pmem_ptr; - unsigned int m_heap_inp_bm_count; - codec_type codec_type_parse; - bool first_frame_meta; - unsigned frame_count; - unsigned nal_count; - unsigned nal_length; - bool look_ahead_nal; - int first_frame; - unsigned char *first_buffer; - int first_frame_size; - unsigned char m_hwdevice_name[80]; - FILE *m_device_file_ptr; - enum vc1_profile_type m_vc1_profile; - OMX_S64 h264_last_au_ts; - OMX_U32 h264_last_au_flags; - OMX_U32 m_demux_offsets[8192]; - OMX_U32 m_demux_entries; - OMX_U32 m_disp_hor_size; - OMX_U32 m_disp_vert_size; - - OMX_S64 prev_ts; - bool rst_prev_ts; - OMX_U32 frm_int; - - struct vdec_allocatorproperty op_buf_rcnfg; - bool in_reconfig; - OMX_NATIVE_WINDOWTYPE m_display_id; - h264_stream_parser *h264_parser; - OMX_U32 client_extradata; -#ifdef _ANDROID_ - bool m_debug_timestamp; - bool perf_flag; - OMX_U32 proc_frms, latency; - perf_metrics fps_metrics; - perf_metrics dec_time; - bool m_enable_android_native_buffers; - bool m_use_android_native_buffers; - bool m_debug_extradata; - bool m_debug_concealedmb; -#endif -#ifdef MAX_RES_1080P - MP4_Utils mp4_headerparser; -#endif - - struct h264_mv_buffer{ - unsigned char* buffer; - int size; - int count; - int pmem_fd; - int offset; - }; - h264_mv_buffer h264_mv_buff; - - struct meta_buffer{ - unsigned char* buffer; - int size; - int count; - int pmem_fd; - int pmem_fd_iommu; - int offset; - }; - meta_buffer meta_buff; - extra_data_handler extra_data_handle; -#ifdef _ANDROID_ - DivXDrmDecrypt* iDivXDrmDecrypt; -#endif //_ANDROID_ - OMX_PARAM_PORTDEFINITIONTYPE m_port_def; - omx_time_stamp_reorder time_stamp_dts; - desc_buffer_hdr *m_desc_buffer_ptr; - bool secure_mode; - bool external_meta_buffer; - bool external_meta_buffer_iommu; - OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata; - bool codec_config_flag; -#ifdef _MSM8974_ - int capture_capability; - int output_capability; - bool streaming[MAX_PORT]; - OMX_CONFIG_RECTTYPE rectangle; - int prev_n_filled_len; -#endif - bool m_power_hinted; - OMX_ERRORTYPE power_module_register(); - OMX_ERRORTYPE power_module_deregister(); - bool msg_thread_created; - bool async_thread_created; - - OMX_VIDEO_PARAM_PROFILELEVELTYPE m_profile_lvl; - unsigned int m_fill_output_msg; - bool client_set_fps; - class allocate_color_convert_buf { - public: - allocate_color_convert_buf(); - ~allocate_color_convert_buf(); - void set_vdec_client(void *); - void update_client(); - bool set_color_format(OMX_COLOR_FORMATTYPE dest_color_format); - bool get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format); - bool update_buffer_req(); - bool get_buffer_req(unsigned int &buffer_size); - OMX_BUFFERHEADERTYPE* get_il_buf_hdr(); - OMX_BUFFERHEADERTYPE* get_il_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); - OMX_BUFFERHEADERTYPE* get_dr_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); - OMX_BUFFERHEADERTYPE* convert(OMX_BUFFERHEADERTYPE *header); - OMX_BUFFERHEADERTYPE* queue_buffer(OMX_BUFFERHEADERTYPE *header); - OMX_ERRORTYPE allocate_buffers_color_convert(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData, - OMX_U32 bytes); - OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - private: - #define MAX_COUNT 32 - omx_vdec *omx; - bool enabled; - OMX_COLOR_FORMATTYPE ColorFormat; - void init_members(); - bool color_convert_mode; - ColorConvertFormat dest_format; - class omx_c2d_conv c2d; - unsigned int allocated_count; - unsigned int buffer_size_req; - unsigned int buffer_alignment_req; - OMX_QCOM_PLATFORM_PRIVATE_LIST m_platform_list_client[MAX_COUNT]; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY m_platform_entry_client[MAX_COUNT]; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO m_pmem_info_client[MAX_COUNT]; - OMX_BUFFERHEADERTYPE m_out_mem_ptr_client[MAX_COUNT]; -#ifdef USE_ION - struct vdec_ion op_buf_ion_info[MAX_COUNT]; -#endif - unsigned char *pmem_baseaddress[MAX_COUNT]; - int pmem_fd[MAX_COUNT]; - struct vidc_heap - { - sp video_heap_ptr; - }; - struct vidc_heap m_heap_ptr[MAX_COUNT]; - }; -#if defined (_MSM8960_) || defined (_MSM8974_) - allocate_color_convert_buf client_buffers; -#endif - struct video_decoder_capability m_decoder_capability; -}; - -#ifdef _MSM8974_ -enum instance_state { - MSM_VIDC_CORE_UNINIT_DONE = 0x0001, - MSM_VIDC_CORE_INIT, - MSM_VIDC_CORE_INIT_DONE, - MSM_VIDC_OPEN, - MSM_VIDC_OPEN_DONE, - MSM_VIDC_LOAD_RESOURCES, - MSM_VIDC_LOAD_RESOURCES_DONE, - MSM_VIDC_START, - MSM_VIDC_START_DONE, - MSM_VIDC_STOP, - MSM_VIDC_STOP_DONE, - MSM_VIDC_RELEASE_RESOURCES, - MSM_VIDC_RELEASE_RESOURCES_DONE, - MSM_VIDC_CLOSE, - MSM_VIDC_CLOSE_DONE, - MSM_VIDC_CORE_UNINIT, -}; - -enum vidc_resposes_id { - MSM_VIDC_DECODER_FLUSH_DONE = 0x11, - MSM_VIDC_DECODER_EVENT_CHANGE, -}; - -#endif // _MSM8974_ - -#endif // __OMX_VDEC_H__ diff --git a/mm-video/vidc/vdec/inc/omx_vdec_hevc.h b/mm-video/vidc/vdec/inc/omx_vdec_hevc.h deleted file mode 100644 index 43603583..00000000 --- a/mm-video/vidc/vdec/inc/omx_vdec_hevc.h +++ /dev/null @@ -1,961 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2013, The Linux Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef __OMX_VDEC_HEVC_H__ -#define __OMX_VDEC_HEVC_H__ -/*============================================================================ - O p e n M A X Component - Video Decoder - -*//** @file comx_vdec_hevc.h - This module contains the class definition for openMAX decoder component. - -*//*========================================================================*/ - -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include - -static ptrdiff_t x; - -#ifdef _ANDROID_ -#ifdef MAX_RES_720P -#define LOG_TAG "OMX-VDEC-720P" -#elif MAX_RES_1080P -#define LOG_TAG "OMX-VDEC-1080P" -#else -#define LOG_TAG "OMX-VDEC" -#endif - -#ifdef USE_ION -#include -#endif -#include -#include -extern "C"{ -#include -} -#include -#include -#include "hevc_utils.h" -#define TIMEOUT 5000 - -#else //_ANDROID_ -#define DEBUG_PRINT_LOW printf -#define DEBUG_PRINT_HIGH printf -#define DEBUG_PRINT_ERROR printf -#endif // _ANDROID_ - - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -#include -#endif - -#include - -#if defined (_ANDROID_ICS_) -#include -#endif - -#include -#ifndef PC_DEBUG -#include -#endif -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "qc_omx_component.h" -#include -#include -#include "frameparser.h" -#ifdef MAX_RES_1080P -#include "mp4_utils.h" -#endif -#include -#include "extra_data_handler.h" -#include "ts_parser.h" -#include "vidc_color_converter.h" -extern "C" { - OMX_API void * get_omx_component_factory_fn(void); -} - -#ifdef _ANDROID_ - using namespace android; -#ifdef USE_ION - class VideoHeap : public MemoryHeapBase - { - public: - VideoHeap(int devicefd, size_t size, void* base,struct ion_handle *handle,int mapfd); - virtual ~VideoHeap() {} - private: - int m_ion_device_fd; - struct ion_handle *m_ion_handle; - }; -#else - // local pmem heap object - class VideoHeap : public MemoryHeapBase - { - public: - VideoHeap(int fd, size_t size, void* base); - virtual ~VideoHeap() {} - }; -#endif -#endif // _ANDROID_ -////////////////////////////////////////////////////////////////////////////// -// Module specific globals -////////////////////////////////////////////////////////////////////////////// -#define OMX_SPEC_VERSION 0x00000101 - - -////////////////////////////////////////////////////////////////////////////// -// Macros -////////////////////////////////////////////////////////////////////////////// -#define PrintFrameHdr(bufHdr) DEBUG_PRINT("bufHdr %x buf %x size %d TS %d\n",\ - (unsigned) bufHdr,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp) - -// BitMask Management logic -#define BITS_PER_BYTE 32 -#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE) -#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE) -#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE)) -#define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ - &= ~(BITMASK_FLAG(mIndex)) -#define BITMASK_SET(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ - |= BITMASK_FLAG(mIndex) -#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) -#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) == 0x0) -#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) -#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) == 0x0) - -#define OMX_CORE_CONTROL_CMDQ_SIZE 100 -#define OMX_CORE_QCIF_HEIGHT 144 -#define OMX_CORE_QCIF_WIDTH 176 -#define OMX_CORE_VGA_HEIGHT 480 -#define OMX_CORE_VGA_WIDTH 640 -#define OMX_CORE_WVGA_HEIGHT 480 -#define OMX_CORE_WVGA_WIDTH 800 - -#define DESC_BUFFER_SIZE (8192 * 16) - -#ifdef _ANDROID_ -#define MAX_NUM_INPUT_OUTPUT_BUFFERS 32 -#endif - -#define OMX_FRAMEINFO_EXTRADATA 0x00010000 -#define OMX_INTERLACE_EXTRADATA 0x00020000 -#define OMX_TIMEINFO_EXTRADATA 0x00040000 -#define OMX_PORTDEF_EXTRADATA 0x00080000 -#define OMX_EXTNUSER_EXTRADATA 0x00100000 -#define DRIVER_EXTRADATA_MASK 0x0000FFFF - -#define OMX_INTERLACE_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ - sizeof(OMX_STREAMINTERLACEFORMAT) + 3)&(~3)) -#define OMX_FRAMEINFO_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ - sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO) + 3)&(~3)) -#define OMX_PORTDEF_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\ - sizeof(OMX_PARAM_PORTDEFINITIONTYPE) + 3)&(~3)) - -// Define next macro with required values to enable default extradata, -// VDEC_EXTRADATA_MB_ERROR_MAP -// OMX_INTERLACE_EXTRADATA -// OMX_FRAMEINFO_EXTRADATA -// OMX_TIMEINFO_EXTRADATA - -//#define DEFAULT_EXTRADATA (OMX_FRAMEINFO_EXTRADATA|OMX_INTERLACE_EXTRADATA) - -enum port_indexes -{ - OMX_CORE_INPUT_PORT_INDEX =0, - OMX_CORE_OUTPUT_PORT_INDEX =1 -}; -#ifdef USE_ION -struct vdec_ion -{ - int ion_device_fd; - struct ion_fd_data fd_ion_data; - struct ion_allocation_data ion_alloc_data; -}; -#endif - -#ifdef _MSM8974_ -struct extradata_buffer_info { - int buffer_size; - char* uaddr; - int count; - int size; -#ifdef USE_ION - struct vdec_ion ion; -#endif -}; -#endif - -struct video_driver_context -{ - int video_driver_fd; - enum vdec_codec decoder_format; - enum vdec_output_fromat output_format; - enum vdec_interlaced_format interlace; - enum vdec_output_order picture_order; - struct vdec_picsize video_resolution; - struct vdec_allocatorproperty ip_buf; - struct vdec_allocatorproperty op_buf; - struct vdec_bufferpayload *ptr_inputbuffer; - struct vdec_bufferpayload *ptr_outputbuffer; - struct vdec_output_frameinfo *ptr_respbuffer; -#ifdef USE_ION - struct vdec_ion *ip_buf_ion_info; - struct vdec_ion *op_buf_ion_info; - struct vdec_ion h264_mv; - struct vdec_ion meta_buffer; - struct vdec_ion meta_buffer_iommu; -#endif - struct vdec_framerate frame_rate; - unsigned extradata; - bool timestamp_adjust; - char kind[128]; - bool idr_only_decoding; - unsigned disable_dmx; -#ifdef _MSM8974_ - struct extradata_buffer_info extradata_info; - int num_planes; -#endif -}; - -#ifdef _ANDROID_ -class DivXDrmDecrypt; -#endif //_ANDROID_ - -// OMX video decoder class -class omx_vdec: public qc_omx_component -{ - -public: - omx_vdec(); // constructor - virtual ~omx_vdec(); // destructor - - static int async_message_process (void *context, void* message); - static void process_event_cb(void *ctxt,unsigned char id); - - OMX_ERRORTYPE allocate_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes - ); - - - OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp); - - OMX_ERRORTYPE component_init(OMX_STRING role); - - OMX_ERRORTYPE component_role_enum( - OMX_HANDLETYPE hComp, - OMX_U8 *role, - OMX_U32 index - ); - - OMX_ERRORTYPE component_tunnel_request( - OMX_HANDLETYPE hComp, - OMX_U32 port, - OMX_HANDLETYPE peerComponent, - OMX_U32 peerPort, - OMX_TUNNELSETUPTYPE *tunnelSetup - ); - - OMX_ERRORTYPE empty_this_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - - - OMX_ERRORTYPE fill_this_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - - OMX_ERRORTYPE free_buffer( - OMX_HANDLETYPE hComp, - OMX_U32 port, - OMX_BUFFERHEADERTYPE *buffer - ); - - OMX_ERRORTYPE get_component_version( - OMX_HANDLETYPE hComp, - OMX_STRING componentName, - OMX_VERSIONTYPE *componentVersion, - OMX_VERSIONTYPE *specVersion, - OMX_UUIDTYPE *componentUUID - ); - - OMX_ERRORTYPE get_config( - OMX_HANDLETYPE hComp, - OMX_INDEXTYPE configIndex, - OMX_PTR configData - ); - - OMX_ERRORTYPE get_extension_index( - OMX_HANDLETYPE hComp, - OMX_STRING paramName, - OMX_INDEXTYPE *indexType - ); - - OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE paramIndex, - OMX_PTR paramData); - - OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp, - OMX_STATETYPE *state); - - - - OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp, - OMX_COMMANDTYPE cmd, - OMX_U32 param1, - OMX_PTR cmdData); - - - OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp, - OMX_CALLBACKTYPE *callbacks, - OMX_PTR appData); - - OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE configIndex, - OMX_PTR configData); - - OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE paramIndex, - OMX_PTR paramData); - - OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8 *buffer); - - OMX_ERRORTYPE use_input_heap_buffers( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8* buffer); - - OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - void * eglImage); - void complete_pending_buffer_done_cbs(); - struct video_driver_context drv_ctx; -#ifdef _MSM8974_ - OMX_ERRORTYPE allocate_extradata(); - void free_extradata(); - void update_resolution(int width, int height); -#endif - int m_pipe_in; - int m_pipe_out; - pthread_t msg_thread_id; - pthread_t async_thread_id; - bool is_component_secure(); - -private: - // Bit Positions - enum flags_bit_positions - { - // Defer transition to IDLE - OMX_COMPONENT_IDLE_PENDING =0x1, - // Defer transition to LOADING - OMX_COMPONENT_LOADING_PENDING =0x2, - // First Buffer Pending - OMX_COMPONENT_FIRST_BUFFER_PENDING =0x3, - // Second Buffer Pending - OMX_COMPONENT_SECOND_BUFFER_PENDING =0x4, - // Defer transition to Enable - OMX_COMPONENT_INPUT_ENABLE_PENDING =0x5, - // Defer transition to Enable - OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x6, - // Defer transition to Disable - OMX_COMPONENT_INPUT_DISABLE_PENDING =0x7, - // Defer transition to Disable - OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x8, - //defer flush notification - OMX_COMPONENT_OUTPUT_FLUSH_PENDING =0x9, - OMX_COMPONENT_INPUT_FLUSH_PENDING =0xA, - OMX_COMPONENT_PAUSE_PENDING =0xB, - OMX_COMPONENT_EXECUTE_PENDING =0xC, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING =0xD, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE - }; - - // Deferred callback identifiers - enum - { - //Event Callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_EVENT = 0x1, - //Buffer Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2, - //Frame Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3, - //Buffer Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_FTB = 0x4, - //Frame Done callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_ETB = 0x5, - //Command - OMX_COMPONENT_GENERATE_COMMAND = 0x6, - //Push-Pending Buffers - OMX_COMPONENT_PUSH_PENDING_BUFS = 0x7, - // Empty Buffer Done callbacks - OMX_COMPONENT_GENERATE_EBD = 0x8, - //Flush Event Callbacks from the vdec component thread context - OMX_COMPONENT_GENERATE_EVENT_FLUSH = 0x9, - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH = 0x0A, - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH = 0x0B, - OMX_COMPONENT_GENERATE_FBD = 0xc, - OMX_COMPONENT_GENERATE_START_DONE = 0xD, - OMX_COMPONENT_GENERATE_PAUSE_DONE = 0xE, - OMX_COMPONENT_GENERATE_RESUME_DONE = 0xF, - OMX_COMPONENT_GENERATE_STOP_DONE = 0x10, - OMX_COMPONENT_GENERATE_HARDWARE_ERROR = 0x11, - OMX_COMPONENT_GENERATE_ETB_ARBITRARY = 0x12, - OMX_COMPONENT_GENERATE_PORT_RECONFIG = 0x13, - OMX_COMPONENT_GENERATE_EOS_DONE = 0x14, - OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG = 0x15, - OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED = 0x16, - }; - - enum vc1_profile_type - { - VC1_SP_MP_RCV = 1, - VC1_AP = 2 - }; - -#ifdef _MSM8974_ - enum v4l2_ports - { - CAPTURE_PORT, - OUTPUT_PORT, - MAX_PORT - }; -#endif - - struct omx_event - { - unsigned param1; - unsigned param2; - unsigned id; - }; - - struct omx_cmd_queue - { - omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE]; - unsigned m_read; - unsigned m_write; - unsigned m_size; - - omx_cmd_queue(); - ~omx_cmd_queue(); - bool insert_entry(unsigned p1, unsigned p2, unsigned id); - bool pop_entry(unsigned *p1,unsigned *p2, unsigned *id); - // get msgtype of the first ele from the queue - unsigned get_q_msg_type(); - - }; - -#ifdef _ANDROID_ - struct ts_entry - { - OMX_TICKS timestamp; - bool valid; - }; - - struct ts_arr_list - { - ts_entry m_ts_arr_list[MAX_NUM_INPUT_OUTPUT_BUFFERS]; - - ts_arr_list(); - ~ts_arr_list(); - - bool insert_ts(OMX_TICKS ts); - bool pop_min_ts(OMX_TICKS &ts); - bool reset_ts_list(); - }; -#endif - - struct desc_buffer_hdr - { - OMX_U8 *buf_addr; - OMX_U32 desc_data_size; - }; - bool allocate_done(void); - bool allocate_input_done(void); - bool allocate_output_done(void); - - OMX_ERRORTYPE free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - OMX_ERRORTYPE free_input_buffer(unsigned int bufferindex, - OMX_BUFFERHEADERTYPE *pmem_bufferHdr); - OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - void free_output_buffer_header(); - void free_input_buffer_header(); - - OMX_ERRORTYPE allocate_input_heap_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes); - - - OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes); - - OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port,OMX_PTR appData, - OMX_U32 bytes); - OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8 *buffer); -#ifdef MAX_RES_720P - OMX_ERRORTYPE get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); -#endif -#ifdef MAX_RES_1080P - OMX_ERRORTYPE get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); -#endif - - OMX_ERRORTYPE allocate_desc_buffer(OMX_U32 index); - OMX_ERRORTYPE allocate_output_headers(); - bool execute_omx_flush(OMX_U32); - bool execute_output_flush(); - bool execute_input_flush(); - OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE * buffer); - - OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE * buffer); - OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer); - - OMX_ERRORTYPE empty_this_buffer_proxy_arbitrary(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - OMX_ERRORTYPE push_input_buffer (OMX_HANDLETYPE hComp); - OMX_ERRORTYPE push_input_sc_codec (OMX_HANDLETYPE hComp); - OMX_ERRORTYPE push_input_h264 (OMX_HANDLETYPE hComp); - OMX_ERRORTYPE push_input_hevc (OMX_HANDLETYPE hComp); - OMX_ERRORTYPE push_input_vc1 (OMX_HANDLETYPE hComp); - - OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer); - bool release_done(); - - bool release_output_done(); - bool release_input_done(); - OMX_ERRORTYPE get_buffer_req(vdec_allocatorproperty *buffer_prop); - OMX_ERRORTYPE set_buffer_req(vdec_allocatorproperty *buffer_prop); - OMX_ERRORTYPE start_port_reconfig(); - OMX_ERRORTYPE update_picture_resolution(); - int stream_off(OMX_U32 port); - void adjust_timestamp(OMX_S64 &act_timestamp); - void set_frame_rate(OMX_S64 act_timestamp); - void handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr); - void handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr); - void print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra); -#ifdef _MSM8974_ - void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 interlaced_format_type); - OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool is_internal, - bool enable = true); - void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 num_conceal_mb, - OMX_U32 picture_type, - OMX_U32 frame_rate, - struct msm_vidc_panscan_window_payload *panscan_payload, - struct vdec_aspectratioinfo *aspect_ratio_info); -#else - void append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 interlaced_format_type, OMX_U32 buf_index); - OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool enable = true); -#endif - void append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 num_conceal_mb, - OMX_U32 picture_type, - OMX_S64 timestamp, - OMX_U32 frame_rate, - struct vdec_aspectratioinfo *aspect_ratio_info); - void fill_aspect_ratio_info(struct vdec_aspectratioinfo *aspect_ratio_info, - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info); - void append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra); - OMX_ERRORTYPE update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn); - void append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra); - void append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_extn); - void append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, OMX_OTHER_EXTRADATATYPE *p_user); - void insert_demux_addr_offset(OMX_U32 address_offset); - void extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr); - OMX_ERRORTYPE handle_demux_data(OMX_BUFFERHEADERTYPE *buf_hdr); - OMX_U32 count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra); - - bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, - OMX_U32 alignment); -#ifdef USE_ION - int alloc_map_ion_memory(OMX_U32 buffer_size, - OMX_U32 alignment, struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data,int flag); - void free_ion_memory(struct vdec_ion *buf_ion_info); -#endif - - - OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp, - OMX_COMMANDTYPE cmd, - OMX_U32 param1, - OMX_PTR cmdData); - bool post_event( unsigned int p1, - unsigned int p2, - unsigned int id - ); - inline int clip2(int x) - { - x = x -1; - x = x | x >> 1; - x = x | x >> 2; - x = x | x >> 4; - x = x | x >> 16; - x = x + 1; - return x; - } - -#ifdef MAX_RES_1080P - OMX_ERRORTYPE vdec_alloc_h264_mv(); - void vdec_dealloc_h264_mv(); - OMX_ERRORTYPE vdec_alloc_meta_buffers(); - void vdec_dealloc_meta_buffers(); -#endif - - inline void omx_report_error () - { - if (m_cb.EventHandler && !m_error_propogated) - { - ALOGE("\nERROR: Sending OMX_EventError to Client"); - m_error_propogated = true; - m_cb.EventHandler(&m_cmp,m_app_data, - OMX_EventError,OMX_ErrorHardware,0,NULL); - } - } -#ifdef _ANDROID_ - OMX_ERRORTYPE createDivxDrmContext(); -#endif //_ANDROID_ -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - OMX_ERRORTYPE use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data); -#endif -#if defined (_ANDROID_ICS_) - struct nativebuffer{ - native_handle_t *nativehandle; - private_handle_t *privatehandle; - int inuse; - }; - nativebuffer native_buffer[MAX_NUM_INPUT_OUTPUT_BUFFERS]; -#endif - - - //************************************************************* - //*******************MEMBER VARIABLES ************************* - //************************************************************* - pthread_mutex_t m_lock; - pthread_mutex_t c_lock; - //sem to handle the minimum procesing of commands - sem_t m_cmd_lock; - bool m_error_propogated; - // compression format - OMX_VIDEO_CODINGTYPE eCompressionFormat; - // OMX State - OMX_STATETYPE m_state; - // Application data - OMX_PTR m_app_data; - // Application callbacks - OMX_CALLBACKTYPE m_cb; - OMX_PRIORITYMGMTTYPE m_priority_mgm ; - OMX_PARAM_BUFFERSUPPLIERTYPE m_buffer_supplier; - // fill this buffer queue - omx_cmd_queue m_ftb_q; - // Command Q for rest of the events - omx_cmd_queue m_cmd_q; - omx_cmd_queue m_etb_q; - // Input memory pointer - OMX_BUFFERHEADERTYPE *m_inp_mem_ptr; - // Output memory pointer - OMX_BUFFERHEADERTYPE *m_out_mem_ptr; - // number of input bitstream error frame count - unsigned int m_inp_err_count; -#ifdef _ANDROID_ - // Timestamp list - ts_arr_list m_timestamp_list; -#endif - - bool input_flush_progress; - bool output_flush_progress; - bool input_use_buffer; - bool output_use_buffer; - bool ouput_egl_buffers; - OMX_BOOL m_use_output_pmem; - OMX_BOOL m_out_mem_region_smi; - OMX_BOOL m_out_pvt_entry_pmem; - - int pending_input_buffers; - int pending_output_buffers; - // bitmask array size for output side - unsigned int m_out_bm_count; - // bitmask array size for input side - unsigned int m_inp_bm_count; - //Input port Populated - OMX_BOOL m_inp_bPopulated; - //Output port Populated - OMX_BOOL m_out_bPopulated; - // encapsulate the waiting states. - unsigned int m_flags; - -#ifdef _ANDROID_ - // Heap pointer to frame buffers - struct vidc_heap - { - sp video_heap_ptr; - }; - struct vidc_heap *m_heap_ptr; - unsigned int m_heap_count; -#endif //_ANDROID_ - // store I/P PORT state - OMX_BOOL m_inp_bEnabled; - // store O/P PORT state - OMX_BOOL m_out_bEnabled; - OMX_U32 m_in_alloc_cnt; - OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE]; - // Platform specific details - OMX_QCOM_PLATFORM_PRIVATE_LIST *m_platform_list; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *m_platform_entry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *m_pmem_info; - // SPS+PPS sent as part of set_config - OMX_VENDOR_EXTRADATATYPE m_vendor_config; - - /*Variables for arbitrary Byte parsing support*/ - frame_parse m_frame_parser; - omx_cmd_queue m_input_pending_q; - omx_cmd_queue m_input_free_q; - bool arbitrary_bytes; - OMX_BUFFERHEADERTYPE h264_scratch; - OMX_BUFFERHEADERTYPE *psource_frame; - OMX_BUFFERHEADERTYPE *pdest_frame; - OMX_BUFFERHEADERTYPE *m_inp_heap_ptr; - OMX_BUFFERHEADERTYPE **m_phdr_pmem_ptr; - unsigned int m_heap_inp_bm_count; - codec_type codec_type_parse; - bool first_frame_meta; - unsigned frame_count; - unsigned nal_count; - unsigned nal_length; - bool look_ahead_nal; - int first_frame; - unsigned char *first_buffer; - int first_frame_size; - unsigned char m_hwdevice_name[80]; - FILE *m_device_file_ptr; - enum vc1_profile_type m_vc1_profile; - OMX_S64 h264_last_au_ts; - OMX_U32 h264_last_au_flags; - OMX_U32 m_demux_offsets[8192]; - OMX_U32 m_demux_entries; - OMX_U32 m_disp_hor_size; - OMX_U32 m_disp_vert_size; - - OMX_S64 prev_ts; - bool rst_prev_ts; - OMX_U32 frm_int; - - struct vdec_allocatorproperty op_buf_rcnfg; - bool in_reconfig; - OMX_NATIVE_WINDOWTYPE m_display_id; - h264_stream_parser *h264_parser; - OMX_U32 client_extradata; -#ifdef _ANDROID_ - bool m_debug_timestamp; - bool perf_flag; - OMX_U32 proc_frms, latency; - perf_metrics fps_metrics; - perf_metrics dec_time; - bool m_enable_android_native_buffers; - bool m_use_android_native_buffers; - bool m_debug_extradata; - bool m_debug_concealedmb; -#endif -#ifdef MAX_RES_1080P - MP4_Utils mp4_headerparser; -#endif - - struct h264_mv_buffer{ - unsigned char* buffer; - int size; - int count; - int pmem_fd; - int offset; - }; - h264_mv_buffer h264_mv_buff; - - struct meta_buffer{ - unsigned char* buffer; - int size; - int count; - int pmem_fd; - int pmem_fd_iommu; - int offset; - }; - meta_buffer meta_buff; - extra_data_handler extra_data_handle; -#ifdef _ANDROID_ - DivXDrmDecrypt* iDivXDrmDecrypt; -#endif //_ANDROID_ - OMX_PARAM_PORTDEFINITIONTYPE m_port_def; - omx_time_stamp_reorder time_stamp_dts; - desc_buffer_hdr *m_desc_buffer_ptr; - bool secure_mode; - bool external_meta_buffer; - bool external_meta_buffer_iommu; - OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata; - bool codec_config_flag; -#ifdef _MSM8974_ - int capture_capability; - int output_capability; - bool streaming[MAX_PORT]; - OMX_CONFIG_RECTTYPE rectangle; -#endif - bool m_power_hinted; - OMX_ERRORTYPE power_module_register(); - OMX_ERRORTYPE power_module_deregister(); - bool msg_thread_created; - bool async_thread_created; - - unsigned int m_fill_output_msg; - class allocate_color_convert_buf { - public: - allocate_color_convert_buf(); - ~allocate_color_convert_buf(); - void set_vdec_client(void *); - void update_client(); - bool set_color_format(OMX_COLOR_FORMATTYPE dest_color_format); - bool get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format); - bool update_buffer_req(); - bool get_buffer_req(unsigned int &buffer_size); - OMX_BUFFERHEADERTYPE* get_il_buf_hdr(); - OMX_BUFFERHEADERTYPE* get_il_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); - OMX_BUFFERHEADERTYPE* get_dr_buf_hdr(OMX_BUFFERHEADERTYPE *input_hdr); - OMX_BUFFERHEADERTYPE* convert(OMX_BUFFERHEADERTYPE *header); - OMX_BUFFERHEADERTYPE* queue_buffer(OMX_BUFFERHEADERTYPE *header); - OMX_ERRORTYPE allocate_buffers_color_convert(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData, - OMX_U32 bytes); - OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - private: - #define MAX_COUNT 32 - omx_vdec *omx; - bool enabled; - OMX_COLOR_FORMATTYPE ColorFormat; - void init_members(); - bool color_convert_mode; - ColorConvertFormat dest_format; - class omx_c2d_conv c2d; - unsigned int allocated_count; - unsigned int buffer_size_req; - unsigned int buffer_alignment_req; - OMX_QCOM_PLATFORM_PRIVATE_LIST m_platform_list_client[MAX_COUNT]; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY m_platform_entry_client[MAX_COUNT]; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO m_pmem_info_client[MAX_COUNT]; - OMX_BUFFERHEADERTYPE m_out_mem_ptr_client[MAX_COUNT]; -#ifdef USE_ION - struct vdec_ion op_buf_ion_info[MAX_COUNT]; -#endif - unsigned char *pmem_baseaddress[MAX_COUNT]; - int pmem_fd[MAX_COUNT]; - struct vidc_heap - { - sp video_heap_ptr; - }; - struct vidc_heap m_heap_ptr[MAX_COUNT]; - }; -#if defined (_MSM8960_) || defined (_MSM8974_) - allocate_color_convert_buf client_buffers; -#endif - HEVC_Utils mHEVCutils; -}; - -#ifdef _MSM8974_ -enum instance_state { - MSM_VIDC_CORE_UNINIT_DONE = 0x0001, - MSM_VIDC_CORE_INIT, - MSM_VIDC_CORE_INIT_DONE, - MSM_VIDC_OPEN, - MSM_VIDC_OPEN_DONE, - MSM_VIDC_LOAD_RESOURCES, - MSM_VIDC_LOAD_RESOURCES_DONE, - MSM_VIDC_START, - MSM_VIDC_START_DONE, - MSM_VIDC_STOP, - MSM_VIDC_STOP_DONE, - MSM_VIDC_RELEASE_RESOURCES, - MSM_VIDC_RELEASE_RESOURCES_DONE, - MSM_VIDC_CLOSE, - MSM_VIDC_CLOSE_DONE, - MSM_VIDC_CORE_UNINIT, -}; - -enum vidc_resposes_id { - MSM_VIDC_DECODER_FLUSH_DONE = 0x11, - MSM_VIDC_DECODER_EVENT_CHANGE, -}; - -#endif // _MSM8974_ - -#endif // __OMX_VDEC_H__ diff --git a/mm-video/vidc/vdec/inc/power_module.h b/mm-video/vidc/vdec/inc/power_module.h deleted file mode 100644 index 59586a12..00000000 --- a/mm-video/vidc/vdec/inc/power_module.h +++ /dev/null @@ -1,42 +0,0 @@ -/*------------------------------------------------------------------------- -Copyright (c) 2012, The Linux Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#include - -class PowerModule -{ - public: - static PowerModule *getInstance(); - power_module_t *getPowerModuleHandle(); - private: - static PowerModule *mPowerModuleInstance; - power_module_t *mPowerModuleHandle; - PowerModule() {} -}; diff --git a/mm-video/vidc/vdec/inc/qtypes.h b/mm-video/vidc/vdec/inc/qtypes.h deleted file mode 100755 index 63126af7..00000000 --- a/mm-video/vidc/vdec/inc/qtypes.h +++ /dev/null @@ -1,90 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef QTYPES_H -#define QTYPES_H -/*=========================================================================== - - Data Declarations - -===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ------------------------------------------------------------------------ -** Constants -** ------------------------------------------------------------------------ */ - -#ifdef TRUE -#undef TRUE -#endif - -#ifdef FALSE -#undef FALSE -#endif - -#define TRUE 1 /* Boolean true value. */ -#define FALSE 0 /* Boolean false value. */ - - - -/* ----------------------------------------------------------------------- -** Standard Types -** ----------------------------------------------------------------------- */ - -/* The following definitions are the same accross platforms. This first -** group are the sanctioned types. -*/ - -typedef unsigned char boolean; /* Boolean value type. */ - -typedef unsigned int uint32; /* Unsigned 32 bit value */ -typedef unsigned short uint16; /* Unsigned 16 bit value */ -typedef unsigned char uint8; /* Unsigned 8 bit value */ - -typedef int int32; /* Signed 32 bit value */ -typedef signed short int16; /* Signed 16 bit value */ -typedef signed char int8; /* Signed 8 bit value */ - -/* This group are the deprecated types. Their use should be -** discontinued and new code should use the types above -*/ -typedef unsigned char byte; /* Unsigned 8 bit value type. */ -typedef unsigned short word; /* Unsinged 16 bit value type. */ -typedef unsigned long dword; /* Unsigned 32 bit value type. */ - -typedef long long int64; -typedef unsigned long long uint64; - - -#ifdef __cplusplus -} -#endif - -#endif /* QTYPES_H */ diff --git a/mm-video/vidc/vdec/inc/queue.h b/mm-video/vidc/vdec/inc/queue.h deleted file mode 100755 index f22e43c1..00000000 --- a/mm-video/vidc/vdec/inc/queue.h +++ /dev/null @@ -1,39 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef QUEUE_H -#define QUEUE_H - -typedef struct Queue Queue; - -Queue *alloc_queue(); -void free_queue(Queue *q); -void free_queue_and_qelement(Queue *q); -int push(Queue *q, void * element); -void *pop(Queue *q); - -#endif diff --git a/mm-video/vidc/vdec/inc/ts_parser.h b/mm-video/vidc/vdec/inc/ts_parser.h deleted file mode 100755 index 8e884c77..00000000 --- a/mm-video/vidc/vdec/inc/ts_parser.h +++ /dev/null @@ -1,88 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef __DTSPARSER_H -#define __DTSPARSER_H - -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "qc_omx_component.h" - -#include - -#include -#include - -#ifdef _ANDROID_ -extern "C"{ -#include -} -#else -#define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args) -#endif /* _ANDROID_ */ - -class omx_time_stamp_reorder { -public: - omx_time_stamp_reorder(); - ~omx_time_stamp_reorder(); - void set_timestamp_reorder_mode(bool flag); - void enable_debug_print(bool flag); - bool insert_timestamp(OMX_BUFFERHEADERTYPE *header); - bool get_next_timestamp(OMX_BUFFERHEADERTYPE *header, bool is_interlaced); - bool remove_time_stamp(OMX_TICKS ts, bool is_interlaced); - void flush_timestamp(); - -private: - #define TIME_SZ 64 - typedef struct timestamp { - OMX_TICKS timestamps; - bool in_use; - }timestamp; - typedef struct time_stamp_list { - timestamp input_timestamps[TIME_SZ]; - time_stamp_list *next; - time_stamp_list *prev; - unsigned int entries_filled; - }time_stamp_list; - bool error; - time_stamp_list *phead,*pcurrent; - bool get_current_list(); - bool add_new_list(); - bool update_head(); - void delete_list(); - void handle_error() - { - ALOGE("Error handler called for TS Parser"); - if (error) - return; - error = true; - delete_list(); - } - bool reorder_ts; - bool print_debug; -}; -#endif diff --git a/mm-video/vidc/vdec/src/frameparser.cpp b/mm-video/vidc/vdec/src/frameparser.cpp deleted file mode 100755 index c591f5fd..00000000 --- a/mm-video/vidc/vdec/src/frameparser.cpp +++ /dev/null @@ -1,688 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "frameparser.h" -//#include "omx_vdec.h" - -#ifdef _ANDROID_ - extern "C"{ - #include - } -#endif//_ANDROID_ - -#undef DEBUG_PRINT_LOW -#undef DEBUG_PRINT_HIGH -#undef DEBUG_PRINT_ERROR - -#define DEBUG_PRINT_LOW ALOGV -#define DEBUG_PRINT_HIGH ALOGV -#define DEBUG_PRINT_ERROR ALOGE - -static unsigned char H264_mask_code[4] = {0xFF,0xFF,0xFF,0xFF}; -static unsigned char H264_start_code[4] = {0x00,0x00,0x00,0x01}; - -static unsigned char MPEG4_start_code[4] = {0x00,0x00,0x01,0xB6}; -static unsigned char MPEG4_mask_code[4] = {0xFF,0xFF,0xFF,0xFF}; - -static unsigned char H263_start_code[4] = {0x00,0x00,0x80,0x00}; -static unsigned char H263_mask_code[4] = {0xFF,0xFF,0xFC,0x00}; - -static unsigned char VC1_AP_start_code[4] = {0x00,0x00,0x01,0x0C}; -static unsigned char VC1_AP_mask_code[4] = {0xFF,0xFF,0xFF,0xFC}; - -static unsigned char MPEG2_start_code[4] = {0x00, 0x00, 0x01, 0x00}; -static unsigned char MPEG2_mask_code[4] = {0xFF, 0xFF, 0xFF, 0xFF}; - -frame_parse::frame_parse():mutils(NULL), - parse_state(A0), - start_code(NULL), - mask_code(NULL), - last_byte_h263(0), - last_byte(0), - header_found(false), - skip_frame_boundary(false), - state_nal(NAL_LENGTH_ACC), - nal_length(0), - accum_length(0), - bytes_tobeparsed(0) -{ -} - -frame_parse::~frame_parse () -{ - if (mutils) - delete mutils; - - mutils = NULL; -} - -int frame_parse::init_start_codes (codec_type codec_type_parse) -{ - /*Check if Codec Type is proper and we are in proper state*/ - if (codec_type_parse > CODEC_TYPE_MAX || parse_state != A0) - { - return -1; - } - - switch (codec_type_parse) - { - case CODEC_TYPE_MPEG4: - start_code = MPEG4_start_code; - mask_code = MPEG4_mask_code; - break; - case CODEC_TYPE_H263: - start_code = H263_start_code; - mask_code = H263_mask_code; - break; - case CODEC_TYPE_H264: - case CODEC_TYPE_HEVC: - start_code = H264_start_code; - mask_code = H264_mask_code; - break; - case CODEC_TYPE_VC1: - start_code = VC1_AP_start_code; - mask_code = VC1_AP_mask_code; - break; - case CODEC_TYPE_MPEG2: - start_code = MPEG2_start_code; - mask_code = MPEG2_mask_code; - break; -#ifdef _MSM8974_ - case CODEC_TYPE_VP8: - break; -#endif - default: - return -1; - } - return 1; -} - - -int frame_parse::init_nal_length (unsigned int nal_len) -{ - if (nal_len == 0 || nal_len > 4 || state_nal != NAL_LENGTH_ACC) - { - return -1; - } - nal_length = nal_len; - - return 1; -} - -int frame_parse::parse_sc_frame ( OMX_BUFFERHEADERTYPE *source, - OMX_BUFFERHEADERTYPE *dest , - OMX_U32 *partialframe) -{ - OMX_U8 *pdest = NULL,*psource = NULL, match_found = FALSE, is_byte_match = 0; - OMX_U32 dest_len =0, source_len = 0, temp_len = 0; - OMX_U32 parsed_length = 0,i=0; - int residue_byte = 0; - - if (source == NULL || dest == NULL || partialframe == NULL) - { - return -1; - } - - /*Calculate how many bytes are left in source and destination*/ - dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); - psource = source->pBuffer + source->nOffset; - pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); - source_len = source->nFilledLen; - - /*Need Minimum Start Code size for destination to copy atleast Start code*/ - if ((start_code == H263_start_code && dest_len < 3) || - (start_code != H263_start_code && dest_len < 4) || (source_len == 0)) - { - DEBUG_PRINT_LOW("\n FrameParser: dest_len %d source_len %d",dest_len,source_len); - if (source_len == 0 && (source->nFlags & 0x01)) - { - DEBUG_PRINT_LOW("\n FrameParser: EOS rxd!! Notify it as a complete frame"); - *partialframe = 0; - return 1; - } - DEBUG_PRINT_LOW("\n FrameParser: Bitstream Parsing error"); - return -1; - } - - /*Check if State of the previous find is a Start code*/ - if (parse_state == A4 || parse_state == A5) - { - /*Check for minimun size should be 4*/ - dest->nFlags = source->nFlags; - dest->nTimeStamp = source->nTimeStamp; - - if(start_code == H263_start_code) - { - memcpy (pdest,start_code,2); - pdest[2] = last_byte_h263; - dest->nFilledLen += 3; - pdest += 3; - } - else - { - memcpy (pdest,start_code,4); - if (start_code == VC1_AP_start_code - || start_code == MPEG4_start_code - || start_code == MPEG2_start_code) - { - pdest[3] = last_byte; - update_skip_frame(); - } - dest->nFilledLen += 4; - pdest += 4; - } - parse_state = A0; - } - - /*Entry State Machine*/ - while ( source->nFilledLen > 0 && parse_state != A0 - && parse_state != A4 && parse_state != A5 && dest_len > 0 - ) - { - //printf ("\n In the Entry Loop"); - switch (parse_state) - { - case A3: - parse_additional_start_code(psource,&parsed_length); - if (parse_state == A4) { - source->nFilledLen--; - source->nOffset++; - psource++; - break; - } - /*If fourth Byte is matching then start code is found*/ - if ((*psource & mask_code [3]) == start_code [3]) - { - parse_state = A4; - last_byte = *psource; - source->nFilledLen--; - source->nOffset++; - psource++; - } - else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) - { - parse_state = A2; - memcpy (pdest,start_code,1); - pdest++; - dest->nFilledLen++; - dest_len--; - } - else if (start_code [2] == start_code [0]) - { - parse_state = A1; - memcpy (pdest,start_code,2); - pdest += 2; - dest->nFilledLen += 2; - dest_len -= 2; - } - else - { - parse_state = A0; - memcpy (pdest,start_code,3); - pdest += 3; - dest->nFilledLen +=3; - dest_len -= 3; - } - break; - - case A2: - is_byte_match = ((*psource & mask_code [2]) == start_code [2]); - match_found = FALSE; - - if (start_code == H263_start_code) - { - if (is_byte_match) - { - last_byte_h263 = *psource; - parse_state = A5; - match_found = TRUE; - } - } - else if (start_code == H264_start_code && - (*psource & mask_code [3]) == start_code [3]) - { - parse_state = A5; - match_found = TRUE; - } - else - { - if (is_byte_match) - { - parse_state = A3; - match_found = TRUE; - } - } - - if (match_found) - { - source->nFilledLen--; - source->nOffset++; - psource++; - } - else if (start_code [1] == start_code [0]) - { - parse_state = A1; - memcpy (pdest,start_code,1); - dest->nFilledLen +=1; - dest_len--; - pdest++; - } - else - { - parse_state = A0; - memcpy (pdest,start_code,2); - dest->nFilledLen +=2; - dest_len -= 2; - pdest += 2; - } - - break; - - case A1: - if ((*psource & mask_code [1]) == start_code [1]) - { - parse_state = A2; - source->nFilledLen--; - source->nOffset++; - psource++; - } - else - { - memcpy (pdest,start_code,1); - dest->nFilledLen +=1; - pdest++; - dest_len--; - parse_state = A0; - } - break; - case A4: - case A0: - case A5: - break; - } - dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); - } - - if (parse_state == A4 || parse_state == A5) - { - *partialframe = 0; - check_skip_frame_boundary(partialframe); - DEBUG_PRINT_LOW("\n FrameParser: Parsed Len = %d", dest->nFilledLen); - return 1; - } - - /*Partial Frame is true*/ - *partialframe = 1; - - /*Calculate how many bytes are left in source and destination*/ - dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); - psource = source->pBuffer + source->nOffset; - pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); - source_len = source->nFilledLen; - - temp_len = (source_len < dest_len)?source_len:dest_len; - - /*Check if entry state machine consumed source or destination*/ - if (temp_len == 0) - { - return 1; - } - - /*Parsing State Machine*/ - while (parsed_length < temp_len) - { - switch (parse_state) - { - case A0: - if ((psource [parsed_length] & mask_code [0]) == start_code[0]) - { - parse_state = A1; - } - parsed_length++; - break; - case A1: - if ((psource [parsed_length] & mask_code [1]) == start_code [1]) - { - parsed_length++; - parse_state = A2; - } - else - { - parse_state = A0; - } - break; - case A2: - is_byte_match = ((psource[parsed_length] & mask_code [2]) == start_code [2]); - match_found = FALSE; - - if (start_code == H263_start_code) - { - if (is_byte_match) - { - last_byte_h263 = psource[parsed_length]; - parse_state = A5; - match_found = TRUE; - } - } - else if (start_code == H264_start_code && - (psource[parsed_length] & mask_code [3]) == start_code [3]) - { - parse_state = A5; - match_found = TRUE; - } - else - { - if(is_byte_match) - { - parse_state = A3; - match_found = TRUE; - } - } - - if (match_found) - { - parsed_length++; - } - else if (start_code [1] == start_code [0]) - { - parse_state = A1; - } - else - { - parse_state = A0; - } - - break; - case A3: - parse_additional_start_code(psource,&parsed_length); - if (parse_state == A4) break; - - if ((psource [parsed_length] & mask_code [3]) == start_code [3]) - { - last_byte = psource [parsed_length]; - parsed_length++; - parse_state = A4; - } - else if ((start_code [1] == start_code [0]) && (start_code [2] == start_code [1])) - { - parse_state = A2; - } - else if (start_code [2] == start_code [0]) - { - parse_state = A1; - } - else - { - parse_state = A0; - } - break; - case A4: - case A5: - break; - } - - /*Found the code break*/ - if (parse_state == A4 || parse_state == A5) - { - break; - } - } - - /*Exit State Machine*/ - psource = source->pBuffer + source->nOffset; - switch (parse_state) - { - case A5: - *partialframe = 0; - check_skip_frame_boundary(partialframe); - if (parsed_length > 3) - { - memcpy (pdest,psource,(parsed_length-3)); - dest->nFilledLen += (parsed_length-3); - } - break; - case A4: - *partialframe = 0; - check_skip_frame_boundary(partialframe); - if (parsed_length > 4) - { - memcpy (pdest,psource,(parsed_length-4)); - dest->nFilledLen += (parsed_length-4); - } - break; - case A3: - if (parsed_length > 3) - { - memcpy (pdest,psource,(parsed_length-3)); - dest->nFilledLen += (parsed_length-3); - } - break; - case A2: - if (parsed_length > 2) - { - memcpy (pdest,psource,(parsed_length-2)); - dest->nFilledLen += (parsed_length-2); - } - break; - case A1: - if (parsed_length > 1) - { - memcpy (pdest,psource,(parsed_length-1)); - dest->nFilledLen += (parsed_length-1); - } - break; - case A0: - memcpy (pdest,psource,(parsed_length)); - dest->nFilledLen += (parsed_length); - break; - } - - if (source->nFilledLen < parsed_length) - { - printf ("\n FATAL Error"); - return -1; - } - source->nFilledLen -= parsed_length; - source->nOffset += parsed_length; - - return 1; -} - - -int frame_parse::parse_h264_nallength (OMX_BUFFERHEADERTYPE *source, - OMX_BUFFERHEADERTYPE *dest , - OMX_U32 *partialframe) -{ - OMX_U8 *pdest = NULL,*psource = NULL; - OMX_U32 dest_len =0, source_len = 0, temp_len = 0,parsed_length = 0; - - if (source == NULL || dest == NULL || partialframe == NULL) - { - return -1; - } - - /*Calculate the length's*/ - dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); - source_len = source->nFilledLen; - - if (dest_len < 4 || source_len == 0 || nal_length == 0) - { - DEBUG_PRINT_LOW("\n FrameParser: NAL Parsing Error! dest_len %d " - "source_len %d nal_length %d", dest_len, source_len, nal_length); - return -1; - } - *partialframe = 1; - temp_len = (source_len < dest_len)?source_len:dest_len; - psource = source->pBuffer + source->nOffset; - pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); - - /* Find the Bytes to Accumalte*/ - if (state_nal == NAL_LENGTH_ACC) - { - while (parsed_length < temp_len ) - { - bytes_tobeparsed |= (((OMX_U32)(*psource))) << (((nal_length-accum_length-1) << 3)); - - /*COPY THE DATA FOR C-SIM TO BE REOMVED ON TARGET*/ - //*pdest = *psource; - accum_length++; - source->nFilledLen--; - source->nOffset++; - psource++; - //dest->nFilledLen++; - //pdest++; - parsed_length++; - - if (accum_length == nal_length) - { - accum_length = 0; - state_nal = NAL_PARSING; - memcpy (pdest,H264_start_code,4); - dest->nFilledLen += 4; - break; - } - } - } - - dest_len = dest->nAllocLen - (dest->nFilledLen + dest->nOffset); - source_len = source->nFilledLen; - temp_len = (source_len < dest_len)?source_len:dest_len; - - psource = source->pBuffer + source->nOffset; - pdest = dest->pBuffer + (dest->nFilledLen + dest->nOffset); - - dest->nTimeStamp = source->nTimeStamp; - dest->nFlags = source->nFlags; - - /*Already in Parsing state go ahead and copy*/ - if(state_nal == NAL_PARSING && temp_len > 0) - { - if (temp_len < bytes_tobeparsed) - { - memcpy (pdest,psource,temp_len); - dest->nFilledLen += temp_len; - source->nOffset += temp_len; - source->nFilledLen -= temp_len; - bytes_tobeparsed -= temp_len; - } - else - { - memcpy (pdest,psource,bytes_tobeparsed); - temp_len -= bytes_tobeparsed; - dest->nFilledLen += bytes_tobeparsed; - source->nOffset += bytes_tobeparsed; - source->nFilledLen -= bytes_tobeparsed; - bytes_tobeparsed = 0; - } - } - - if (bytes_tobeparsed == 0 && state_nal == NAL_PARSING) - { - *partialframe = 0; - state_nal = NAL_LENGTH_ACC; - } - - return 1; -} - -void frame_parse::flush () -{ - parse_state = A0; - state_nal = NAL_LENGTH_ACC; - accum_length = 0; - bytes_tobeparsed = 0; - header_found = false; - skip_frame_boundary = false; -} - -void frame_parse::parse_additional_start_code(OMX_U8 *psource, - OMX_U32 *parsed_length) -{ - - if (((start_code == MPEG4_start_code) || - (start_code == MPEG2_start_code)) && - psource && - parsed_length) - { - OMX_U32 index = *parsed_length; - if ((start_code == MPEG4_start_code && - (psource [index] & 0xF0) == 0x20) || - (start_code == MPEG2_start_code && - psource [index] == 0xB3)) - { - if (header_found) - { - last_byte = psource [index]; - index++; - parse_state = A4; - } else - header_found = true; - } - *parsed_length = index; - } -} - -void frame_parse::check_skip_frame_boundary(OMX_U32 *partialframe) -{ - if ((start_code == MPEG4_start_code || - start_code == MPEG2_start_code) && - partialframe) { - - *partialframe = 1; - if (!skip_frame_boundary) - *partialframe = 0; - skip_frame_boundary = false; - } -} - -void frame_parse::update_skip_frame() -{ - if (((start_code == MPEG4_start_code) && - ((last_byte & 0xF0) == 0x20)) || - ((start_code == MPEG2_start_code) && - (last_byte == 0xB3))) { - - skip_frame_boundary = true; - } -} diff --git a/mm-video/vidc/vdec/src/h264_utils.cpp b/mm-video/vidc/vdec/src/h264_utils.cpp deleted file mode 100644 index 651bb6b4..00000000 --- a/mm-video/vidc/vdec/src/h264_utils.cpp +++ /dev/null @@ -1,1700 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -/*======================================================================== - - O p e n M M - V i d e o U t i l i t i e s - -*//** @file VideoUtils.cpp - This module contains utilities and helper routines. - -@par EXTERNALIZED FUNCTIONS - -@par INITIALIZATION AND SEQUENCING REQUIREMENTS - (none) - -*//*====================================================================== */ - -/* ======================================================================= - - INCLUDE FILES FOR MODULE - -========================================================================== */ -#include "h264_utils.h" -#include "extra_data_handler.h" -#include -#include -#include -#include -#ifdef _ANDROID_ -#include - extern "C"{ - #include - } - -#endif - -/* ======================================================================= - - DEFINITIONS AND DECLARATIONS FOR MODULE - -This section contains definitions for constants, macros, types, variables -and other items needed by this module. - -========================================================================== */ - -#define SIZE_NAL_FIELD_MAX 4 -#define BASELINE_PROFILE 66 -#define MAIN_PROFILE 77 -#define HIGH_PROFILE 100 - -#define MAX_SUPPORTED_LEVEL 32 - -RbspParser::RbspParser (const uint8 *_begin, const uint8 *_end) -: begin (_begin), end(_end), pos (- 1), bit (0), -cursor (0xFFFFFF), advanceNeeded (true) -{ -} - -// Destructor -/*lint -e{1540} Pointer member neither freed nor zeroed by destructor - * No problem - */ -RbspParser::~RbspParser () {} - -// Return next RBSP byte as a word -uint32 RbspParser::next () -{ - if (advanceNeeded) advance (); - //return static_cast (*pos); - return static_cast (begin[pos]); -} - -// Advance RBSP decoder to next byte -void RbspParser::advance () -{ - ++pos; - //if (pos >= stop) - if (begin + pos == end) - { - /*lint -e{730} Boolean argument to function - * I don't see a problem here - */ - //throw false; - ALOGV("H264Parser-->NEED TO THROW THE EXCEPTION...\n"); - } - cursor <<= 8; - //cursor |= static_cast (*pos); - cursor |= static_cast (begin[pos]); - if ((cursor & 0xFFFFFF) == 0x000003) - { - advance (); - } - advanceNeeded = false; -} - -// Decode unsigned integer -uint32 RbspParser::u (uint32 n) -{ - uint32 i, s, x = 0; - for (i = 0; i < n; i += s) - { - s = static_castSTD_MIN(static_cast(8 - bit), - static_cast(n - i)); - x <<= s; - - x |= ((next () >> ((8 - static_cast(bit)) - s)) & - ((1 << s) - 1)); - - bit = (bit + s) % 8; - if (!bit) - { - advanceNeeded = true; - } - } - return x; -} - -// Decode unsigned integer Exp-Golomb-coded syntax element -uint32 RbspParser::ue () -{ - int leadingZeroBits = -1; - for (uint32 b = 0; !b; ++leadingZeroBits) - { - b = u (1); - } - return ((1 << leadingZeroBits) - 1) + - u (static_cast(leadingZeroBits)); -} - -// Decode signed integer Exp-Golomb-coded syntax element -int32 RbspParser::se () -{ - const uint32 x = ue (); - if (!x) return 0; - else if (x & 1) return static_cast ((x >> 1) + 1); - else return - static_cast (x >> 1); -} - -void H264_Utils::allocate_rbsp_buffer(uint32 inputBufferSize) -{ - m_rbspBytes = (byte *) calloc(1,inputBufferSize); - m_prv_nalu.nal_ref_idc = 0; - m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED; -} - -H264_Utils::H264_Utils(): m_height(0), - m_width(0), - m_rbspBytes(NULL), - m_au_data (false) -{ - initialize_frame_checking_environment(); -} - -H264_Utils::~H264_Utils() -{ -/* if(m_pbits) - { - delete(m_pbits); - m_pbits = NULL; - } -*/ - if (m_rbspBytes) - { - free(m_rbspBytes); - m_rbspBytes = NULL; - } -} - -/***********************************************************************/ -/* -FUNCTION: - H264_Utils::initialize_frame_checking_environment - -DESCRIPTION: - Extract RBSP data from a NAL - -INPUT/OUTPUT PARAMETERS: - None - -RETURN VALUE: - boolean - -SIDE EFFECTS: - None. -*/ -/***********************************************************************/ -void H264_Utils::initialize_frame_checking_environment() -{ - m_forceToStichNextNAL = false; - m_au_data = false; - m_prv_nalu.nal_ref_idc = 0; - m_prv_nalu.nalu_type = NALU_TYPE_UNSPECIFIED; -} - -/***********************************************************************/ -/* -FUNCTION: - H264_Utils::extract_rbsp - -DESCRIPTION: - Extract RBSP data from a NAL - -INPUT/OUTPUT PARAMETERS: - - buffer : buffer containing start code or nal length + NAL units - buffer_length : the length of the NAL buffer - start_code : If true, start code is detected, - otherwise size nal length is detected - size_of_nal_length_field: size of nal length field - - - rbsp_bistream : extracted RBSP bistream - rbsp_length : the length of the RBSP bitstream - nal_unit : decoded NAL header information - -RETURN VALUE: - boolean - -SIDE EFFECTS: - None. -*/ -/***********************************************************************/ - -boolean H264_Utils::extract_rbsp(OMX_IN OMX_U8 *buffer, - OMX_IN OMX_U32 buffer_length, - OMX_IN OMX_U32 size_of_nal_length_field, - OMX_OUT OMX_U8 *rbsp_bistream, - OMX_OUT OMX_U32 *rbsp_length, - OMX_OUT NALU *nal_unit) -{ - byte coef1, coef2, coef3; - uint32 pos = 0; - uint32 nal_len = buffer_length; - uint32 sizeofNalLengthField = 0; - uint32 zero_count; - boolean eRet = true; - boolean start_code = (size_of_nal_length_field==0)?true:false; - - if(start_code) { - // Search start_code_prefix_one_3bytes (0x000001) - coef2 = buffer[pos++]; - coef3 = buffer[pos++]; - do { - if(pos >= buffer_length) - { - ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - - coef1 = coef2; - coef2 = coef3; - coef3 = buffer[pos++]; - } while(coef1 || coef2 || coef3 != 1); - } - else if (size_of_nal_length_field) - { - /* This is the case to play multiple NAL units inside each access unit*/ - /* Extract the NAL length depending on sizeOfNALength field */ - sizeofNalLengthField = size_of_nal_length_field; - nal_len = 0; - while(size_of_nal_length_field--) - { - nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3); - } - if (nal_len >= buffer_length) - { - ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - } - - if (nal_len > buffer_length) - { - ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - if(pos + 1 > (nal_len + sizeofNalLengthField)) - { - ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - if ((nal_unit->forbidden_zero_bit = (buffer[pos] & 0x80)) != 0) - { - ALOGE("ERROR: In %s() - line %d", __func__, __LINE__); - } - nal_unit->nal_ref_idc = (buffer[pos] & 0x60) >> 5; - nal_unit->nalu_type = buffer[pos++] & 0x1f; - ALOGV("\n@#@# Pos = %x NalType = %x buflen = %d", - pos-1, nal_unit->nalu_type, buffer_length); - *rbsp_length = 0; - - - if( nal_unit->nalu_type == NALU_TYPE_EOSEQ || - nal_unit->nalu_type == NALU_TYPE_EOSTREAM) - return (nal_len + sizeofNalLengthField); - - zero_count = 0; - while (pos < (nal_len+sizeofNalLengthField)) //similar to for in p-42 - { - if( zero_count == 2 ) { - if( buffer[pos] == 0x03 ) { - pos ++; - zero_count = 0; - continue; - } - if( buffer[pos] <= 0x01 ) { - if( start_code ) { - *rbsp_length -= 2; - pos -= 2; - return pos; - } - } - zero_count = 0; - } - zero_count ++; - if( buffer[pos] != 0 ) - zero_count = 0; - - rbsp_bistream[(*rbsp_length)++] = buffer[pos++]; - } - - return eRet; -} - -/*=========================================================================== -FUNCTION: - H264_Utils::iSNewFrame - -DESCRIPTION: - Returns true if NAL parsing successfull otherwise false. - -INPUT/OUTPUT PARAMETERS: - - buffer : buffer containing start code or nal length + NAL units - buffer_length : the length of the NAL buffer - start_code : If true, start code is detected, - otherwise size nal length is detected - size_of_nal_length_field: size of nal length field - - isNewFrame: true if the NAL belongs to a differenet frame - false if the NAL belongs to a current frame - -RETURN VALUE: - boolean true, if nal parsing is successful - false, if the nal parsing has errors - -SIDE EFFECTS: - None. -===========================================================================*/ -bool H264_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, - OMX_IN OMX_U32 size_of_nal_length_field, - OMX_OUT OMX_BOOL &isNewFrame) -{ - NALU nal_unit; - uint16 first_mb_in_slice = 0; - OMX_IN OMX_U32 numBytesInRBSP = 0; - OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer; - OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen; - bool eRet = true; - - ALOGV("isNewFrame: buffer %p buffer_length %d " - "size_of_nal_length_field %d\n", buffer, buffer_length, - size_of_nal_length_field); - - if ( false == extract_rbsp(buffer, buffer_length, size_of_nal_length_field, - m_rbspBytes, &numBytesInRBSP, &nal_unit) ) - { - ALOGE("ERROR: In %s() - extract_rbsp() failed", __func__); - isNewFrame = OMX_FALSE; - eRet = false; - } - else - { - nalu_type = nal_unit.nalu_type; - switch (nal_unit.nalu_type) - { - case NALU_TYPE_IDR: - case NALU_TYPE_NON_IDR: - { - ALOGV("\n AU Boundary with NAL type %d ",nal_unit.nalu_type); - if (m_forceToStichNextNAL) - { - isNewFrame = OMX_FALSE; - } - else - { - RbspParser rbsp_parser(m_rbspBytes, (m_rbspBytes+numBytesInRBSP)); - first_mb_in_slice = rbsp_parser.ue(); - - if((!first_mb_in_slice) || /*(slice.prv_frame_num != slice.frame_num ) ||*/ - ( (m_prv_nalu.nal_ref_idc != nal_unit.nal_ref_idc) && ( nal_unit.nal_ref_idc * m_prv_nalu.nal_ref_idc == 0 ) ) || - /*( ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) && (nal_unit.nalu_type == NALU_TYPE_IDR)) && (slice.idr_pic_id != slice.prv_idr_pic_id) ) || */ - ( (m_prv_nalu.nalu_type != nal_unit.nalu_type ) && ((m_prv_nalu.nalu_type == NALU_TYPE_IDR) || (nal_unit.nalu_type == NALU_TYPE_IDR)) ) ) - { - //ALOGV("Found a New Frame due to NALU_TYPE_IDR/NALU_TYPE_NON_IDR"); - isNewFrame = OMX_TRUE; - } - else - { - isNewFrame = OMX_FALSE; - } - } - m_au_data = true; - m_forceToStichNextNAL = false; - break; - } - case NALU_TYPE_SPS: - case NALU_TYPE_PPS: - case NALU_TYPE_SEI: - { - ALOGV("\n Non-AU boundary with NAL type %d", nal_unit.nalu_type); - if(m_au_data) - { - isNewFrame = OMX_TRUE; - m_au_data = false; - } - else - { - isNewFrame = OMX_FALSE; - } - - m_forceToStichNextNAL = true; - break; - } - case NALU_TYPE_ACCESS_DELIM: - case NALU_TYPE_UNSPECIFIED: - case NALU_TYPE_EOSEQ: - case NALU_TYPE_EOSTREAM: - default: - { - isNewFrame = OMX_FALSE; - // Do not update m_forceToStichNextNAL - break; - } - } // end of switch - } // end of if - m_prv_nalu = nal_unit; - ALOGV("get_h264_nal_type - newFrame value %d\n",isNewFrame); - return eRet; -} - -void perf_metrics::start() -{ - if (!active) - { - start_time = get_act_time(); - active = true; - } -} - -void perf_metrics::stop() -{ - OMX_U64 stop_time = get_act_time(); - if (active) - { - proc_time += (stop_time - start_time); - active = false; - } -} - -void perf_metrics::end(OMX_U32 units_cntr) -{ - stop(); - ALOGV("--> Processing time : [%.2f] Sec", (float)proc_time / 1e6); - if (units_cntr) - { - ALOGV("--> Avrg proc time : [%.2f] mSec", proc_time / (float)(units_cntr * 1e3)); - } -} - -void perf_metrics::reset() -{ - start_time = 0; - proc_time = 0; - active = false; -} - -OMX_U64 perf_metrics::get_act_time() -{ - struct timeval act_time = {0, 0}; - gettimeofday(&act_time, NULL); - return (act_time.tv_usec + act_time.tv_sec * 1e6); -} - -OMX_U64 perf_metrics::processing_time_us() -{ - return proc_time; -} - -h264_stream_parser::h264_stream_parser() -{ - reset(); -#ifdef PANSCAN_HDLR - panscan_hdl = new panscan_handler(); - if (!panscan_hdl) - { - ALOGE("ERROR: Panscan hdl was not allocated!"); - } - else if (!panscan_hdl->initialize(10)) - { - ALOGE("ERROR: Allocating memory for panscan!"); - delete panscan_hdl; - panscan_hdl = NULL; - } -#else - memset(&panscan_param, 0, sizeof(panscan_param)); - panscan_param.rect_id = NO_PAN_SCAN_BIT; -#endif -} - -h264_stream_parser::~h264_stream_parser() -{ -#ifdef PANSCAN_HDLR - if (panscan_hdl) - { - delete panscan_hdl; - panscan_hdl = NULL; - } -#endif -} - -void h264_stream_parser::reset() -{ - curr_32_bit = 0; - bits_read = 0; - zero_cntr = 0; - emulation_code_skip_cntr = 0; - emulation_sc_enabled = true; - bitstream = NULL; - bitstream_bytes = 0; - memset(&vui_param, 0, sizeof(vui_param)); - vui_param.fixed_fps_prev_ts = LLONG_MAX; - memset(&sei_buf_period, 0, sizeof(sei_buf_period)); - memset(&sei_pic_timing, 0, sizeof(sei_pic_timing)); - memset(&frame_packing_arrangement,0,sizeof(frame_packing_arrangement)); - frame_packing_arrangement.cancel_flag = 1; - mbaff_flag = 0; -} - -void h264_stream_parser::init_bitstream(OMX_U8* data, OMX_U32 size) -{ - bitstream = data; - bitstream_bytes = size; - curr_32_bit = 0; - bits_read = 0; - zero_cntr = 0; - emulation_code_skip_cntr = 0; -} - -void h264_stream_parser::parse_vui(bool vui_in_extradata) -{ - OMX_U32 value = 0; - ALOGV("parse_vui: IN"); - if (vui_in_extradata) - while (!extract_bits(1) && more_bits()); // Discard VUI enable flag - if (!more_bits()) - return; - - vui_param.aspect_ratio_info_present_flag = extract_bits(1); //aspect_ratio_info_present_flag - if (vui_param.aspect_ratio_info_present_flag) - { - ALOGV("Aspect Ratio Info present!"); - aspect_ratio_info(); - } - - if (extract_bits(1)) //overscan_info_present_flag - extract_bits(1); //overscan_appropriate_flag - if (extract_bits(1)) //video_signal_type_present_flag - { - extract_bits(3); //video_format - extract_bits(1); //video_full_range_flag - if (extract_bits(1)) //colour_description_present_flag - { - extract_bits(8); //colour_primaries - extract_bits(8); //transfer_characteristics - extract_bits(8); //matrix_coefficients - } - } - if (extract_bits(1)) //chroma_location_info_present_flag - { - uev(); //chroma_sample_loc_type_top_field - uev(); //chroma_sample_loc_type_bottom_field - } - vui_param.timing_info_present_flag = extract_bits(1); - if (vui_param.timing_info_present_flag) - { - vui_param.num_units_in_tick = extract_bits(32); - vui_param.time_scale = extract_bits(32); - vui_param.fixed_frame_rate_flag = extract_bits(1); - ALOGV("Timing info present in VUI!"); - ALOGV(" num units in tick : %u", vui_param.num_units_in_tick); - ALOGV(" time scale : %u", vui_param.time_scale); - ALOGV(" fixed frame rate : %u", vui_param.fixed_frame_rate_flag); - } - vui_param.nal_hrd_parameters_present_flag = extract_bits(1); - if (vui_param.nal_hrd_parameters_present_flag) - { - ALOGV("nal hrd params present!"); - hrd_parameters(&vui_param.nal_hrd_parameters); - } - vui_param.vcl_hrd_parameters_present_flag = extract_bits(1); - if (vui_param.vcl_hrd_parameters_present_flag) - { - ALOGV("vcl hrd params present!"); - hrd_parameters(&vui_param.vcl_hrd_parameters); - } - if (vui_param.nal_hrd_parameters_present_flag || - vui_param.vcl_hrd_parameters_present_flag) - vui_param.low_delay_hrd_flag = extract_bits(1); - vui_param.pic_struct_present_flag = extract_bits(1); - ALOGV("pic_struct_present_flag : %u", vui_param.pic_struct_present_flag); - if (extract_bits(1)) //bitstream_restriction_flag - { - extract_bits(1); //motion_vectors_over_pic_boundaries_flag - uev(); //max_bytes_per_pic_denom - uev(); //max_bits_per_mb_denom - uev(); //log2_max_mv_length_vertical - uev(); //log2_max_mv_length_horizontal - uev(); //num_reorder_frames - uev(); //max_dec_frame_buffering - } - ALOGV("parse_vui: OUT"); -} - -void h264_stream_parser::aspect_ratio_info() -{ - ALOGV("aspect_ratio_info: IN"); - OMX_U32 aspect_ratio_idc = 0; - OMX_U32 aspect_ratio_x = 0; - OMX_U32 aspect_ratio_y = 0; - aspect_ratio_idc = extract_bits(8); //aspect_ratio_idc - switch (aspect_ratio_idc) - { - case 1: - aspect_ratio_x = 1; - aspect_ratio_y = 1; - break; - case 2: - aspect_ratio_x = 12; - aspect_ratio_y = 11; - break; - case 3: - aspect_ratio_x = 10; - aspect_ratio_y = 11; - break; - case 4: - aspect_ratio_x = 16; - aspect_ratio_y = 11; - break; - case 5: - aspect_ratio_x = 40; - aspect_ratio_y = 33; - break; - case 6: - aspect_ratio_x = 24; - aspect_ratio_y = 11; - break; - case 7: - aspect_ratio_x = 20; - aspect_ratio_y = 11; - break; - case 8: - aspect_ratio_x = 32; - aspect_ratio_y = 11; - break; - case 9: - aspect_ratio_x = 80; - aspect_ratio_y = 33; - break; - case 10: - aspect_ratio_x = 18; - aspect_ratio_y = 11; - break; - case 11: - aspect_ratio_x = 15; - aspect_ratio_y = 11; - break; - case 12: - aspect_ratio_x = 64; - aspect_ratio_y = 33; - break; - case 13: - aspect_ratio_x = 160; - aspect_ratio_y = 99; - break; - case 14: - aspect_ratio_x = 4; - aspect_ratio_y = 3; - break; - case 15: - aspect_ratio_x = 3; - aspect_ratio_y = 2; - break; - case 16: - aspect_ratio_x = 2; - aspect_ratio_y = 1; - break; - case 255: - aspect_ratio_x = extract_bits(16); //sar_width - aspect_ratio_y = extract_bits(16); //sar_height - break; - default: - ALOGV("-->aspect_ratio_idc: Reserved Value "); - break; - } - ALOGV("-->aspect_ratio_idc : %u", aspect_ratio_idc); - ALOGV("-->aspect_ratio_x : %u", aspect_ratio_x); - ALOGV("-->aspect_ratio_y : %u", aspect_ratio_y); - vui_param.aspect_ratio_info.aspect_ratio_idc = aspect_ratio_idc; - vui_param.aspect_ratio_info.aspect_ratio_x = aspect_ratio_x; - vui_param.aspect_ratio_info.aspect_ratio_y = aspect_ratio_y; - ALOGV("aspect_ratio_info: OUT"); -} - -void h264_stream_parser::hrd_parameters(h264_hrd_param *hrd_param) -{ - OMX_U32 idx; - ALOGV("hrd_parameters: IN"); - hrd_param->cpb_cnt = uev() + 1; - hrd_param->bit_rate_scale = extract_bits(4); - hrd_param->cpb_size_scale = extract_bits(4); - ALOGV("-->cpb_cnt : %u", hrd_param->cpb_cnt); - ALOGV("-->bit_rate_scale : %u", hrd_param->bit_rate_scale); - ALOGV("-->cpb_size_scale : %u", hrd_param->cpb_size_scale); - if (hrd_param->cpb_cnt > MAX_CPB_COUNT) - { - ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt); - return; - } - for (idx = 0; idx < hrd_param->cpb_cnt && more_bits(); idx++) - { - hrd_param->bit_rate_value[idx] = uev() + 1; - hrd_param->cpb_size_value[idx] = uev() + 1; - hrd_param->cbr_flag[idx] = extract_bits(1); - ALOGV("-->bit_rate_value [%d] : %u", idx, hrd_param->bit_rate_value[idx]); - ALOGV("-->cpb_size_value [%d] : %u", idx, hrd_param->cpb_size_value[idx]); - ALOGV("-->cbr_flag [%d] : %u", idx, hrd_param->cbr_flag[idx]); - } - hrd_param->initial_cpb_removal_delay_length = extract_bits(5) + 1; - hrd_param->cpb_removal_delay_length = extract_bits(5) + 1; - hrd_param->dpb_output_delay_length = extract_bits(5) + 1; - hrd_param->time_offset_length = extract_bits(5); - ALOGV("-->initial_cpb_removal_delay_length : %u", hrd_param->initial_cpb_removal_delay_length); - ALOGV("-->cpb_removal_delay_length : %u", hrd_param->cpb_removal_delay_length); - ALOGV("-->dpb_output_delay_length : %u", hrd_param->dpb_output_delay_length); - ALOGV("-->time_offset_length : %u", hrd_param->time_offset_length); - ALOGV("hrd_parameters: OUT"); -} - -void h264_stream_parser::parse_sei() -{ - OMX_U32 value = 0, processed_bytes = 0; - OMX_U8 *sei_msg_start = bitstream; - OMX_U32 sei_unit_size = bitstream_bytes; - ALOGV("@@parse_sei: IN sei_unit_size(%u)", sei_unit_size); - while ((processed_bytes + 2) < sei_unit_size && more_bits()) - { - init_bitstream(sei_msg_start + processed_bytes, sei_unit_size - processed_bytes); - ALOGV("-->NALU_TYPE_SEI"); - OMX_U32 payload_type = 0, payload_size = 0, aux = 0; - do { - value = extract_bits(8); - payload_type += value; - processed_bytes++; - } while (value == 0xFF); - ALOGV("-->payload_type : %u", payload_type); - do { - value = extract_bits(8); - payload_size += value; - processed_bytes++; - } while (value == 0xFF); - ALOGV("-->payload_size : %u", payload_size); - if (payload_size > 0) - { - switch (payload_type) - { - case BUFFERING_PERIOD: - sei_buffering_period(); - break; - case PIC_TIMING: - sei_picture_timing(); - break; - case PAN_SCAN_RECT: - sei_pan_scan(); - break; - case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT: - parse_frame_pack(); - break; - default: - ALOGV("-->SEI payload type [%u] not implemented! size[%u]", payload_type, payload_size); - } - } - processed_bytes += (payload_size + emulation_code_skip_cntr); - ALOGV("-->SEI processed_bytes[%u]", processed_bytes); - } - ALOGV("@@parse_sei: OUT"); -} - -void h264_stream_parser::sei_buffering_period() -{ - OMX_U32 idx; - OMX_U32 value = 0; - h264_hrd_param *hrd_param = NULL; - ALOGV("@@sei_buffering_period: IN"); - value = uev(); // seq_parameter_set_id - ALOGV("-->seq_parameter_set_id : %u", value); - if (value > 31) - { - ALOGV("ERROR: Invalid seq_parameter_set_id [%u]!", value); - return; - } - sei_buf_period.is_valid = false; - if (vui_param.nal_hrd_parameters_present_flag) - { - hrd_param = &vui_param.nal_hrd_parameters; - if (hrd_param->cpb_cnt > MAX_CPB_COUNT) - { - ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt); - return; - } - for (idx = 0; idx < hrd_param->cpb_cnt ; idx++) - { - sei_buf_period.is_valid = true; - sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); - sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); - ALOGV("-->initial_cpb_removal_delay : %u", sei_buf_period.initial_cpb_removal_delay[idx]); - ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]); - } - } - if (vui_param.vcl_hrd_parameters_present_flag) - { - hrd_param = &vui_param.vcl_hrd_parameters; - if (hrd_param->cpb_cnt > MAX_CPB_COUNT) - { - ALOGV("ERROR: Invalid hrd_param->cpb_cnt [%u]!", hrd_param->cpb_cnt); - return; - } - for (idx = 0; idx < hrd_param->cpb_cnt ; idx++) - { - sei_buf_period.is_valid = true; - sei_buf_period.initial_cpb_removal_delay[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); - sei_buf_period.initial_cpb_removal_delay_offset[idx] = extract_bits(hrd_param->initial_cpb_removal_delay_length); - ALOGV("-->initial_cpb_removal_delay : %u", sei_buf_period.initial_cpb_removal_delay[idx]); - ALOGV("-->initial_cpb_removal_delay_offset : %u", sei_buf_period.initial_cpb_removal_delay_offset[idx]); - } - } - sei_buf_period.au_cntr = 0; - ALOGV("@@sei_buffering_period: OUT"); -} - -void h264_stream_parser::sei_picture_timing() -{ - ALOGV("@@sei_picture_timing: IN"); - OMX_U32 time_offset_len = 0, cpb_removal_len = 24, dpb_output_len = 24; - OMX_U8 cbr_flag = 0; - sei_pic_timing.is_valid = true; - if (vui_param.nal_hrd_parameters_present_flag) - { - cpb_removal_len = vui_param.nal_hrd_parameters.cpb_removal_delay_length; - dpb_output_len = vui_param.nal_hrd_parameters.dpb_output_delay_length; - time_offset_len = vui_param.nal_hrd_parameters.time_offset_length; - cbr_flag = vui_param.nal_hrd_parameters.cbr_flag[0]; - } - else if (vui_param.vcl_hrd_parameters_present_flag) - { - cpb_removal_len = vui_param.vcl_hrd_parameters.cpb_removal_delay_length; - dpb_output_len = vui_param.vcl_hrd_parameters.dpb_output_delay_length; - time_offset_len = vui_param.vcl_hrd_parameters.time_offset_length; - cbr_flag = vui_param.vcl_hrd_parameters.cbr_flag[0]; - } - sei_pic_timing.cpb_removal_delay = extract_bits(cpb_removal_len); - sei_pic_timing.dpb_output_delay = extract_bits(dpb_output_len); - ALOGV("-->cpb_removal_len : %u", cpb_removal_len); - ALOGV("-->dpb_output_len : %u", dpb_output_len); - ALOGV("-->cpb_removal_delay : %u", sei_pic_timing.cpb_removal_delay); - ALOGV("-->dpb_output_delay : %u", sei_pic_timing.dpb_output_delay); - if (vui_param.pic_struct_present_flag) - { - sei_pic_timing.pic_struct = extract_bits(4); - sei_pic_timing.num_clock_ts = 0; - switch (sei_pic_timing.pic_struct) - { - case 0: case 1: case 2: sei_pic_timing.num_clock_ts = 1; break; - case 3: case 4: case 7: sei_pic_timing.num_clock_ts = 2; break; - case 5: case 6: case 8: sei_pic_timing.num_clock_ts = 3; break; - default: - ALOGE("sei_picture_timing: pic_struct invalid!"); - } - ALOGV("-->num_clock_ts : %u", sei_pic_timing.num_clock_ts); - for (OMX_U32 i = 0; i < sei_pic_timing.num_clock_ts && more_bits(); i++) - { - sei_pic_timing.clock_ts_flag = extract_bits(1); - if(sei_pic_timing.clock_ts_flag) - { - ALOGV("-->clock_timestamp present!"); - sei_pic_timing.ct_type = extract_bits(2); - sei_pic_timing.nuit_field_based_flag = extract_bits(1); - sei_pic_timing.counting_type = extract_bits(5); - sei_pic_timing.full_timestamp_flag = extract_bits(1); - sei_pic_timing.discontinuity_flag = extract_bits(1); - sei_pic_timing.cnt_dropped_flag = extract_bits(1); - sei_pic_timing.n_frames = extract_bits(8); - ALOGV("-->f_timestamp_flg : %u", sei_pic_timing.full_timestamp_flag); - ALOGV("-->n_frames : %u", sei_pic_timing.n_frames); - sei_pic_timing.seconds_value = 0; - sei_pic_timing.minutes_value = 0; - sei_pic_timing.hours_value = 0; - if (sei_pic_timing.full_timestamp_flag) - { - sei_pic_timing.seconds_value = extract_bits(6); - sei_pic_timing.minutes_value = extract_bits(6); - sei_pic_timing.hours_value = extract_bits(5); - } - else if (extract_bits(1)) - { - ALOGV("-->seconds_flag enabled!"); - sei_pic_timing.seconds_value = extract_bits(6); - if (extract_bits(1)) - { - ALOGV("-->minutes_flag enabled!"); - sei_pic_timing.minutes_value = extract_bits(6); - if (extract_bits(1)) - { - ALOGV("-->hours_flag enabled!"); - sei_pic_timing.hours_value = extract_bits(5); - } - } - } - sei_pic_timing.time_offset = 0; - if (time_offset_len > 0) - sei_pic_timing.time_offset = iv(time_offset_len); - ALOGV("-->seconds_value : %u", sei_pic_timing.seconds_value); - ALOGV("-->minutes_value : %u", sei_pic_timing.minutes_value); - ALOGV("-->hours_value : %u", sei_pic_timing.hours_value); - ALOGV("-->time_offset : %d", sei_pic_timing.time_offset); - } - } - } - ALOGV("@@sei_picture_timing: OUT"); -} - -void h264_stream_parser::sei_pan_scan() -{ -#ifdef _ANDROID_ - char property_value[PROPERTY_VALUE_MAX] = {0}; - OMX_S32 enable_panscan_log = 0; - property_get("vidc.dec.debug.panframedata", property_value, "0"); - enable_panscan_log = atoi(property_value); -#endif -#ifdef PANSCAN_HDLR - h264_pan_scan *pan_scan_param = panscan_hdl->get_free(); -#else - h264_pan_scan *pan_scan_param = &panscan_param; -#endif - - if (!pan_scan_param) - { - ALOGE("sei_pan_scan: ERROR: Invalid pointer!"); - return; - } - - pan_scan_param->rect_id = uev(); - if (pan_scan_param->rect_id > 0xFF) - { - ALOGE("sei_pan_scan: ERROR: Invalid rect_id[%lu]!", pan_scan_param->rect_id); - pan_scan_param->rect_id = NO_PAN_SCAN_BIT; - return; - } - - pan_scan_param->rect_cancel_flag = extract_bits(1); - - if (pan_scan_param->rect_cancel_flag) - pan_scan_param->rect_id = NO_PAN_SCAN_BIT; - else - { - pan_scan_param->cnt = uev() + 1; - if (pan_scan_param->cnt > MAX_PAN_SCAN_RECT) - { - ALOGE("sei_pan_scan: ERROR: Invalid num of rect [%lu]!", pan_scan_param->cnt); - pan_scan_param->rect_id = NO_PAN_SCAN_BIT; - return; - } - - for (OMX_U32 i = 0; i < pan_scan_param->cnt; i++) - { - pan_scan_param->rect_left_offset[i] = sev(); - pan_scan_param->rect_right_offset[i] = sev(); - pan_scan_param->rect_top_offset[i] = sev(); - pan_scan_param->rect_bottom_offset[i] = sev(); - - } - pan_scan_param->rect_repetition_period = uev(); -#ifdef PANSCAN_HDLR - if (pan_scan_param->rect_repetition_period > 1) - // Repetition period is decreased by 2 each time panscan data is used - pan_scan_param->rect_repetition_period *= 2; -#endif -#ifdef _ANDROID_ - if (enable_panscan_log) - { - print_pan_data(pan_scan_param); - } -#endif - } -} - -void h264_stream_parser::print_pan_data(h264_pan_scan *pan_scan_param) -{ - ALOGE("@@print_pan_data: IN"); - - ALOGE("-->rect_id : %lu", pan_scan_param->rect_id); - ALOGE("-->rect_cancel_flag : %u", pan_scan_param->rect_cancel_flag); - - ALOGE("-->cnt : %lu", pan_scan_param->cnt); - - for (OMX_U32 i = 0; i < pan_scan_param->cnt; i++) - { - ALOGE("-->rect_left_offset : %ld", pan_scan_param->rect_left_offset[i]); - ALOGE("-->rect_right_offset : %ld", pan_scan_param->rect_right_offset[i]); - ALOGE("-->rect_top_offset : %ld", pan_scan_param->rect_top_offset[i]); - ALOGE("-->rect_bottom_offset : %ld", pan_scan_param->rect_bottom_offset[i]); - } - ALOGE("-->repetition_period : %lu", pan_scan_param->rect_repetition_period); - - ALOGE("@@print_pan_data: OUT"); -} - -void h264_stream_parser::parse_sps() -{ - OMX_U32 value = 0, scaling_matrix_limit; - ALOGV("@@parse_sps: IN"); - value = extract_bits(8); //profile_idc - extract_bits(8); //constraint flags and reserved bits - extract_bits(8); //level_idc - uev(); //sps id - if (value == 100 || value == 110 || value == 122 || value == 244 || - value == 44 || value == 83 || value == 86 || value == 118) - { - if (uev() == 3) //chroma_format_idc - { - extract_bits(1); //separate_colour_plane_flag - scaling_matrix_limit = 12; - } - else - scaling_matrix_limit = 12; - uev(); //bit_depth_luma_minus8 - uev(); //bit_depth_chroma_minus8 - extract_bits(1); //qpprime_y_zero_transform_bypass_flag - if (extract_bits(1)) { //seq_scaling_matrix_present_flag - for (unsigned int i = 0; i < scaling_matrix_limit && more_bits(); i++) - { - if (extract_bits(1)) { ////seq_scaling_list_present_flag[ i ] - if (i < 6) - scaling_list(16); - else - scaling_list(64); - } - } - } - } - uev(); //log2_max_frame_num_minus4 - value = uev(); //pic_order_cnt_type - if (value == 0) - uev(); //log2_max_pic_order_cnt_lsb_minus4 - else if (value == 1) - { - extract_bits(1); //delta_pic_order_always_zero_flag - sev(); //offset_for_non_ref_pic - sev(); //offset_for_top_to_bottom_field - value = uev(); // num_ref_frames_in_pic_order_cnt_cycle - for (unsigned int i = 0; i < value; i++) - sev(); //offset_for_ref_frame[ i ] - } - uev(); //max_num_ref_frames - extract_bits(1); //gaps_in_frame_num_value_allowed_flag - value = uev(); //pic_width_in_mbs_minus1 - value = uev(); //pic_height_in_map_units_minus1 - if (!extract_bits(1)) //frame_mbs_only_flag - mbaff_flag = extract_bits(1); //mb_adaptive_frame_field_flag - extract_bits(1); //direct_8x8_inference_flag - if (extract_bits(1)) //frame_cropping_flag - { - uev(); //frame_crop_left_offset - uev(); //frame_crop_right_offset - uev(); //frame_crop_top_offset - uev(); //frame_crop_bottom_offset - } - if (extract_bits(1)) //vui_parameters_present_flag - parse_vui(false); - ALOGV("@@parse_sps: OUT"); -} - -void h264_stream_parser::scaling_list(OMX_U32 size_of_scaling_list) -{ - OMX_S32 last_scale = 8, next_scale = 8, delta_scale; - for (unsigned int j = 0; j < size_of_scaling_list; j++) - { - if (next_scale != 0) - { - delta_scale = sev(); - next_scale = (last_scale + delta_scale + 256) % 256; - } - last_scale = (next_scale == 0)? last_scale : next_scale; - } -} - -OMX_U32 h264_stream_parser::extract_bits(OMX_U32 n) -{ - OMX_U32 value = 0; - if (n > 32) - { - ALOGE("ERROR: extract_bits limit to 32 bits!"); - return value; - } - value = curr_32_bit >> (32 - n); - if (bits_read < n) - { - n -= bits_read; - read_word(); - value |= (curr_32_bit >> (32 - n)); - if (bits_read < n) - { - ALOGV("ERROR: extract_bits underflow!"); - value >>= (n - bits_read); - n = bits_read; - } - } - bits_read -= n; - curr_32_bit <<= n; - return value; -} - -void h264_stream_parser::read_word() -{ - curr_32_bit = 0; - bits_read = 0; - while (bitstream_bytes && bits_read < 32) - { - if (*bitstream == EMULATION_PREVENTION_THREE_BYTE && - zero_cntr >= 2 && emulation_sc_enabled) - { - ALOGV("EMULATION_PREVENTION_THREE_BYTE: Skip 0x03 byte aligned!"); - emulation_code_skip_cntr++; - } - else - { - curr_32_bit <<= 8; - curr_32_bit |= *bitstream; - bits_read += 8; - } - if (*bitstream == 0) - zero_cntr++; - else - zero_cntr = 0; - bitstream++; - bitstream_bytes--; - } - curr_32_bit <<= (32 - bits_read); -} - -OMX_U32 h264_stream_parser::uev() -{ - OMX_U32 lead_zero_bits = 0, code_num = 0; - while(!extract_bits(1) && more_bits()) - lead_zero_bits++; - code_num = lead_zero_bits == 0 ? 0 : - (1 << lead_zero_bits) - 1 + extract_bits(lead_zero_bits); - return code_num; -} - -bool h264_stream_parser::more_bits() -{ - return (bitstream_bytes > 0 || bits_read > 0); -} - -OMX_S32 h264_stream_parser::sev() -{ - OMX_U32 code_num = uev(); - OMX_S32 ret; - ret = (code_num + 1) >> 1; - return ((code_num & 1) ? ret : -ret); -} - -OMX_S32 h264_stream_parser::iv(OMX_U32 n_bits) -{ - OMX_U32 code_num = extract_bits(n_bits); - OMX_S32 ret = (code_num >> (n_bits - 1))? (-1)*(~(code_num & ~(0x1 << (n_bits - 1))) + 1) : code_num; - return ret; -} - -OMX_U32 h264_stream_parser::get_nal_unit_type(OMX_U32 *nal_unit_type) -{ - OMX_U32 value = 0, consumed_bytes = 3; - *nal_unit_type = NALU_TYPE_UNSPECIFIED; - ALOGV("-->get_nal_unit_type: IN"); - value = extract_bits(24); - while (value != 0x00000001 && more_bits()) - { - value <<= 8; - value |= extract_bits(8); - consumed_bytes++; - } - if (value != 0x00000001) - { - ALOGE("ERROR in get_nal_unit_type: Start code not found!"); - } - else - { - if (extract_bits(1)) // forbidden_zero_bit - { - ALOGE("WARNING: forbidden_zero_bit should be zero!"); - } - value = extract_bits(2); - ALOGV("-->nal_ref_idc : %x", value); - *nal_unit_type = extract_bits(5); - ALOGV("-->nal_unit_type : %x", *nal_unit_type); - consumed_bytes++; - if (consumed_bytes > 5) - { - ALOGE("-->WARNING: Startcode was found after the first 4 bytes!"); - } - } - ALOGV("-->get_nal_unit_type: OUT"); - return consumed_bytes; -} - -OMX_S64 h264_stream_parser::calculate_buf_period_ts(OMX_S64 timestamp) -{ - OMX_S64 clock_ts = timestamp; - ALOGV("calculate_ts(): IN"); - if (sei_buf_period.au_cntr == 0) - clock_ts = sei_buf_period.reference_ts = timestamp; - else if (sei_pic_timing.is_valid && VALID_TS(sei_buf_period.reference_ts)) - { - clock_ts = sei_buf_period.reference_ts + sei_pic_timing.cpb_removal_delay * - 1e6 * vui_param.num_units_in_tick / vui_param.time_scale; - } - sei_buf_period.au_cntr++; - ALOGV("calculate_ts(): OUT"); - return clock_ts; -} - -OMX_S64 h264_stream_parser::calculate_fixed_fps_ts(OMX_S64 timestamp, OMX_U32 DeltaTfiDivisor) -{ - if (VALID_TS(timestamp)) - vui_param.fixed_fps_prev_ts = timestamp; - else if (VALID_TS(vui_param.fixed_fps_prev_ts)) - vui_param.fixed_fps_prev_ts += DeltaTfiDivisor * 1e6 * - vui_param.num_units_in_tick / vui_param.time_scale; - return vui_param.fixed_fps_prev_ts; -} - -void h264_stream_parser::parse_frame_pack() -{ -#ifdef _ANDROID_ - char property_value[PROPERTY_VALUE_MAX] = {0}; - OMX_S32 enable_framepack_log = 0; - - property_get("vidc.dec.debug.panframedata", property_value, "0"); - enable_framepack_log = atoi(property_value); -#endif - ALOGV("\n%s:%d parse_frame_pack", __func__, __LINE__); - - frame_packing_arrangement.id = uev(); - - frame_packing_arrangement.cancel_flag = extract_bits(1); - if(!frame_packing_arrangement.cancel_flag) { - frame_packing_arrangement.type = extract_bits(7); - frame_packing_arrangement.quincunx_sampling_flag = extract_bits(1); - frame_packing_arrangement.content_interpretation_type = extract_bits(6); - frame_packing_arrangement.spatial_flipping_flag = extract_bits(1); - frame_packing_arrangement.frame0_flipped_flag = extract_bits(1); - frame_packing_arrangement.field_views_flag = extract_bits(1); - frame_packing_arrangement.current_frame_is_frame0_flag = extract_bits(1); - frame_packing_arrangement.frame0_self_contained_flag = extract_bits(1); - frame_packing_arrangement.frame1_self_contained_flag = extract_bits(1); - - if(!frame_packing_arrangement.quincunx_sampling_flag && - frame_packing_arrangement.type != 5) { - frame_packing_arrangement.frame0_grid_position_x = extract_bits(4); - frame_packing_arrangement.frame0_grid_position_y = extract_bits(4); - frame_packing_arrangement.frame1_grid_position_x = extract_bits(4); - frame_packing_arrangement.frame1_grid_position_y = extract_bits(4); - } - frame_packing_arrangement.reserved_byte = extract_bits(8); - frame_packing_arrangement.repetition_period = uev(); - } - frame_packing_arrangement.extension_flag = extract_bits(1); - -#ifdef _ANDROID_ - if (enable_framepack_log) - { - print_frame_pack(); - } -#endif -} - -void h264_stream_parser::print_frame_pack() -{ - ALOGV("\n ## frame_packing_arrangement.id = %u", frame_packing_arrangement.id); - ALOGV("\n ## frame_packing_arrangement.cancel_flag = %u", - frame_packing_arrangement.cancel_flag); - if(!frame_packing_arrangement.cancel_flag) - { - ALOGV("\n ## frame_packing_arrangement.type = %u", - frame_packing_arrangement.type); - ALOGV("\n ## frame_packing_arrangement.quincunx_sampling_flag = %u", - frame_packing_arrangement.quincunx_sampling_flag); - ALOGV("\n ## frame_packing_arrangement.content_interpretation_type = %u", - frame_packing_arrangement.content_interpretation_type); - ALOGV("\n ## frame_packing_arrangement.spatial_flipping_flag = %u", - frame_packing_arrangement.spatial_flipping_flag); - ALOGV("\n ## frame_packing_arrangement.frame0_flipped_flag = %u", - frame_packing_arrangement.frame0_flipped_flag); - ALOGV("\n ## frame_packing_arrangement.field_views_flag = %u", - frame_packing_arrangement.field_views_flag); - ALOGV("\n ## frame_packing_arrangement.current_frame_is_frame0_flag = %u", - frame_packing_arrangement.current_frame_is_frame0_flag); - ALOGV("\n ## frame_packing_arrangement.frame0_self_contained_flag = %u", - frame_packing_arrangement.frame0_self_contained_flag); - ALOGV("\n ## frame_packing_arrangement.frame1_self_contained_flag = %u", - frame_packing_arrangement.frame1_self_contained_flag); - ALOGV("\n ## frame_packing_arrangement.reserved_byte = %u", - frame_packing_arrangement.reserved_byte); - ALOGV("\n ## frame_packing_arrangement.repetition_period = %u", - frame_packing_arrangement.repetition_period); - ALOGV("\n ## frame_packing_arrangement.extension_flag = %u", - frame_packing_arrangement.extension_flag); - } -} -/* API'S EXPOSED TO OMX COMPONENT */ - -void h264_stream_parser::get_frame_pack_data( - OMX_QCOM_FRAME_PACK_ARRANGEMENT *frame_pack) -{ - ALOGV("\n%s:%d get frame data", __func__, __LINE__); - memcpy(&frame_pack->id,&frame_packing_arrangement.id, - FRAME_PACK_SIZE*sizeof(OMX_U32)); - return; -} - - -bool h264_stream_parser::is_mbaff() -{ - ALOGV("\n%s:%d MBAFF flag=%d", __func__, __LINE__,mbaff_flag); - return mbaff_flag; -} - -void h264_stream_parser::get_frame_rate(OMX_U32 *frame_rate) -{ - if (vui_param.num_units_in_tick != 0) - *frame_rate = vui_param.time_scale / (2 * vui_param.num_units_in_tick); -} - -void h264_stream_parser::parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, OMX_U32 nal_type, bool enable_emu_sc) -{ - OMX_U32 nal_unit_type = NALU_TYPE_UNSPECIFIED, cons_bytes = 0; - ALOGV("parse_nal(): IN nal_type(%lu)", nal_type); - if (!data_len) - return; - init_bitstream(data_ptr, data_len); - emulation_sc_enabled = enable_emu_sc; - if (nal_type != NALU_TYPE_VUI) - { - cons_bytes = get_nal_unit_type(&nal_unit_type); - if (nal_type != nal_unit_type && nal_type != NALU_TYPE_UNSPECIFIED) - { - ALOGV("Unexpected nal_type(%x) expected(%x)", nal_unit_type, nal_type); - return; - } - } - switch (nal_type) - { - case NALU_TYPE_SPS: - if (more_bits()) - parse_sps(); -#ifdef PANSCAN_HDLR - panscan_hdl->get_free(); -#endif - break; - case NALU_TYPE_SEI: - init_bitstream(data_ptr + cons_bytes, data_len - cons_bytes); - parse_sei(); - break; - case NALU_TYPE_VUI: - parse_vui(true); - break; - default: - ALOGV("nal_unit_type received : %lu", nal_type); - } - ALOGV("parse_nal(): OUT"); -} - -#ifdef PANSCAN_HDLR -void h264_stream_parser::update_panscan_data(OMX_S64 timestamp) -{ - panscan_hdl->update_last(timestamp); -} -#endif - -void h264_stream_parser::fill_aspect_ratio_info(OMX_QCOM_ASPECT_RATIO *dest_aspect_ratio) -{ - if(dest_aspect_ratio && vui_param.aspect_ratio_info_present_flag) - { - dest_aspect_ratio->aspectRatioX = vui_param.aspect_ratio_info.aspect_ratio_x; - dest_aspect_ratio->aspectRatioY = vui_param.aspect_ratio_info.aspect_ratio_y; - } -} - -void h264_stream_parser::fill_pan_scan_data(OMX_QCOM_PANSCAN *dest_pan_scan, OMX_S64 timestamp) -{ -#ifdef PANSCAN_HDLR - h264_pan_scan *pan_scan_param = panscan_hdl->get_populated(timestamp); -#else - h264_pan_scan *pan_scan_param = &panscan_param; -#endif - if (pan_scan_param) { - if (!(pan_scan_param->rect_id & NO_PAN_SCAN_BIT)) - { - PRINT_PANSCAN_PARAM(*pan_scan_param); - dest_pan_scan->numWindows = pan_scan_param->cnt; - for (unsigned int i = 0; i < dest_pan_scan->numWindows; i++) - { - dest_pan_scan->window[i].x = pan_scan_param->rect_left_offset[i]; - dest_pan_scan->window[i].y = pan_scan_param->rect_top_offset[i]; - dest_pan_scan->window[i].dx = pan_scan_param->rect_right_offset[i]; - dest_pan_scan->window[i].dy = pan_scan_param->rect_bottom_offset[i]; - } -#ifndef PANSCAN_HDLR - if (pan_scan_param->rect_repetition_period == 0) - pan_scan_param->rect_id = NO_PAN_SCAN_BIT; - else if (pan_scan_param->rect_repetition_period > 1) - pan_scan_param->rect_repetition_period = - (pan_scan_param->rect_repetition_period == 2)? 0 : - (pan_scan_param->rect_repetition_period - 1); -#endif - } - else - pan_scan_param->rect_repetition_period = 0; - } -} - -OMX_S64 h264_stream_parser::process_ts_with_sei_vui(OMX_S64 timestamp) -{ - bool clock_ts_flag = false; - OMX_S64 clock_ts = timestamp; - OMX_U32 deltaTfiDivisor = 2; - if (vui_param.timing_info_present_flag) - { - if (vui_param.pic_struct_present_flag) - { - if(sei_pic_timing.clock_ts_flag) - { - clock_ts = ((sei_pic_timing.hours_value * 60 + sei_pic_timing.minutes_value) * 60 + sei_pic_timing.seconds_value) * 1e6 + - (sei_pic_timing.n_frames * (vui_param.num_units_in_tick * (1 + sei_pic_timing.nuit_field_based_flag)) + sei_pic_timing.time_offset) * - 1e6 / vui_param.time_scale; - ALOGV("-->CLOCK TIMESTAMP : %lld", clock_ts); - clock_ts_flag = true; - } - if (vui_param.fixed_frame_rate_flag) - { - switch (sei_pic_timing.pic_struct) - { - case 1: case 2: deltaTfiDivisor = 1; break; - case 0: case 3: case 4: deltaTfiDivisor = 2; break; - case 5: case 6: deltaTfiDivisor = 3; break; - case 7: deltaTfiDivisor = 4; break; - case 8: deltaTfiDivisor = 6; break; - default: - ALOGE("process_ts_with_sei_vui: pic_struct invalid!"); - } - } - } - if (!clock_ts_flag) - { - if (vui_param.fixed_frame_rate_flag) - clock_ts = calculate_fixed_fps_ts(timestamp, deltaTfiDivisor); - else if (sei_buf_period.is_valid) - clock_ts = calculate_buf_period_ts(timestamp); - } - } - else - { - ALOGV("NO TIMING information present in VUI!"); - } - sei_pic_timing.is_valid = false; // SEI data is valid only for current frame - return clock_ts; -} - -#ifdef PANSCAN_HDLR - -panscan_handler::panscan_handler() : panscan_data(NULL) {} - -panscan_handler::~panscan_handler() -{ - if (panscan_data) - { - free(panscan_data); - panscan_data = NULL; - } -} - -bool panscan_handler::initialize(int num_data) -{ - bool ret = false; - if (!panscan_data) - { - panscan_data = (PANSCAN_NODE *) malloc (sizeof(PANSCAN_NODE) * num_data); - if (panscan_data) - { - panscan_free.add_multiple(panscan_data, num_data); - ret = true; - } - } - else - { - ALOGE("ERROR: Old panscan memory must be freed to allocate new"); - } - return ret; -} - -h264_pan_scan *panscan_handler::get_free() -{ - h264_pan_scan *data = NULL; - PANSCAN_NODE *panscan_node = panscan_used.watch_last(); - panscan_node = (!panscan_node || VALID_TS(panscan_node->start_ts))? - panscan_free.remove_first() : - panscan_used.remove_last(); - if (panscan_node) - { - panscan_node->start_ts = LLONG_MAX; - panscan_node->end_ts = LLONG_MAX; - panscan_node->pan_scan_param.rect_id = NO_PAN_SCAN_BIT; - panscan_node->active = false; - panscan_used.add_last(panscan_node); - data = &panscan_node->pan_scan_param; - } - return data; -} - -h264_pan_scan *panscan_handler::get_populated(OMX_S64 frame_ts) -{ - h264_pan_scan *data = NULL; - PANSCAN_NODE *panscan_node = panscan_used.watch_first(); - while (panscan_node && !data) - { - if (VALID_TS(panscan_node->start_ts)) - { - if (panscan_node->active && frame_ts < panscan_node->start_ts) - panscan_node->start_ts = frame_ts; - if (frame_ts >= panscan_node->start_ts) - if (frame_ts < panscan_node->end_ts) - { - data = &panscan_node->pan_scan_param; - panscan_node->active = true; - } - else - { - panscan_free.add_last(panscan_used.remove_first()); - panscan_node = panscan_used.watch_first(); - } - else - // Finish search if current timestamp has not reached - // start timestamp of first panscan data. - panscan_node = NULL; - } - else - { - // Only one panscan data is stored for clips - // with invalid timestamps in every frame - data = &panscan_node->pan_scan_param; - panscan_node->active = true; - } - } - if (data) { - if (data->rect_repetition_period == 0) - panscan_free.add_last(panscan_used.remove_first()); - else if (data->rect_repetition_period > 1) - data->rect_repetition_period -= 2; - } - PRINT_PANSCAN_DATA(panscan_node); - return data; -} - -void panscan_handler::update_last(OMX_S64 frame_ts) -{ - PANSCAN_NODE *panscan_node = panscan_used.watch_last(); - if (panscan_node && !VALID_TS(panscan_node->start_ts)) - { - panscan_node->start_ts = frame_ts; - PRINT_PANSCAN_DATA(panscan_node); - if (panscan_node->prev) - { - if (frame_ts < panscan_node->prev->end_ts) - panscan_node->prev->end_ts = frame_ts; - else if (!VALID_TS(frame_ts)) - panscan_node->prev->pan_scan_param.rect_repetition_period = 0; - PRINT_PANSCAN_DATA(panscan_node->prev); - } - } -} - -template -void omx_dl_list::add_multiple(NODE_STRUCT *data_arr, int data_num) -{ - for (int idx = 0; idx < data_num; idx++) - add_last(&data_arr[idx]); -} - -template -NODE_STRUCT *omx_dl_list::remove_first() -{ - NODE_STRUCT *data = head; - if (head) - { - if (head->next) - { - head = head->next; - head->prev = NULL; - } - else - head = tail = NULL; - data->next = data->prev = NULL; - } - return data; -} - -template -NODE_STRUCT *omx_dl_list::remove_last() -{ - NODE_STRUCT *data = tail; - if (tail) - { - if (tail->prev) - { - tail = tail->prev; - tail->next = NULL; - } - else - head = tail = NULL; - data->next = data->prev = NULL; - } - return data; -} - -template -void omx_dl_list::add_last(NODE_STRUCT* data_ptr) -{ - if (data_ptr) - { - data_ptr->next = NULL; - data_ptr->prev = tail; - if (tail) - { - tail->next = data_ptr; - tail = data_ptr; - } - else - head = tail = data_ptr; - } -} - -template -NODE_STRUCT* omx_dl_list::watch_first() -{ - return head; -} - -template -NODE_STRUCT* omx_dl_list::watch_last() -{ - return tail; -} - -#endif diff --git a/mm-video/vidc/vdec/src/hevc_utils.cpp b/mm-video/vidc/vdec/src/hevc_utils.cpp deleted file mode 100644 index a283f0ed..00000000 --- a/mm-video/vidc/vdec/src/hevc_utils.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -/*======================================================================== - - O p e n M M - V i d e o U t i l i t i e s - -*//** @file VideoUtils.cpp - This module contains utilities and helper routines. - -@par EXTERNALIZED FUNCTIONS - -@par INITIALIZATION AND SEQUENCING REQUIREMENTS - (none) - -*//*====================================================================== */ - -/* ======================================================================= - - INCLUDE FILES FOR MODULE - -========================================================================== */ -#include "hevc_utils.h" -#include -#include -#include -#include -#ifdef _ANDROID_ -#include -#endif - -#define DEBUG_PRINT_LOW ALOGV -#define DEBUG_PRINT_ERROR ALOGE - - -/* ======================================================================= - - DEFINITIONS AND DECLARATIONS FOR MODULE - -This section contains definitions for constants, macros, types, variables -and other items needed by this module. - -========================================================================== */ - -HEVC_Utils::HEVC_Utils() -{ - initialize_frame_checking_environment(); -} - -HEVC_Utils::~HEVC_Utils() -{ -} - -/***********************************************************************/ -/* -FUNCTION: - HEVC_Utils::initialize_frame_checking_environment - -DESCRIPTION: - Extract RBSP data from a NAL - -INPUT/OUTPUT PARAMETERS: - None - -RETURN VALUE: - boolean - -SIDE EFFECTS: - None. -*/ -/***********************************************************************/ -void HEVC_Utils::initialize_frame_checking_environment() -{ - m_forceToStichNextNAL = false; - m_au_data = false; - nalu_type = NAL_UNIT_INVALID; -} - -/*=========================================================================== -FUNCTION: - HEVC_Utils::iSNewFrame - -DESCRIPTION: - Returns true if NAL parsing successfull otherwise false. - -INPUT/OUTPUT PARAMETERS: - - buffer : buffer containing start code or nal length + NAL units - buffer_length : the length of the NAL buffer - start_code : If true, start code is detected, - otherwise size nal length is detected - size_of_nal_length_field: size of nal length field - - isNewFrame: true if the NAL belongs to a differenet frame - false if the NAL belongs to a current frame - -RETURN VALUE: - boolean true, if nal parsing is successful - false, if the nal parsing has errors - -SIDE EFFECTS: - None. -===========================================================================*/ -bool HEVC_Utils::isNewFrame(OMX_BUFFERHEADERTYPE *p_buf_hdr, - OMX_IN OMX_U32 size_of_nal_length_field, - OMX_OUT OMX_BOOL &isNewFrame) -{ - OMX_IN OMX_U8 *buffer = p_buf_hdr->pBuffer; - OMX_IN OMX_U32 buffer_length = p_buf_hdr->nFilledLen; - byte bFirstSliceInPic = 0; - - byte coef1=1, coef2=0, coef3=0; - uint32 pos = 0; - uint32 nal_len = buffer_length; - uint32 sizeofNalLengthField = 0; - uint32 zero_count; - boolean start_code = (size_of_nal_length_field==0)?true:false; - - if(start_code) { - // Search start_code_prefix_one_3bytes (0x000001) - coef2 = buffer[pos++]; - coef3 = buffer[pos++]; - do { - if(pos >= buffer_length) - { - DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - - coef1 = coef2; - coef2 = coef3; - coef3 = buffer[pos++]; - } while(coef1 || coef2 || coef3 != 1); - } - else if (size_of_nal_length_field) - { - /* This is the case to play multiple NAL units inside each access unit*/ - /* Extract the NAL length depending on sizeOfNALength field */ - sizeofNalLengthField = size_of_nal_length_field; - nal_len = 0; - while(size_of_nal_length_field--) - { - nal_len |= buffer[pos++]<<(size_of_nal_length_field<<3); - } - if (nal_len >= buffer_length) - { - DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - } - - if (nal_len > buffer_length) - { - DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - - if(pos + 2 > (nal_len + sizeofNalLengthField)) - { - DEBUG_PRINT_ERROR("ERROR: In %s() - line %d", __func__, __LINE__); - return false; - } - - nalu_type = (buffer[pos] & 0x7E)>>1 ; //=== nal_unit_type - - DEBUG_PRINT_LOW("\n@#@# Pos = %x NalType = %x buflen = %d", pos-1, nalu_type, buffer_length); - - isNewFrame = OMX_FALSE; - - if (nalu_type == NAL_UNIT_VPS || - nalu_type == NAL_UNIT_SPS || - nalu_type == NAL_UNIT_PPS || - nalu_type == NAL_UNIT_SEI) - { - DEBUG_PRINT_LOW("\n Non-AU boundary with NAL type %d", nalu_type); - if(m_au_data) - { - isNewFrame = OMX_TRUE; - m_au_data = false; - } - - m_forceToStichNextNAL = true; - } - else if (nalu_type <= NAL_UNIT_RESERVED_23) - { - DEBUG_PRINT_LOW("\n AU Boundary with NAL type %d ",nal_unit.nalu_type); - if (!m_forceToStichNextNAL) - { - bFirstSliceInPic = ((buffer[pos+2] & 0x80)>>7); - if (bFirstSliceInPic) //=== first_ctb_in_slice is only 1'b1 coded tree block - { - DEBUG_PRINT_LOW("Found a New Frame due to 1st coded tree block"); - isNewFrame = OMX_TRUE; - } - } - m_au_data = true; - m_forceToStichNextNAL = false; - } - DEBUG_PRINT_LOW("get_HEVC_nal_type - newFrame value %d\n",isNewFrame); - return true; -} - diff --git a/mm-video/vidc/vdec/src/message_queue.c b/mm-video/vidc/vdec/src/message_queue.c deleted file mode 100755 index a6b491ed..00000000 --- a/mm-video/vidc/vdec/src/message_queue.c +++ /dev/null @@ -1,178 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "message_queue.h" - -int check_if_queue_empty ( unsigned int queuetocheck, void* queuecontext ) -{ - struct video_queue_context *ptr_q = NULL; - /* - * queuetocheck - 0 command queue - * queuetocheck - 1 data queue - */ - if ( queuecontext == NULL || (queuetocheck > 1 ) ) - { - return 1; - } - ptr_q = (struct video_queue_context *)queuecontext; - - if (queuetocheck == 0) - { - if (ptr_q->read_comq == ptr_q->write_comq) - { - return 1; - } - } - else if (queuetocheck == 1) - { - if (ptr_q->write_dataq == ptr_q->read_dataq) - { - return 1; - } - } - - return 0; -} - - - -struct video_msgq * queue_get_cmd (void* queuecontext ) -{ - struct video_queue_context *ptr_q = NULL; - struct video_msgq *pitem = NULL; - - if( NULL == queuecontext ) - { - printf("\n queue_get_cmd: Invalid Input parameter\n"); - return NULL; - } - - ptr_q = (struct video_queue_context *)queuecontext; - - /* Wait on the semaphore till it is released */ - sem_wait(&ptr_q->sem_message); - - /* Lock the mutex to protect the critical section */ - pthread_mutex_lock(&ptr_q->mutex); - - if (ptr_q->read_comq != ptr_q->write_comq) - { - pitem = &ptr_q->ptr_cmdq [ptr_q->read_comq]; - ptr_q->read_comq = (ptr_q->read_comq + 1) % \ - ptr_q->commandq_size; - } - else if (ptr_q->write_dataq != ptr_q->read_dataq) - { - pitem = &ptr_q->ptr_dataq [ptr_q->read_dataq]; - ptr_q->read_dataq = (ptr_q->read_dataq + 1) % \ - ptr_q->dataq_size; - } - - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - - return pitem; -} - - -int queue_post_cmdq ( void* queuecontext, - struct video_msgq *pitem - ) -{ - struct video_queue_context *ptr_q = NULL; - - if (pitem == NULL || queuecontext == NULL) - { - return -1; - } - ptr_q = (struct video_queue_context *)queuecontext; - - /* Lock the mutex to protect the critical section */ - pthread_mutex_lock(&ptr_q->mutex); - - if ((ptr_q->write_comq + 1) % ptr_q->commandq_size == ptr_q->read_comq) - { - printf("\n QUEUE is FULL"); - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - return 0; - } - else - { - /* Store the command in the Message Queue & increment write offset */ - memcpy ( &ptr_q->ptr_cmdq [ptr_q->write_comq],pitem, \ - sizeof (struct video_msgq)); - ptr_q->write_comq = (ptr_q->write_comq + 1) % ptr_q->commandq_size; - } - - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - - /* Post the semaphore */ - sem_post(&ptr_q->sem_message); - return 1; -} - - -int queue_post_dataq ( void *queuecontext, - struct video_msgq *pitem - ) -{ - struct video_queue_context *ptr_q = NULL; - - if (pitem == NULL || queuecontext == NULL) - { - return -1; - } - ptr_q = (struct video_queue_context *)queuecontext; - - /* Lock the mutex to protect the critical section */ - pthread_mutex_lock(&ptr_q->mutex); - - if ((ptr_q->write_dataq + 1) % ptr_q->dataq_size == ptr_q->read_dataq) - { - printf("\n QUEUE is FULL"); - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - return 0; - } - else - { - /* Store the command in the Message Queue & increment write offset */ - memcpy ( &ptr_q->ptr_dataq [ptr_q->write_dataq],pitem, \ - sizeof (struct video_msgq)); - ptr_q->write_dataq = (ptr_q->write_dataq + 1) % ptr_q->dataq_size; - } - - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - - /* Post the semaphore */ - sem_post(&ptr_q->sem_message); - return 1; - -} diff --git a/mm-video/vidc/vdec/src/mp4_utils.cpp b/mm-video/vidc/vdec/src/mp4_utils.cpp deleted file mode 100644 index 95335d08..00000000 --- a/mm-video/vidc/vdec/src/mp4_utils.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "mp4_utils.h" -//#include "omx_vdec.h" -# include -#ifdef _ANDROID_ - extern "C"{ - #include - } -#endif//_ANDROID_ - -#undef DEBUG_PRINT_LOW -#undef DEBUG_PRINT_HIGH -#undef DEBUG_PRINT_ERROR - -#define DEBUG_PRINT_LOW ALOGV -#define DEBUG_PRINT_HIGH ALOGV -#define DEBUG_PRINT_ERROR ALOGE - -MP4_Utils::MP4_Utils() -{ - m_SrcWidth = 0; - m_SrcHeight = 0; - vop_time_resolution = 0; - vop_time_found = false; - -} -MP4_Utils::~MP4_Utils() -{ -} - -uint32 MP4_Utils::read_bit_field(posInfoType * posPtr, uint32 size) { - uint8 *bits = &posPtr->bytePtr[0]; - uint32 bitBuf = - (bits[0] << 24) | (bits[1] << 16) | (bits[2] << 8) | bits[3]; - - uint32 value = (bitBuf >> (32 - posPtr->bitPos - size)) & MASK(size); - - /* Update the offset in preparation for next field */ - posPtr->bitPos += size; - - while (posPtr->bitPos >= 8) { - posPtr->bitPos -= 8; - posPtr->bytePtr++; - } - return value; -} -static uint8 *find_code - (uint8 * bytePtr, uint32 size, uint32 codeMask, uint32 referenceCode) { - uint32 code = 0xFFFFFFFF; - for (uint32 i = 0; i < size; i++) { - code <<= 8; - code |= *bytePtr++; - - if ((code & codeMask) == referenceCode) { - return bytePtr; - } - } - - DEBUG_PRINT_LOW("Unable to find code 0x%x\n", referenceCode); - return NULL; -} -bool MP4_Utils::parseHeader(mp4StreamType * psBits) { - uint32 profile_and_level_indication = 0; - uint8 VerID = 1; /* default value */ - long hxw = 0; - - m_posInfo.bitPos = 0; - m_posInfo.bytePtr = psBits->data; - m_dataBeginPtr = psBits->data; - - m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,4, - MASK(32),VOP_START_CODE); - if(m_posInfo.bytePtr) { - return false; - } - - m_posInfo.bitPos = 0; - m_posInfo.bytePtr = psBits->data; - m_dataBeginPtr = psBits->data; - m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,4, - MASK(32),GOV_START_CODE); - if(m_posInfo.bytePtr) { - return false; - } - - m_posInfo.bitPos = 0; - m_posInfo.bytePtr = psBits->data; - m_dataBeginPtr = psBits->data; - /* parsing Visual Object Seqence(VOS) header */ - m_posInfo.bytePtr = find_code(m_posInfo.bytePtr, - psBits->numBytes, - MASK(32), - VISUAL_OBJECT_SEQUENCE_START_CODE); - if ( m_posInfo.bytePtr == NULL ){ - m_posInfo.bitPos = 0; - m_posInfo.bytePtr = psBits->data; - } - else { - uint32 profile_and_level_indication = read_bit_field (&m_posInfo, 8); - } - /* parsing Visual Object(VO) header*/ - /* note: for now, we skip over the user_data */ - m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,psBits->numBytes, - MASK(32),VISUAL_OBJECT_START_CODE); - if(m_posInfo.bytePtr == NULL) { - m_posInfo.bitPos = 0; - m_posInfo.bytePtr = psBits->data; - } - else { - uint32 is_visual_object_identifier = read_bit_field (&m_posInfo, 1); - if ( is_visual_object_identifier ) { - /* visual_object_verid*/ - read_bit_field (&m_posInfo, 4); - /* visual_object_priority*/ - read_bit_field (&m_posInfo, 3); - } - - /* visual_object_type*/ - uint32 visual_object_type = read_bit_field (&m_posInfo, 4); - if ( visual_object_type != VISUAL_OBJECT_TYPE_VIDEO_ID ) { - return false; - } - /* skipping video_signal_type params*/ - /*parsing Video Object header*/ - m_posInfo.bytePtr = find_code(m_posInfo.bytePtr,psBits->numBytes, - VIDEO_OBJECT_START_CODE_MASK,VIDEO_OBJECT_START_CODE); - if ( m_posInfo.bytePtr == NULL ) { - return false; - } - } - - /* parsing Video Object Layer(VOL) header */ - m_posInfo.bitPos = 0; - m_posInfo.bytePtr = find_code(m_posInfo.bytePtr, - psBits->numBytes, - VIDEO_OBJECT_LAYER_START_CODE_MASK, - VIDEO_OBJECT_LAYER_START_CODE); - if ( m_posInfo.bytePtr == NULL ) { - m_posInfo.bitPos = 0; - m_posInfo.bytePtr = psBits->data; - } - - // 1 -> random accessible VOL - read_bit_field(&m_posInfo, 1); - - uint32 video_object_type_indication = read_bit_field (&m_posInfo, 8); - if ( (video_object_type_indication != SIMPLE_OBJECT_TYPE) && - (video_object_type_indication != SIMPLE_SCALABLE_OBJECT_TYPE) && - (video_object_type_indication != CORE_OBJECT_TYPE) && - (video_object_type_indication != ADVANCED_SIMPLE) && - (video_object_type_indication != RESERVED_OBJECT_TYPE) && - (video_object_type_indication != MAIN_OBJECT_TYPE)) { - return false; - } - /* is_object_layer_identifier*/ - uint32 is_object_layer_identifier = read_bit_field (&m_posInfo, 1); - if (is_object_layer_identifier) { - uint32 video_object_layer_verid = read_bit_field (&m_posInfo, 4); - uint32 video_object_layer_priority = read_bit_field (&m_posInfo, 3); - VerID = (unsigned char)video_object_layer_verid; - } - - /* aspect_ratio_info*/ - uint32 aspect_ratio_info = read_bit_field (&m_posInfo, 4); - if ( aspect_ratio_info == EXTENDED_PAR ) { - /* par_width*/ - read_bit_field (&m_posInfo, 8); - /* par_height*/ - read_bit_field (&m_posInfo, 8); - } - /* vol_control_parameters */ - uint32 vol_control_parameters = read_bit_field (&m_posInfo, 1); - if ( vol_control_parameters ) { - /* chroma_format*/ - uint32 chroma_format = read_bit_field (&m_posInfo, 2); - if ( chroma_format != 1 ) { - return false; - } - /* low_delay*/ - uint32 low_delay = read_bit_field (&m_posInfo, 1); - /* vbv_parameters (annex D)*/ - uint32 vbv_parameters = read_bit_field (&m_posInfo, 1); - if ( vbv_parameters ) { - /* first_half_bitrate*/ - uint32 first_half_bitrate = read_bit_field (&m_posInfo, 15); - uint32 marker_bit = read_bit_field (&m_posInfo, 1); - if ( marker_bit != 1) { - return false; - } - /* latter_half_bitrate*/ - uint32 latter_half_bitrate = read_bit_field (&m_posInfo, 15); - marker_bit = read_bit_field (&m_posInfo, 1); - if ( marker_bit != 1) { - return false; - } - uint32 VBVPeakBitRate = (first_half_bitrate << 15) + latter_half_bitrate; - /* first_half_vbv_buffer_size*/ - uint32 first_half_vbv_buffer_size = read_bit_field (&m_posInfo, 15); - marker_bit = read_bit_field (&m_posInfo, 1); - if ( marker_bit != 1) { - return false; - } - /* latter_half_vbv_buffer_size*/ - uint32 latter_half_vbv_buffer_size = read_bit_field (&m_posInfo, 3); - uint32 VBVBufferSize = (first_half_vbv_buffer_size << 3) + latter_half_vbv_buffer_size; - /* first_half_vbv_occupancy*/ - uint32 first_half_vbv_occupancy = read_bit_field (&m_posInfo, 11); - marker_bit = read_bit_field (&m_posInfo, 1); - if ( marker_bit != 1) { - return false; - } - /* latter_half_vbv_occupancy*/ - uint32 latter_half_vbv_occupancy = read_bit_field (&m_posInfo, 15); - marker_bit = read_bit_field (&m_posInfo, 1); - if ( marker_bit != 1) { - return false; - } - }/* vbv_parameters*/ - }/*vol_control_parameters*/ - - /* video_object_layer_shape*/ - uint32 video_object_layer_shape = read_bit_field (&m_posInfo, 2); - uint8 VOLShape = (unsigned char)video_object_layer_shape; - if ( VOLShape != MPEG4_SHAPE_RECTANGULAR ) { - return false; - } - /* marker_bit*/ - uint32 marker_bit = read_bit_field (&m_posInfo, 1); - if ( marker_bit != 1 ) { - return false; - } - /* vop_time_increment_resolution*/ - uint32 vop_time_increment_resolution = read_bit_field (&m_posInfo, 16); - vop_time_resolution = vop_time_increment_resolution; - vop_time_found = true; - return true; -} - -bool MP4_Utils::is_notcodec_vop(unsigned char *pbuffer, unsigned int len) -{ - unsigned int index = 4,vop_bits=0; - unsigned int temp = vop_time_resolution - 1; - unsigned char vop_type=0,modulo_bit=0,not_coded=0; - if (!vop_time_found || !pbuffer || len < 5) { - return false; - } - if((pbuffer[0] == 0) && (pbuffer[1] == 0) && (pbuffer[2] == 1) && (pbuffer[3] == 0xB6)){ - while(temp) { - vop_bits++; - temp >>= 1; - } - vop_type = (pbuffer[index] & 0xc0) >> 6; - unsigned bits_parsed = 2; - do { - modulo_bit = pbuffer[index] & (1 << (7-bits_parsed)); - bits_parsed++; - index += bits_parsed/8; - bits_parsed = bits_parsed %8; - if(index >= len) { - return false; - } - }while(modulo_bit); - bits_parsed++; //skip marker bit - bits_parsed += vop_bits + 1;//Vop bit & Marker bits - index += bits_parsed/8; - if(index >= len) { - return false; - } - bits_parsed = bits_parsed % 8; - not_coded = pbuffer[index] & (1 << (7 - bits_parsed)); - if(!not_coded){ - return true; - } - } - return false; -} diff --git a/mm-video/vidc/vdec/src/omx_vdec.cpp b/mm-video/vidc/vdec/src/omx_vdec.cpp deleted file mode 100644 index f9ca19ca..00000000 --- a/mm-video/vidc/vdec/src/omx_vdec.cpp +++ /dev/null @@ -1,9978 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -/*============================================================================ - O p e n M A X w r a p p e r s - O p e n M A X C o r e - -*//** @file omx_vdec.cpp - This module contains the implementation of the OpenMAX core & component. - -*//*========================================================================*/ - -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// -#define JB_MR1 -#include -#include -#include -#include -#include -#include -#ifndef JB_MR1 -#include -#include -#endif -#include "power_module.h" -#include "omx_vdec.h" -#include -#include - -#ifndef _ANDROID_ -#include -#include -#endif //_ANDROID_ - -#ifdef _ANDROID_ -#include -#undef USE_EGL_IMAGE_GPU -#endif - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -#include -#endif - -#if defined (_ANDROID_ICS_) -#include -#include -#endif - -#ifdef _ANDROID_ -#include "DivXDrmDecrypt.h" -#endif //_ANDROID_ - -#ifdef USE_EGL_IMAGE_GPU -#include -#include -#define EGL_BUFFER_HANDLE_QCOM 0x4F00 -#define EGL_BUFFER_OFFSET_QCOM 0x4F01 -#endif - -#ifdef INPUT_BUFFER_LOG -#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" -#define INPUT_BUFFER_FILE_NAME_LEN 30 -FILE *inputBufferFile1; -char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; -#endif -#ifdef OUTPUT_BUFFER_LOG -FILE *outputBufferFile1; -char outputfilename [] = "/data/output.yuv"; -#endif -#ifdef OUTPUT_EXTRADATA_LOG -FILE *outputExtradataFile; -char ouputextradatafilename [] = "/data/extradata"; -#endif - -#define DEFAULT_FPS 30 -#define MAX_NUM_SPS 32 -#define MAX_NUM_PPS 256 -#define MAX_INPUT_ERROR (MAX_NUM_SPS + MAX_NUM_PPS) -#define MAX_SUPPORTED_FPS 120 - -#define VC1_SP_MP_START_CODE 0xC5000000 -#define VC1_SP_MP_START_CODE_MASK 0xFF000000 -#define VC1_AP_SEQ_START_CODE 0x0F010000 -#define VC1_STRUCT_C_PROFILE_MASK 0xF0 -#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 -#define VC1_SIMPLE_PROFILE 0 -#define VC1_MAIN_PROFILE 1 -#define VC1_ADVANCE_PROFILE 3 -#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 -#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 -#define VC1_STRUCT_C_LEN 4 -#define VC1_STRUCT_C_POS 8 -#define VC1_STRUCT_A_POS 12 -#define VC1_STRUCT_B_POS 24 -#define VC1_SEQ_LAYER_SIZE 36 - -#ifdef USE_ION - #define MEM_DEVICE "/dev/ion" - #ifdef MAX_RES_720P - #define MEM_HEAP_ID ION_CAMERA_HEAP_ID - #else - #define MEM_HEAP_ID ION_CP_MM_HEAP_ID - #endif -#elif MAX_RES_720P -#define MEM_DEVICE "/dev/pmem_adsp" -#elif MAX_RES_1080P_EBI -#define MEM_DEVICE "/dev/pmem_adsp" -#elif MAX_RES_1080P -#define MEM_DEVICE "/dev/pmem_smipool" -#endif - - -#ifdef MAX_RES_720P -#define DEVICE_SCRATCH 0 -#else -#define DEVICE_SCRATCH 64 -#endif - -/* -#ifdef _ANDROID_ - extern "C"{ - #include - } -#endif//_ANDROID_ -*/ - -#ifndef _ANDROID_ -#include -#define strlcpy g_strlcpy -#endif - -#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } -#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } - -void* async_message_thread (void *input) -{ - struct vdec_ioctl_msg ioctl_msg; - struct vdec_msginfo vdec_msg; - omx_vdec *omx = reinterpret_cast(input); - int error_code = 0; - DEBUG_PRINT_HIGH("omx_vdec: Async thread start"); - prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); - while (1) - { - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&vdec_msg; - /*Wait for a message from the video decoder driver*/ - error_code = ioctl ( omx->drv_ctx.video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG, - (void*)&ioctl_msg); - if (error_code == -512) // ERESTARTSYS - { - DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!"); - } - else if (error_code < 0) - { - DEBUG_PRINT_ERROR("\n Error in ioctl read next msg"); - break; - } /*Call Instance specific process function*/ - else if (omx->async_message_process(input,&vdec_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message"); - } - } - DEBUG_PRINT_HIGH("omx_vdec: Async thread stop"); - return NULL; -} - -void* message_thread(void *input) -{ - omx_vdec* omx = reinterpret_cast(input); - unsigned char id; - int n; - - DEBUG_PRINT_HIGH("omx_vdec: message thread start"); - prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); - while (1) - { - - n = read(omx->m_pipe_in, &id, 1); - - if(0 == n) - { - break; - } - - if (1 == n) - { - omx->process_event_cb(omx, id); - } - if ((n < 0) && (errno != EINTR)) - { - DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); - break; - } - } - DEBUG_PRINT_HIGH("omx_vdec: message thread stop"); - return 0; -} - -void post_message(omx_vdec *omx, unsigned char id) -{ - int ret_value; - DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out); - ret_value = write(omx->m_pipe_out, &id, 1); - DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value); -} - -// omx_cmd_queue destructor -omx_vdec::omx_cmd_queue::~omx_cmd_queue() -{ - // Nothing to do -} - -// omx cmd queue constructor -omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) -{ - memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); -} - -// omx cmd queue insert -bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) -{ - bool ret = true; - if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_q[m_write].id = id; - m_q[m_write].param1 = p1; - m_q[m_write].param2 = p2; - m_write++; - m_size ++; - if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_write = 0; - } - } - else - { - ret = false; - DEBUG_PRINT_ERROR("\n ERROR: %s()::Command Queue Full", __func__); - } - return ret; -} - -// omx cmd queue pop -bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) -{ - bool ret = true; - if (m_size > 0) - { - *id = m_q[m_read].id; - *p1 = m_q[m_read].param1; - *p2 = m_q[m_read].param2; - // Move the read pointer ahead - ++m_read; - --m_size; - if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_read = 0; - } - } - else - { - ret = false; - } - return ret; -} - -// Retrieve the first mesg type in the queue -unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() -{ - return m_q[m_read].id; -} - -#ifdef _ANDROID_ -omx_vdec::ts_arr_list::ts_arr_list() -{ - //initialize timestamps array - memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); -} -omx_vdec::ts_arr_list::~ts_arr_list() -{ - //free m_ts_arr_list? -} - -bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) -{ - bool ret = true; - bool duplicate_ts = false; - int idx = 0; - - //insert at the first available empty location - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - if (!m_ts_arr_list[idx].valid) - { - //found invalid or empty entry, save timestamp - m_ts_arr_list[idx].valid = true; - m_ts_arr_list[idx].timestamp = ts; - DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", - ts, idx); - break; - } - } - - if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) - { - DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); - ret = false; - } - return ret; -} - -bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) -{ - bool ret = true; - int min_idx = -1; - OMX_TICKS min_ts = 0; - int idx = 0; - - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - - if (m_ts_arr_list[idx].valid) - { - //found valid entry, save index - if (min_idx < 0) - { - //first valid entry - min_ts = m_ts_arr_list[idx].timestamp; - min_idx = idx; - } - else if (m_ts_arr_list[idx].timestamp < min_ts) - { - min_ts = m_ts_arr_list[idx].timestamp; - min_idx = idx; - } - } - - } - - if (min_idx < 0) - { - //no valid entries found - DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); - ts = 0; - ret = false; - } - else - { - ts = m_ts_arr_list[min_idx].timestamp; - m_ts_arr_list[min_idx].valid = false; - DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", - ts, min_idx); - } - - return ret; - -} - - -bool omx_vdec::ts_arr_list::reset_ts_list() -{ - bool ret = true; - int idx = 0; - - DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - m_ts_arr_list[idx].valid = false; - } - return ret; -} -#endif - -// factory function executed by the core to create instances -void *get_omx_component_factory_fn(void) -{ - return (new omx_vdec); -} - -#ifdef _ANDROID_ -#ifdef USE_ION -VideoHeap::VideoHeap(int devicefd, size_t size, void* base, - struct ion_handle *handle, int ionMapfd) -{ - m_ion_device_fd = devicefd; - m_ion_handle = handle; - MemoryHeapBase::init(ionMapfd, base, size, 0, MEM_DEVICE); - //ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); -} -#else -VideoHeap::VideoHeap(int fd, size_t size, void* base) -{ - // dup file descriptor, map once, use pmem - init(dup(fd), base, size, 0 , MEM_DEVICE); -} -#endif -#endif // _ANDROID_ -/* ====================================================================== -FUNCTION - omx_vdec::omx_vdec - -DESCRIPTION - Constructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_vdec::omx_vdec(): m_state(OMX_StateInvalid), - m_app_data(NULL), - m_inp_mem_ptr(NULL), - m_out_mem_ptr(NULL), - m_phdr_pmem_ptr(NULL), - pending_input_buffers(0), - pending_output_buffers(0), - m_out_bm_count(0), - m_inp_bm_count(0), - m_inp_bPopulated(OMX_FALSE), - m_out_bPopulated(OMX_FALSE), - m_flags(0), - m_inp_bEnabled(OMX_TRUE), - m_out_bEnabled(OMX_TRUE), - m_platform_list(NULL), - m_platform_entry(NULL), - m_pmem_info(NULL), - output_flush_progress (false), - input_flush_progress (false), - input_use_buffer (false), - output_use_buffer (false), - arbitrary_bytes (true), - psource_frame (NULL), - pdest_frame (NULL), - m_inp_heap_ptr (NULL), - m_heap_inp_bm_count (0), - codec_type_parse ((codec_type)0), - first_frame_meta (true), - frame_count (0), - nal_length(0), - nal_count (0), - look_ahead_nal (false), - first_frame(0), - first_buffer(NULL), - first_frame_size (0), - m_error_propogated(false), - m_device_file_ptr(NULL), - m_vc1_profile((vc1_profile_type)0), - prev_ts(LLONG_MAX), - rst_prev_ts(true), - frm_int(0), - m_in_alloc_cnt(0), - m_display_id(NULL), - ouput_egl_buffers(false), - h264_parser(NULL), - client_extradata(0), - h264_last_au_ts(LLONG_MAX), - h264_last_au_flags(0), - m_inp_err_count(0), - m_disp_hor_size(0), - m_disp_vert_size(0), -#ifdef _ANDROID_ - m_heap_ptr(NULL), - m_heap_count(0), - m_enable_android_native_buffers(OMX_FALSE), - m_use_android_native_buffers(OMX_FALSE), -#endif - in_reconfig(false), - m_use_output_pmem(OMX_FALSE), - m_out_mem_region_smi(OMX_FALSE), - m_out_pvt_entry_pmem(OMX_FALSE), - secure_mode(false), - external_meta_buffer(false), - external_meta_buffer_iommu(false) -#ifdef _ANDROID_ - ,iDivXDrmDecrypt(NULL) -#endif - ,m_desc_buffer_ptr(NULL) - ,m_extradata(NULL) - ,m_power_hinted(false) -{ - /* Assumption is that , to begin with , we have all the frames with decoder */ - DEBUG_PRINT_HIGH("In OMX vdec Constructor"); -#ifdef _ANDROID_ - char property_value[PROPERTY_VALUE_MAX] = {0}; - property_get("vidc.dec.debug.perf", property_value, "0"); - perf_flag = atoi(property_value); - if (perf_flag) - { - DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); - dec_time.start(); - proc_frms = latency = 0; - } - property_value[0] = NULL; - property_get("vidc.dec.debug.ts", property_value, "0"); - m_debug_timestamp = atoi(property_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); - if (m_debug_timestamp) - { - time_stamp_dts.set_timestamp_reorder_mode(true); - time_stamp_dts.enable_debug_print(true); - } - - property_value[0] = NULL; - property_get("vidc.dec.debug.concealedmb", property_value, "0"); - m_debug_concealedmb = atoi(property_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); - -#endif - memset(&m_cmp,0,sizeof(m_cmp)); - memset(&m_cb,0,sizeof(m_cb)); - memset (&drv_ctx,0,sizeof(drv_ctx)); - memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); - memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); - memset(&op_buf_rcnfg, 0 ,sizeof(vdec_allocatorproperty)); - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - msg_thread_created = false; - async_thread_created = false; -#ifdef _ANDROID_ICS_ - memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); -#endif - drv_ctx.timestamp_adjust = false; - drv_ctx.video_driver_fd = -1; - m_vendor_config.pData = NULL; - pthread_mutex_init(&m_lock, NULL); - sem_init(&m_cmd_lock,0,0); -#ifdef _ANDROID_ - char extradata_value[PROPERTY_VALUE_MAX] = {0}; - property_get("vidc.dec.debug.extradata", extradata_value, "0"); - m_debug_extradata = atoi(extradata_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); -#endif - m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; - client_buffers.set_vdec_client(this); -} - - -/* ====================================================================== -FUNCTION - omx_vdec::~omx_vdec - -DESCRIPTION - Destructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_vdec::~omx_vdec() -{ - m_pmem_info = NULL; - DEBUG_PRINT_HIGH("In OMX vdec Destructor"); - if(m_pipe_in) close(m_pipe_in); - if(m_pipe_out) close(m_pipe_out); - m_pipe_in = -1; - m_pipe_out = -1; - if (msg_thread_created) - { - DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); - pthread_join(msg_thread_id,NULL); - } - if (async_thread_created) - { - DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); - pthread_join(async_thread_id,NULL); - } - DEBUG_PRINT_HIGH("Calling close() on Video Driver"); - close (drv_ctx.video_driver_fd); - drv_ctx.video_driver_fd = -1; - - pthread_mutex_destroy(&m_lock); - sem_destroy(&m_cmd_lock); -#ifdef _ANDROID_ - if (perf_flag) - { - DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); - dec_time.end(); - } -#endif /* _ANDROID_ */ - DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); -} - -/* ====================================================================== -FUNCTION - omx_vdec::OMXCntrlProcessMsgCb - -DESCRIPTION - IL Client callbacks are generated through this routine. The decoder - provides the thread context for this routine. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -void omx_vdec::process_event_cb(void *ctxt, unsigned char id) -{ - unsigned p1; // Parameter - 1 - unsigned p2; // Parameter - 2 - unsigned ident; - unsigned qsize=0; // qsize - omx_vdec *pThis = (omx_vdec *) ctxt; - - if(!pThis) - { - DEBUG_PRINT_ERROR("\n ERROR: %s()::Context is incorrect, bailing out", - __func__); - return; - } - - // Protect the shared queue data structure - do - { - /*Read the message id's from the queue*/ - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if(qsize) - { - pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); - } - - if (qsize == 0 && pThis->m_state != OMX_StatePause) - { - qsize = pThis->m_ftb_q.m_size; - if (qsize) - { - pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); - } - } - - if (qsize == 0 && pThis->m_state != OMX_StatePause) - { - qsize = pThis->m_etb_q.m_size; - if (qsize) - { - pThis->m_etb_q.pop_entry(&p1,&p2,&ident); - } - } - pthread_mutex_unlock(&pThis->m_lock); - - /*process message if we have one*/ - if(qsize > 0) - { - id = ident; - switch (id) - { - case OMX_COMPONENT_GENERATE_EVENT: - if (pThis->m_cb.EventHandler) - { - switch (p1) - { - case OMX_CommandStateSet: - pThis->m_state = (OMX_STATETYPE) p2; - DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d", - pThis->m_state); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL); - break; - - case OMX_EventError: - if(p2 == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); - pThis->m_state = (OMX_STATETYPE) p2; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError, OMX_ErrorInvalidState, p2, NULL); - } - else if (p2 == OMX_ErrorHardware) - { - pThis->omx_report_error(); - } - else - { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError, p2, NULL, NULL ); - } - break; - - case OMX_CommandPortDisable: - DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2); - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) - { - BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); - break; - } - if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig) - { - pThis->in_reconfig = false; - pThis->drv_ctx.op_buf = pThis->op_buf_rcnfg; - OMX_ERRORTYPE eRet = pThis->set_buffer_req(&pThis->drv_ctx.op_buf); - if(eRet != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); - pThis->omx_report_error(); - break; - } - } - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - case OMX_CommandPortEnable: - DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - default: - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - } - } - else - { - DEBUG_PRINT_ERROR("\n ERROR: %s()::EventHandler is NULL", __func__); - } - break; - case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: - if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); - pThis->omx_report_error (); - } - break; - case OMX_COMPONENT_GENERATE_ETB: - if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FTB: - if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_COMMAND: - pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ - (OMX_U32)p2,(OMX_PTR)NULL); - break; - - case OMX_COMPONENT_GENERATE_EBD: - - if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); - pThis->omx_report_error (); - } - else - { - if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) - { - pThis->m_inp_err_count++; - pThis->time_stamp_dts.remove_time_stamp( - ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, - (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - } - else - { - pThis->m_inp_err_count = 0; - } - if ( pThis->empty_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); - pThis->omx_report_error (); - } - if(!pThis->arbitrary_bytes && pThis->m_inp_err_count > MAX_INPUT_ERROR) - { - DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); - pThis->omx_report_error (); - } - } - break; - case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: - { - int64_t *timestamp = (int64_t *)p1; - if (p1) - { - pThis->time_stamp_dts.remove_time_stamp(*timestamp, - (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - free(timestamp); - } - } - break; - case OMX_COMPONENT_GENERATE_FBD: - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); - pThis->omx_report_error (); - } - else if ( pThis->fill_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: - DEBUG_PRINT_HIGH("Driver flush i/p Port complete"); - if (!pThis->input_flush_progress) - { - DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); - } - else - { - pThis->execute_input_flush(); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); - pThis->omx_report_error (); - } - else - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_INPUT_FLUSH_PENDING)) - { - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); - DEBUG_PRINT_LOW("Input Flush completed - Notify Client"); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - OMX_CORE_INPUT_PORT_INDEX,NULL ); - } - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_IDLE_PENDING)) - { - if (!pThis->output_flush_progress) - { - DEBUG_PRINT_LOW("Output flush done hence issue stop"); - if (ioctl (pThis->drv_ctx.video_driver_fd, - VDEC_IOCTL_CMD_STOP,NULL ) < 0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); - pThis->omx_report_error (); - } - } - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: - DEBUG_PRINT_HIGH("Driver flush o/p Port complete"); - if (!pThis->output_flush_progress) - { - DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); - } - else - { - pThis->execute_output_flush(); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); - pThis->omx_report_error (); - } - else - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) - { - DEBUG_PRINT_LOW("Notify Output Flush done"); - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - OMX_CORE_OUTPUT_PORT_INDEX,NULL ); - } - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) - { - DEBUG_PRINT_LOW("Internal flush complete"); - BITMASK_CLEAR (&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) - { - pThis->post_event(OMX_CommandPortDisable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - BITMASK_CLEAR (&pThis->m_flags, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); - - } - } - - if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) - { - if (!pThis->input_flush_progress) - { - DEBUG_PRINT_LOW("Input flush done hence issue stop"); - if (ioctl (pThis->drv_ctx.video_driver_fd, - VDEC_IOCTL_CMD_STOP,NULL ) < 0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed"); - pThis->omx_report_error (); - } - } - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_START_DONE: - DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE"); - - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); - pThis->omx_report_error (); - } - else - { - DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success"); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("Move to executing"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting, NULL); - } - else if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_PAUSE_PENDING)) - { - if (ioctl (pThis->drv_ctx.video_driver_fd, - VDEC_IOCTL_CMD_PAUSE,NULL ) < 0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); - pThis->omx_report_error (); - } - } - } - } - else - { - DEBUG_PRINT_ERROR("\n Event Handler callback is NULL"); - } - break; - - case OMX_COMPONENT_GENERATE_PAUSE_DONE: - DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); - pThis->omx_report_error (); - } - else - { - pThis->complete_pending_buffer_done_cbs(); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) - { - DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); - //Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); - pThis->m_state = OMX_StatePause; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StatePause, NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_RESUME_DONE: - DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); - pThis->omx_report_error (); - } - else - { - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("Moving the decoder to execute state"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting,NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_STOP_DONE: - DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); - pThis->omx_report_error (); - } - else - { - pThis->complete_pending_buffer_done_cbs(); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); - pThis->m_state = OMX_StateIdle; - DEBUG_PRINT_LOW("Move to Idle State"); - pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateIdle,NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_PORT_RECONFIG: - DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); - if (pThis->start_port_reconfig() != OMX_ErrorNone) - pThis->omx_report_error(); - else - { - if (pThis->in_reconfig) - { - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventPortSettingsChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - { - OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; - OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; - if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) - format = OMX_InterlaceInterleaveFrameTopFieldFirst; - else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) - format = OMX_InterlaceInterleaveFrameBottomFieldFirst; - else //unsupported interlace format; raise a error - event = OMX_EventError; - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - event, format, 0, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - } - break; - - case OMX_COMPONENT_GENERATE_EOS_DONE: - DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, - OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - pThis->prev_ts = LLONG_MAX; - pThis->rst_prev_ts = true; - break; - - case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); - pThis->omx_report_error (); - break; - case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: - { - DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - //update power HAL with new width, height and bitrate - pThis->power_module_deregister(); - pThis->power_module_register(); - } - default: - break; - } - } - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if (pThis->m_state != OMX_StatePause) - qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); - pthread_mutex_unlock(&pThis->m_lock); - } - while(qsize>0); - -} - - - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentInit - -DESCRIPTION - Initialize the component. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - unsigned int alignment = 0,buffer_size = 0; - int is_secure = 0; - int i = 0; - int fds[2]; - int r; - OMX_STRING device_name = "/dev/msm_vidc_dec"; - -#ifndef JB_MR1 - sp sm; - sp hwcBinder = NULL; -#endif - if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){ - secure_mode = true; - arbitrary_bytes = false; - role = "OMX.qcom.video.decoder.avc"; - device_name = "/dev/msm_vidc_dec_sec"; - is_secure = 1; - } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",OMX_MAX_STRINGNAME_SIZE)){ - secure_mode = true; - arbitrary_bytes = false; - role = "OMX.qcom.video.decoder.mpeg2"; - device_name = "/dev/msm_vidc_dec_sec"; - is_secure = 1; - } -#ifndef JB_MR1 - if (secure_mode) { - sm = defaultServiceManager(); - hwcBinder = - interface_cast(sm->getService(String16("display.hwcservice"))); - if (hwcBinder != NULL) { - hwcBinder->setOpenSecureStart(); - } else { - DEBUG_PRINT_HIGH("Failed to get ref to hwcBinder, " - "cannot call secure display start"); - } - } -#endif - DEBUG_PRINT_HIGH("omx_vdec::component_init(): Start of New Playback : role = %s : DEVICE = %s", - role, device_name); - - drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); - - DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d, errno %d", - drv_ctx.video_driver_fd, errno); - - if(drv_ctx.video_driver_fd == 0){ - drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); - } - - if(is_secure && drv_ctx.video_driver_fd < 0) { - do { - usleep(100 * 1000); - drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK); - if (drv_ctx.video_driver_fd > 0) { - break; - } - } while(i++ < 50); - } - if(drv_ctx.video_driver_fd < 0) - { - DEBUG_PRINT_ERROR("\n Omx_vdec::Comp Init Returning failure, errno %d", errno); - return OMX_ErrorInsufficientResources; - } - drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; - drv_ctx.frame_rate.fps_denominator = 1; - - -#ifdef INPUT_BUFFER_LOG - strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); -#endif -#ifdef OUTPUT_BUFFER_LOG - outputBufferFile1 = fopen (outputfilename, "ab"); -#endif -#ifdef OUTPUT_EXTRADATA_LOG - outputExtradataFile = fopen (ouputextradatafilename, "ab"); -#endif - - // Copy the role information which provides the decoder kind - strlcpy(drv_ctx.kind,role,128); - if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE); - drv_ctx.timestamp_adjust = true; - drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; - eCompressionFormat = OMX_VIDEO_CodingMPEG4; - /*Initialize Start Code for MPEG4*/ - codec_type_parse = CODEC_TYPE_MPEG4; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "m4v"); -#endif - } - else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ - OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; - eCompressionFormat = OMX_VIDEO_CodingMPEG2; - /*Initialize Start Code for MPEG2*/ - codec_type_parse = CODEC_TYPE_MPEG2; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "mpg"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("H263 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_H263; - eCompressionFormat = OMX_VIDEO_CodingH263; - codec_type_parse = CODEC_TYPE_H263; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "263"); -#endif - } -#ifdef MAX_RES_1080P - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW ("DIVX 311 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef _ANDROID_ - OMX_ERRORTYPE err = createDivxDrmContext(); - if( err != OMX_ErrorNone ) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - eRet = err; - goto cleanup; - } -#endif //_ANDROID_ - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef _ANDROID_ - OMX_ERRORTYPE err = createDivxDrmContext(); - if( err != OMX_ErrorNone ) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - eRet = err; - goto cleanup; - } -#endif //_ANDROID_ - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef _ANDROID_ - OMX_ERRORTYPE err = createDivxDrmContext(); - if( err != OMX_ErrorNone ) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - eRet = err; - goto cleanup; - } -#endif //_ANDROID_ - } -#else - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ - OMX_MAX_STRINGNAME_SIZE)) || (!strncmp(drv_ctx.kind, \ - "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE))) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_ERROR ("DIVX Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_5; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - m_frame_parser.init_start_codes (codec_type_parse); - -#ifdef _ANDROID_ - OMX_ERRORTYPE err = createDivxDrmContext(); - if( err != OMX_ErrorNone ) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - eRet = err; - goto cleanup; - } -#endif //_ANDROID_ - } -#endif - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_H264; - eCompressionFormat = OMX_VIDEO_CodingAVC; - codec_type_parse = CODEC_TYPE_H264; - m_frame_parser.init_start_codes (codec_type_parse); - m_frame_parser.init_nal_length(nal_length); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "264"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; - eCompressionFormat = OMX_VIDEO_CodingWMV; - codec_type_parse = CODEC_TYPE_VC1; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "vc1"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; - eCompressionFormat = OMX_VIDEO_CodingWMV; - codec_type_parse = CODEC_TYPE_VC1; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "vc1"); -#endif - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } -#ifdef INPUT_BUFFER_LOG - inputBufferFile1 = fopen (inputfilename, "ab"); -#endif - if (eRet == OMX_ErrorNone) - { -#ifdef MAX_RES_720P - drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; - -#endif -#ifdef MAX_RES_1080P - drv_ctx.output_format = VDEC_YUV_FORMAT_TILE_4x2; - OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; - if (!client_buffers.set_color_format(dest_color_format)) { - DEBUG_PRINT_ERROR("\n Setting color format failed"); - eRet = OMX_ErrorInsufficientResources; - } -#endif - /*Initialize Decoder with codec type and resolution*/ - ioctl_msg.in = &drv_ctx.decoder_format; - ioctl_msg.out = NULL; - - if ( (eRet == OMX_ErrorNone) && - ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_CODEC, - (void*)&ioctl_msg) < 0) - - { - DEBUG_PRINT_ERROR("\n Set codec type failed"); - eRet = OMX_ErrorInsufficientResources; - } - - /*Set the output format*/ - ioctl_msg.in = &drv_ctx.output_format; - ioctl_msg.out = NULL; - - if ( (eRet == OMX_ErrorNone) && - ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set output format failed"); - eRet = OMX_ErrorInsufficientResources; - } - -#ifdef MAX_RES_720P - drv_ctx.video_resolution.frame_height = - drv_ctx.video_resolution.scan_lines = 720; - drv_ctx.video_resolution.frame_width = - drv_ctx.video_resolution.stride = 1280; -#endif -#ifdef MAX_RES_1080P - drv_ctx.video_resolution.frame_height = - drv_ctx.video_resolution.scan_lines = 1088; - drv_ctx.video_resolution.frame_width = - drv_ctx.video_resolution.stride = 1920; -#endif - - ioctl_msg.in = &drv_ctx.video_resolution; - ioctl_msg.out = NULL; - - if ( (eRet == OMX_ErrorNone) && - ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_PICRES, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set Resolution failed"); - eRet = OMX_ErrorInsufficientResources; - } - - /*Get the Buffer requirements for input and output ports*/ - drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; - drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; - drv_ctx.extradata = 0; - drv_ctx.picture_order = VDEC_ORDER_DISPLAY; - drv_ctx.idr_only_decoding = 0; - - if (eRet == OMX_ErrorNone) - eRet = get_buffer_req(&drv_ctx.ip_buf); - if (eRet == OMX_ErrorNone) - eRet = get_buffer_req(&drv_ctx.op_buf); - m_state = OMX_StateLoaded; -#ifdef DEFAULT_EXTRADATA - if (eRet == OMX_ErrorNone) - eRet = enable_extradata(DEFAULT_EXTRADATA); -#endif - if ( (codec_type_parse == CODEC_TYPE_VC1) || - (codec_type_parse == CODEC_TYPE_H264)) //add CP check here - { - //Check if dmx can be disabled - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - ioctl_msg.out = &drv_ctx.disable_dmx; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT, &ioctl_msg)) - { - DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT"); - eRet = OMX_ErrorHardware; - } - else - { - if (drv_ctx.disable_dmx && !secure_mode) - { - DEBUG_PRINT_HIGH("DMX disable is supported"); - - int rc = ioctl(drv_ctx.video_driver_fd, - VDEC_IOCTL_SET_DISABLE_DMX); - if(rc < 0) { - DEBUG_PRINT_ERROR("Failed to disable dmx on driver."); - drv_ctx.disable_dmx = false; - eRet = OMX_ErrorHardware; - } - } - else { - drv_ctx.disable_dmx = false; - } - } - } - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - if (m_frame_parser.mutils == NULL) - { - m_frame_parser.mutils = new H264_Utils(); - - if (m_frame_parser.mutils == NULL) - { - DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); - eRet = OMX_ErrorInsufficientResources; - } - else - { - h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; - h264_scratch.pBuffer = (OMX_U8 *)malloc (h264_scratch.nAllocLen); - h264_scratch.nFilledLen = 0; - h264_scratch.nOffset = 0; - - if (h264_scratch.pBuffer == NULL) - { - DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); - return OMX_ErrorInsufficientResources; - } - m_frame_parser.mutils->initialize_frame_checking_environment(); - m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); - } - } - - h264_parser = new h264_stream_parser(); - if (!h264_parser) - { - DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); - eRet = OMX_ErrorInsufficientResources; - } - } - - if(pipe(fds)) - { - DEBUG_PRINT_ERROR("\n pipe creation failed."); - eRet = OMX_ErrorInsufficientResources; - } - else - { - int temp1[2]; - if(fds[0] == 0 || fds[1] == 0) - { - if (pipe (temp1)) - { - DEBUG_PRINT_ERROR("\n pipe creation failed.."); - return OMX_ErrorInsufficientResources; - } - //close (fds[0]); - //close (fds[1]); - fds[0] = temp1 [0]; - fds[1] = temp1 [1]; - } - m_pipe_in = fds[0]; - m_pipe_out = fds[1]; - r = pthread_create(&msg_thread_id,0,message_thread,this); - if(r < 0) - { - DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - msg_thread_created = true; - r = pthread_create(&async_thread_id,0,async_message_thread,this); - if(r < 0) - { - DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - async_thread_created = true; - } - } - } - } - - if (eRet != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Component Init Failed"); - DEBUG_PRINT_HIGH("Calling VDEC_IOCTL_STOP_NEXT_MSG"); - (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, - NULL); - } - else - { - DEBUG_PRINT_HIGH("omx_vdec::component_init() success"); - } - - memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); - memset(&meta_buff,0,sizeof(struct meta_buffer)); -cleanup: - if (!secure_mode) { - return eRet; - } -#ifndef JB_MR1 - if (hwcBinder != NULL) { - (eRet == OMX_ErrorNone) ? - hwcBinder->setOpenSecureEnd() : - hwcBinder->setCloseSecureEnd(); - } else { - DEBUG_PRINT_HIGH("hwcBinder not found, " - "not calling secure end"); - } -#endif - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetComponentVersion - -DESCRIPTION - Returns the component version. - -PARAMETERS - TBD. - -RETURN VALUE - OMX_ErrorNone. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_component_version - ( - OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STRING componentName, - OMX_OUT OMX_VERSIONTYPE* componentVersion, - OMX_OUT OMX_VERSIONTYPE* specVersion, - OMX_OUT OMX_UUIDTYPE* componentUUID - ) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n Get Comp Version in Invalid State"); - return OMX_ErrorInvalidState; - } - /* TBD -- Return the proper version */ - if (specVersion) - { - specVersion->nVersion = OMX_SPEC_VERSION; - } - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_vdec::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - DEBUG_PRINT_HIGH("send_command: Recieved a Command from Client"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n ERROR: Send Command in Invalid State"); - return OMX_ErrorInvalidState; - } - if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX - && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) - { - DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush " - "to invalid port: %d", param1); - return OMX_ErrorBadPortIndex; - } - post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); - sem_wait(&m_cmd_lock); - DEBUG_PRINT_HIGH("send_command: Command Processed"); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_STATETYPE eState = (OMX_STATETYPE) param1; - int bFlag = 1,sem_posted = 0; - - DEBUG_PRINT_HIGH("send_command_proxy(): cmd = %d, Current State %d, Expected State %d", - cmd, m_state, eState); - - if(cmd == OMX_CommandStateSet) - { - DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued"); - DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState); - /***************************/ - /* Current State is Loaded */ - /***************************/ - if(m_state == OMX_StateLoaded) - { - if(eState == OMX_StateIdle) - { - //if all buffers are allocated or all ports disabled - if(allocate_done() || - (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) - { - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle"); - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending"); - BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Loaded to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\n ERROR::send_command_proxy(): Loaded-->Loaded"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Loaded to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources"); - } - /* Requesting transition from Loaded to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ - eState); - eRet = OMX_ErrorBadParameter; - } - } - - /***************************/ - /* Current State is IDLE */ - /***************************/ - else if(m_state == OMX_StateIdle) - { - if(eState == OMX_StateLoaded) - { - if(release_done()) - { - /* - Since error is None , we will post an event at the end - of this function definition - */ - DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Loaded"); - } - else - { - DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Loaded-Pending"); - BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Idle to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Executing"); - BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); - bFlag = 0; - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, - NULL) < 0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } else { - power_module_register(); - } - } - /* Requesting transition from Idle to Idle */ - else if(eState == OMX_StateIdle) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Idle to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Idle to Pause */ - else if(eState == OMX_StatePause) - { - /*To pause the Video core we need to start the driver*/ - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, - NULL) < 0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); - DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Pause"); - bFlag = 0; - } - } - /* Requesting transition from Idle to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - - /******************************/ - /* Current State is Executing */ - /******************************/ - else if(m_state == OMX_StateExecuting) - { - DEBUG_PRINT_HIGH("Command Recieved in OMX_StateExecuting"); - /* Requesting transition from Executing to Idle */ - if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition - */ - DEBUG_PRINT_HIGH("send_command_proxy(): Executing --> Idle"); - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - execute_omx_flush(OMX_ALL); - } - bFlag = 0; - } - /* Requesting transition from Executing to Paused */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_HIGH("PAUSE Command Issued"); - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_PAUSE, - NULL) < 0) - { - DEBUG_PRINT_ERROR("\n Error In Pause State"); - post_event(OMX_EventError,OMX_ErrorHardware,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); - DEBUG_PRINT_HIGH("send_command_proxy(): Executing-->Pause"); - bFlag = 0; - } - } - /* Requesting transition from Executing to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Executing to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is Pause */ - /***************************/ - else if(m_state == OMX_StatePause) - { - /* Requesting transition from Pause to Executing */ - if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_HIGH("Pause --> Executing"); - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_RESUME, - NULL) < 0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed"); - post_event(OMX_EventError,OMX_ErrorHardware,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); - DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Executing"); - post_event (NULL,VDEC_S_SUCCESS,\ - OMX_COMPONENT_GENERATE_RESUME_DONE); - bFlag = 0; - } - } - /* Requesting transition from Pause to Idle */ - else if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_HIGH("Pause --> Idle.."); - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - execute_omx_flush(OMX_ALL); - } - bFlag = 0; - } - /* Requesting transition from Pause to loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Pause to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is WaitForResources */ - /***************************/ - else if(m_state == OMX_StateWaitForResources) - { - /* Requesting transition from WaitForResources to Loaded */ - if(eState == OMX_StateLoaded) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_HIGH("send_command_proxy(): WaitForResources-->Loaded"); - } - /* Requesting transition from WaitForResources to WaitForResources */ - else if (eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorSameState, - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from WaitForResources to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - /* Requesting transition from WaitForResources to Loaded - - is NOT tested by Khronos TS */ - - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); - eRet = OMX_ErrorBadParameter; - } - } - /********************************/ - /* Current State is Invalid */ - /*******************************/ - else if(m_state == OMX_StateInvalid) - { - /* State Transition from Inavlid to any state */ - if(eState == (OMX_StateLoaded || OMX_StateWaitForResources - || OMX_StateIdle || OMX_StateExecuting - || OMX_StatePause || OMX_StateInvalid)) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); - post_event(OMX_EventError,OMX_ErrorInvalidState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - } - else if (cmd == OMX_CommandFlush) - { - DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued " - "with param1: %d", param1); - if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); - } - if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) - { - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - } - if (!sem_posted){ - sem_posted = 1; - DEBUG_PRINT_LOW("Set the Semaphore"); - sem_post (&m_cmd_lock); - execute_omx_flush(param1); - } - bFlag = 0; - } - else if ( cmd == OMX_CommandPortEnable) - { - DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued " - "with param1: %d", param1); - if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_inp_bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || allocate_input_done()) - { - post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - DEBUG_PRINT_HIGH("send_command_proxy(): Disabled-->Enabled Pending"); - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) - { - DEBUG_PRINT_HIGH("Enable output Port command recieved"); - m_out_bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || (allocate_output_done())) - { - post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - - } - else - { - DEBUG_PRINT_HIGH("send_command_proxy(): Disabled-->Enabled Pending"); - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - } - else if (cmd == OMX_CommandPortDisable) - { - DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued " - "with param1: %d", param1); - if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_inp_bEnabled = OMX_FALSE; - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_input_done()) - { - post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - } - execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); - } - - // Skip the event notification - bFlag = 0; - } - } - if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_out_bEnabled = OMX_FALSE; - DEBUG_PRINT_HIGH("Disable output Port command recieved"); - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_output_done()) - { - post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - if (!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - } - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); - execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); - } - // Skip the event notification - bFlag = 0; - - } - } - } - else - { - DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); - eRet = OMX_ErrorNotImplemented; - } - if(eRet == OMX_ErrorNone && bFlag) - { - post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); - } - if(!sem_posted) - { - sem_post(&m_cmd_lock); - } - - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ExecuteOmxFlush - -DESCRIPTION - Executes the OMX flush. - -PARAMETERS - flushtype - input flush(1)/output flush(0)/ both. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_vdec::execute_omx_flush(OMX_U32 flushType) -{ - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - enum vdec_bufferflush flush_dir; - bool bRet = false; - switch (flushType) - { - case OMX_CORE_INPUT_PORT_INDEX: - input_flush_progress = true; - flush_dir = VDEC_FLUSH_TYPE_INPUT; - break; - case OMX_CORE_OUTPUT_PORT_INDEX: - output_flush_progress = true; - flush_dir = VDEC_FLUSH_TYPE_OUTPUT; - break; - default: - input_flush_progress = true; - output_flush_progress = true; - flush_dir = VDEC_FLUSH_TYPE_ALL; - } - ioctl_msg.in = &flush_dir; - ioctl_msg.out = NULL; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_CMD_FLUSH, &ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", (int)flush_dir); - bRet = false; - } - return bRet; -} -/*========================================================================= -FUNCTION : execute_output_flush - -DESCRIPTION - Executes the OMX flush at OUTPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_vdec::execute_output_flush() -{ - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate FBD for all Buffers in the FTBq*/ - pthread_mutex_lock(&m_lock); - DEBUG_PRINT_HIGH("Initiate Output Flush"); - while (m_ftb_q.m_size) - { - DEBUG_PRINT_HIGH("Buffer queue size %d pending buf cnt %d", - m_ftb_q.m_size,pending_output_buffers); - m_ftb_q.pop_entry(&p1,&p2,&ident); - DEBUG_PRINT_HIGH("ID(%x) P1(%x) P2(%x)", ident, p1, p2); - if(ident == m_fill_output_msg ) - { - m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); - } - else if (ident == OMX_COMPONENT_GENERATE_FBD) - { - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - pthread_mutex_unlock(&m_lock); - output_flush_progress = false; - - if (arbitrary_bytes) - { - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } - DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); - return bRet; -} -/*========================================================================= -FUNCTION : execute_input_flush - -DESCRIPTION - Executes the OMX flush at INPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_vdec::execute_input_flush() -{ - unsigned i =0; - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate EBD for all Buffers in the ETBq*/ - DEBUG_PRINT_HIGH("Initiate Input Flush"); - - pthread_mutex_lock(&m_lock); - DEBUG_PRINT_LOW("Check if the Queue is empty"); - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - - if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) - { - DEBUG_PRINT_HIGH("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); - m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_ETB) - { - pending_input_buffers++; - DEBUG_PRINT_HIGH("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", - (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if (ident == OMX_COMPONENT_GENERATE_EBD) - { - DEBUG_PRINT_HIGH("Flush Input OMX_COMPONENT_GENERATE_EBD %p", - (OMX_BUFFERHEADERTYPE *)p1); - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - time_stamp_dts.flush_timestamp(); - /*Check if Heap Buffers are to be flushed*/ - if (arbitrary_bytes && !(codec_config_flag)) - { - DEBUG_PRINT_HIGH("Reset all the variables before flusing"); - h264_scratch.nFilledLen = 0; - nal_count = 0; - look_ahead_nal = false; - frame_count = 0; - h264_last_au_ts = LLONG_MAX; - h264_last_au_flags = 0; - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - DEBUG_PRINT_HIGH("Initialize parser"); - if (m_frame_parser.mutils) - { - m_frame_parser.mutils->initialize_frame_checking_environment(); - } - - while (m_input_pending_q.m_size) - { - m_input_pending_q.pop_entry(&p1,&p2,&ident); - m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); - } - - if (psource_frame) - { - m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); - psource_frame = NULL; - } - - if (pdest_frame) - { - pdest_frame->nFilledLen = 0; - m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); - pdest_frame = NULL; - } - m_frame_parser.flush(); - } - else if (codec_config_flag) - { - DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " - "is not sent to the driver yet"); - } - pthread_mutex_unlock(&m_lock); - input_flush_progress = false; - if (!arbitrary_bytes) - { - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } -#ifdef _ANDROID_ - if (m_debug_timestamp) - { - m_timestamp_list.reset_ts_list(); - } -#endif - DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); - return bRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::SendCommandEvent - -DESCRIPTION - Send the event to decoder pipe. This is needed to generate the callbacks - in decoder thread context. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_vdec::post_event(unsigned int p1, - unsigned int p2, - unsigned int id) -{ - bool bRet = false; - - - pthread_mutex_lock(&m_lock); - - if (id == m_fill_output_msg || - id == OMX_COMPONENT_GENERATE_FBD) - { - m_ftb_q.insert_entry(p1,p2,id); - } - else if (id == OMX_COMPONENT_GENERATE_ETB || - id == OMX_COMPONENT_GENERATE_EBD || - id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) - { - m_etb_q.insert_entry(p1,p2,id); - } - else - { - m_cmd_q.insert_entry(p1,p2,id); - } - - bRet = true; - DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this); - post_message(this, id); - - pthread_mutex_unlock(&m_lock); - - return bRet; -} -#ifdef MAX_RES_720P -OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 0) { - if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else - { - DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - return eRet; -} -#endif -#ifdef MAX_RES_1080P -OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNoMore; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 0) { - if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else - { - DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; - profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore\n"); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - return eRet; -} -#endif - -/* ====================================================================== -FUNCTION - omx_vdec::GetParameter - -DESCRIPTION - OMX Get Parameter method implementation - -PARAMETERS - . - -RETURN VALUE - Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_INOUT OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - DEBUG_PRINT_LOW("get_parameter:"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("\n Get Param in Invalid paramData"); - return OMX_ErrorBadParameter; - } - switch(paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn = - (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - eRet = update_portdef(portDefn); - if (eRet == OMX_ErrorNone) - m_port_def = *portDefn; - DEBUG_PRINT_HIGH("Get_parameter: OMX_IndexParamPortDefinition: " - "nPortIndex (%d), nFrameWidth (%d), nFrameHeight (%d), " - "nStride (%d), nSliceHeight (%d), nBitrate (%d), xFramerate (0x%x), " - "nBufferSize (%d), nBufferCountMin (%d), nBufferCountActual (%d), " - "bBuffersContiguous (%d), nBufferAlignment (%d), " - "bEnabled (%d), bPopulated (%d), eCompressionFormat (0x%x), " - "eColorFormat (0x%x)" , (int)portDefn->nPortIndex, - (int)portDefn->format.video.nFrameWidth, (int)portDefn->format.video.nFrameHeight, - (int)portDefn->format.video.nStride, (int)portDefn->format.video.nSliceHeight, - (int)portDefn->format.video.nBitrate, (int)portDefn->format.video.xFramerate, - (int)portDefn->nBufferSize, (int)portDefn->nBufferCountMin, - (int)portDefn->nBufferCountActual, (int)portDefn->bBuffersContiguous, - (int)portDefn->nBufferAlignment, (int)portDefn->bEnabled, (int)portDefn->bPopulated, - (int)portDefn->format.video.eCompressionFormat, (int)portDefn->format.video.eColorFormat); - break; - } - case OMX_IndexParamVideoInit: - { - OMX_PORT_PARAM_TYPE *portParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); - - portParamType->nVersion.nVersion = OMX_SPEC_VERSION; - portParamType->nSize = sizeof(portParamType); - portParamType->nPorts = 2; - portParamType->nStartPortNumber = 0; - break; - } - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - portFmt->nVersion.nVersion = OMX_SPEC_VERSION; - portFmt->nSize = sizeof(portFmt); - - if (0 == portFmt->nPortIndex) - { - if (0 == portFmt->nIndex) - { - portFmt->eColorFormat = OMX_COLOR_FormatUnused; - portFmt->eCompressionFormat = eCompressionFormat; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ - " NoMore compression formats\n"); - eRet = OMX_ErrorNoMore; - } - } - else if (1 == portFmt->nPortIndex) - { - portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; - if(0 == portFmt->nIndex) - portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; - else if (1 == portFmt->nIndex) - { - portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ - " NoMore Color formats\n"); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", - (int)portFmt->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_HIGH("Get_parameter: OMX_IndexParamVideoPortFormat: " - "nPortIndex (%d), nIndex (%d), eCompressionFormat (0x%x), " - "eColorFormat (0x%x), xFramerate (0x%x)", (int)portFmt->nPortIndex, - (int)portFmt->nIndex, (int)portFmt->eCompressionFormat, - (int)portFmt->eColorFormat, (int)portFmt->xFramerate); - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamAudioInit: - { - OMX_PORT_PARAM_TYPE *audioPortParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); - audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; - audioPortParamType->nSize = sizeof(audioPortParamType); - audioPortParamType->nPorts = 0; - audioPortParamType->nStartPortNumber = 0; - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamImageInit: - { - OMX_PORT_PARAM_TYPE *imagePortParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); - imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; - imagePortParamType->nSize = sizeof(imagePortParamType); - imagePortParamType->nPorts = 0; - imagePortParamType->nStartPortNumber = 0; - break; - - } - /*Component should support this port definition*/ - case OMX_IndexParamOtherInit: - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", - paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - break; - } - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - comp_role->nVersion.nVersion = OMX_SPEC_VERSION; - comp_role->nSize = sizeof(*comp_role); - - DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", - paramIndex); - strlcpy((char*)comp_role->cRole,(const char*)m_cRole, - OMX_MAX_STRINGNAME_SIZE); - break; - } - /* Added for parameter test */ - case OMX_IndexParamPriorityMgmt: - { - - OMX_PRIORITYMGMTTYPE *priorityMgmType = - (OMX_PRIORITYMGMTTYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); - priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; - priorityMgmType->nSize = sizeof(priorityMgmType); - - break; - } - /* Added for parameter test */ - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = - (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); - - bufferSupplierType->nSize = sizeof(bufferSupplierType); - bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; - if(0 == bufferSupplierType->nPortIndex) - bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; - else if (1 == bufferSupplierType->nPortIndex) - bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; - else - eRet = OMX_ErrorBadPortIndex; - - - break; - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoH263: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg4: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg2: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex); - OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = - (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; -#ifdef MAX_RES_720P - eRet = get_supported_profile_level_for_720p(profileLevelType); -#endif -#ifdef MAX_RES_1080P - eRet = get_supported_profile_level_for_1080p(profileLevelType); -#endif - break; - } -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: - { - DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage"); - GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; - if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { -#ifdef USE_ION -#if defined (MAX_RES_720P) - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_CAMERA_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); - DEBUG_PRINT_HIGH("ION:720P: nUsage 0x%x",nativeBuffersUsage->nUsage); -#else - if(secure_mode) { - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | - GRALLOC_USAGE_PRIVATE_UNCACHED); - DEBUG_PRINT_HIGH("ION:secure_mode: nUsage 0x%x",nativeBuffersUsage->nUsage); - } else { - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | - GRALLOC_USAGE_PRIVATE_IOMMU_HEAP); - DEBUG_PRINT_HIGH("ION:non_secure_mode: nUsage 0x%x",nativeBuffersUsage->nUsage); - } -#endif //(MAX_RES_720P) -#else // USE_ION -#if defined (MAX_RES_720P) || defined (MAX_RES_1080P_EBI) - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); - DEBUG_PRINT_HIGH("720P/1080P_EBI: nUsage 0x%x",nativeBuffersUsage->nUsage); -#elif MAX_RES_1080P - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_SMI_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); - DEBUG_PRINT_HIGH("1080P: nUsage 0x%x",nativeBuffersUsage->nUsage); -#endif -#endif // USE_ION - } else { - DEBUG_PRINT_ERROR("\n get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!"); - eRet = OMX_ErrorBadParameter; - } - } - break; -#endif - - default: - { - DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - } - - } - - DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)", - drv_ctx.video_resolution.frame_width, - drv_ctx.video_resolution.frame_height, - drv_ctx.video_resolution.stride, - drv_ctx.video_resolution.scan_lines); - - return eRet; -} - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) -{ - DEBUG_PRINT_LOW("Inside use_android_native_buffer"); - OMX_ERRORTYPE eRet = OMX_ErrorNone; - UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; - - if((params == NULL) || - (params->nativeBuffer == NULL) || - (params->nativeBuffer->handle == NULL) || - !m_enable_android_native_buffers) - return OMX_ErrorBadParameter; - m_use_android_native_buffers = OMX_TRUE; - sp nBuf = params->nativeBuffer; - private_handle_t *handle = (private_handle_t *)nBuf->handle; - - if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { - DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," - " expected %u, got %lu", - drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); - return OMX_ErrorBadParameter; - } - - if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port - OMX_U8 *buffer = NULL; - if(!secure_mode) { - buffer = (OMX_U8*)mmap(0, handle->size, - PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); - if(buffer == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); - return OMX_ErrorInsufficientResources; - } - } - eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); - } else { - eRet = OMX_ErrorBadParameter; - } - return eRet; -} -#endif -/* ====================================================================== -FUNCTION - omx_vdec::Setparameter - -DESCRIPTION - OMX Set Parameter method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_IN OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - if((m_state != OMX_StateLoaded) && - BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && - (m_out_bEnabled == OMX_TRUE) && - BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && - (m_inp_bEnabled == OMX_TRUE)) { - DEBUG_PRINT_ERROR("Set Param in Invalid State \n"); - return OMX_ErrorIncorrectStateOperation; - } - - switch(paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has - //been called. - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d", - (int)portDefn->format.video.nFrameHeight, - (int)portDefn->format.video.nFrameWidth); - if(OMX_DirOutput == portDefn->eDir) - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port"); - m_display_id = portDefn->format.video.pNativeWindow; - unsigned int buffer_size; - if (!client_buffers.get_buffer_req(buffer_size)) { - DEBUG_PRINT_ERROR("\n Error in getting buffer requirements"); - eRet = OMX_ErrorBadParameter; - } else { - if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && - portDefn->nBufferSize >= buffer_size) - { - drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; - drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; - eRet = set_buffer_req(&drv_ctx.op_buf); - if (eRet == OMX_ErrorNone) - m_port_def = *portDefn; - } - else - { - DEBUG_PRINT_HIGH("ERROR: OP Requirements(#%d: %u) Requested(#%d: %u)\n", - drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, - portDefn->nBufferCountActual, portDefn->nBufferSize); - eRet = OMX_ErrorBadParameter; - } - } - } - else if(OMX_DirInput == portDefn->eDir) - { - if((portDefn->format.video.xFramerate >> 16) > 0 && - (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) - { - // Frame rate only should be set if this is a "known value" or to - // activate ts prediction logic (arbitrary mode only) sending input - // timestamps with max value (LLONG_MAX). - DEBUG_PRINT_LOW("set_parameter: frame rate set by omx client : %d", - portDefn->format.video.xFramerate >> 16); - Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, - drv_ctx.frame_rate.fps_denominator); - if(!drv_ctx.frame_rate.fps_numerator) - { - DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); - drv_ctx.frame_rate.fps_numerator = 30; - } - if(drv_ctx.frame_rate.fps_denominator) - drv_ctx.frame_rate.fps_numerator = (int) - drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; - drv_ctx.frame_rate.fps_denominator = 1; - frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / - drv_ctx.frame_rate.fps_numerator; - ioctl_msg.in = &drv_ctx.frame_rate; - if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Setting frame rate to driver failed"); - } - DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", - frm_int, drv_ctx.frame_rate.fps_numerator / - (float)drv_ctx.frame_rate.fps_denominator); - } - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port"); - if(drv_ctx.video_resolution.frame_height != - portDefn->format.video.nFrameHeight || - drv_ctx.video_resolution.frame_width != - portDefn->format.video.nFrameWidth) - { - DEBUG_PRINT_LOW("SetParam IP: WxH(%d x %d)", - portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight); - if (portDefn->format.video.nFrameHeight != 0x0 && - portDefn->format.video.nFrameWidth != 0x0) - { - drv_ctx.video_resolution.frame_height = - drv_ctx.video_resolution.scan_lines = - portDefn->format.video.nFrameHeight; - drv_ctx.video_resolution.frame_width = - drv_ctx.video_resolution.stride = - portDefn->format.video.nFrameWidth; - ioctl_msg.in = &drv_ctx.video_resolution; - ioctl_msg.out = NULL; - if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICRES, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set Resolution failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - else - eRet = get_buffer_req(&drv_ctx.op_buf); - } - } - else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount - && portDefn->nBufferSize == (drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH)) - { - drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; - drv_ctx.ip_buf.buffer_size = portDefn->nBufferSize + DEVICE_SCRATCH; - eRet = set_buffer_req(&drv_ctx.ip_buf); - } - else - { - DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%d: %u)\n", - drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, - portDefn->nBufferCountActual, portDefn->nBufferSize); - eRet = OMX_ErrorBadParameter; - } - } - else if (portDefn->eDir == OMX_DirMax) - { - DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_HIGH("Set_parameter: OMX_IndexParamPortDefinition: " - "nPortIndex (%d), nFrameWidth (%d), nFrameHeight (%d), " - "nStride (%d), nSliceHeight (%d), nBitrate (%d), xFramerate (0x%x), " - "nBufferSize (%d), nBufferCountMin (%d), nBufferCountActual (%d), " - "bBuffersContiguous (%d), nBufferAlignment (%d), " - "bEnabled (%d), bPopulated (%d), eCompressionFormat (0x%x), " - "eColorFormat (0x%x)" , (int)portDefn->nPortIndex, - (int)portDefn->format.video.nFrameWidth, (int)portDefn->format.video.nFrameHeight, - (int)portDefn->format.video.nStride, (int)portDefn->format.video.nSliceHeight, - (int)portDefn->format.video.nBitrate, (int)portDefn->format.video.xFramerate, - (int)portDefn->nBufferSize, (int)portDefn->nBufferCountMin, - (int)portDefn->nBufferCountActual, (int)portDefn->bBuffersContiguous, - (int)portDefn->nBufferAlignment, (int)portDefn->bEnabled, (int)portDefn->bPopulated, - (int)portDefn->format.video.eCompressionFormat, (int)portDefn->format.video.eColorFormat); - } - break; - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - if(1 == portFmt->nPortIndex) - { - enum vdec_output_fromat op_format; - if(portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) - op_format = VDEC_YUV_FORMAT_NV12; - else if(portFmt->eColorFormat == - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka || - portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar) - op_format = VDEC_YUV_FORMAT_TILE_4x2; - else - eRet = OMX_ErrorBadParameter; - - if(eRet == OMX_ErrorNone && drv_ctx.output_format != op_format) - { - /*Set the output format*/ - drv_ctx.output_format = op_format; - ioctl_msg.in = &drv_ctx.output_format; - ioctl_msg.out = NULL; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_OUTPUT_FORMAT, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set output format failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - else { - eRet = get_buffer_req(&drv_ctx.op_buf); - } - } - if (eRet == OMX_ErrorNone){ - if (!client_buffers.set_color_format(portFmt->eColorFormat)) { - DEBUG_PRINT_ERROR("\n Set color format failed"); - eRet = OMX_ErrorBadParameter; - } - } - } - DEBUG_PRINT_HIGH("Set_parameter: OMX_IndexParamVideoPortFormat: " - "nPortIndex (%d), nIndex (%d), eCompressionFormat (0x%x), " - "eColorFormat (0x%x), xFramerate (0x%x)", (int)portFmt->nPortIndex, - (int)portFmt->nIndex, (int)portFmt->eCompressionFormat, - (int)portFmt->eColorFormat, (int)portFmt->xFramerate); - } - break; - - case OMX_QcomIndexPortDefn: - { - OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = - (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d", - portFmt->nFramePackingFormat); - - /* Input port */ - if (portFmt->nPortIndex == 0) - { - if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) - { - if(secure_mode) { - arbitrary_bytes = false; - DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); - eRet = OMX_ErrorUnsupportedSetting; - } else { - arbitrary_bytes = true; - DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes enabled"); - } - } - else if (portFmt->nFramePackingFormat == - OMX_QCOM_FramePacking_OnlyOneCompleteFrame) - { - arbitrary_bytes = false; - DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes disabled"); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n", - portFmt->nFramePackingFormat); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port"); - if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && - portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && - portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) - { - m_out_mem_region_smi = OMX_TRUE; - if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: set use_output_pmem"); - m_use_output_pmem = OMX_TRUE; - } - } - } - } - break; - - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s", - comp_role->cRole); - - if((m_state == OMX_StateLoaded)&& - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("Set Parameter called in valid state"); - } - else - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } -#ifdef MAX_RES_1080P - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) - ) -#else - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) -#endif - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind); - eRet = OMX_ErrorInvalidComponentName; - } - break; - } - - case OMX_IndexParamPriorityMgmt: - { - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", - priorityMgmtype->nGroupID); - - DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", - priorityMgmtype->nGroupPriority); - - m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; - m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; - - break; - } - - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", - bufferSupplierType->eBufferSupplier); - if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) - m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; - - else - - eRet = OMX_ErrorBadPortIndex; - - break; - - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoH263: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg4: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg2: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n", - paramIndex); - break; - } - case OMX_QcomIndexParamVideoDecoderPictureOrder: - { - QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = - (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; - enum vdec_output_order pic_order = VDEC_ORDER_DISPLAY; - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n", - pictureOrder->eOutputPictureOrder); - if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) - pic_order = VDEC_ORDER_DISPLAY; - else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){ - pic_order = VDEC_ORDER_DECODE; - time_stamp_dts.set_timestamp_reorder_mode(false); - } - else - eRet = OMX_ErrorBadParameter; -#ifdef MAX_RES_720P - if (drv_ctx.idr_only_decoding) - { - if (pictureOrder->eOutputPictureOrder != QOMX_VIDEO_DECODE_ORDER) - { - DEBUG_PRINT_HIGH("only decode order is supported for thumbnail mode"); - eRet = OMX_ErrorBadParameter; - } - } -#endif - if (eRet == OMX_ErrorNone && pic_order != drv_ctx.picture_order) - { - drv_ctx.picture_order = pic_order; - ioctl_msg.in = &drv_ctx.picture_order; - ioctl_msg.out = NULL; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set picture order failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - } - break; - } - case OMX_QcomIndexParamConcealMBMapExtraData: - { - eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - } - break; - case OMX_QcomIndexParamFrameInfoExtraData: - { - eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - } - break; - case OMX_QcomIndexParamInterlaceExtraData: - { - eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - } - break; - case OMX_QcomIndexParamH264TimeInfo: - { - eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - } - break; - case OMX_QcomIndexParamVideoDivx: - { -#ifdef MAX_RES_720P - QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; - if((divXType) && (divXType->eFormat == QOMX_VIDEO_DIVXFormat311)) { - DEBUG_PRINT_HIGH("set_parameter: DivX 3.11 not supported in 7x30 core."); - eRet = OMX_ErrorUnsupportedSetting; - } -#endif - } - break; - case OMX_QcomIndexPlatformPvt: - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port"); - OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; - if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) - { - DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); - eRet = OMX_ErrorUnsupportedSetting; - } - else - { - m_out_pvt_entry_pmem = OMX_TRUE; - if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: use output pmem set"); - m_use_output_pmem = OMX_TRUE; - } - } - - } - break; - case OMX_QcomIndexParamVideoSyncFrameDecodingMode: - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); - DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); - drv_ctx.idr_only_decoding = 1; - int rc = ioctl(drv_ctx.video_driver_fd, - VDEC_IOCTL_SET_IDR_ONLY_DECODING); - if(rc < 0) { - DEBUG_PRINT_ERROR("Failed to set IDR only decoding on driver."); - eRet = OMX_ErrorHardware; - } -#ifdef MAX_RES_720P - if (eRet == OMX_ErrorNone) - { - DEBUG_PRINT_HIGH("set decode order for thumbnail mode"); - drv_ctx.picture_order = VDEC_ORDER_DECODE; - ioctl_msg.in = &drv_ctx.picture_order; - ioctl_msg.out = NULL; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set picture order failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - } -#endif - } - break; -#ifdef MAX_RES_1080P - case OMX_QcomIndexParamIndexExtraDataType: - { - if(!secure_mode) { - QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; - if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && - (extradataIndexType->bEnabled == OMX_TRUE) && - (extradataIndexType->nPortIndex == 1)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming"); - eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, extradataIndexType->bEnabled); - // Set smooth streaming parameter - int rc = ioctl(drv_ctx.video_driver_fd, - VDEC_IOCTL_SET_CONT_ON_RECONFIG); - if(rc < 0) { - DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); - eRet = OMX_ErrorHardware; - } - } - } - } - break; - - case OMX_QcomIndexParamEnableSmoothStreaming: - { - - int rc = ioctl(drv_ctx.video_driver_fd, - VDEC_IOCTL_SET_CONT_ON_RECONFIG); - if(rc < 0) { - DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); - eRet = OMX_ErrorHardware; - } - } - break; -#endif -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - /* Need to allow following two set_parameters even in Idle - * state. This is ANDROID architecture which is not in sync - * with openmax standard. */ - case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: - { - EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; - if(enableNativeBuffers) { - m_enable_android_native_buffers = enableNativeBuffers->enable; - } - } - break; - case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: - { - eRet = use_android_native_buffer(hComp, paramData); - } - break; -#endif - case OMX_QcomIndexParamEnableTimeStampReorder: - { - QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; - if (drv_ctx.picture_order == QOMX_VIDEO_DISPLAY_ORDER) { - if (reorder->bEnable == OMX_TRUE) { - frm_int =0; - time_stamp_dts.set_timestamp_reorder_mode(true); - } - else - time_stamp_dts.set_timestamp_reorder_mode(false); - } else { - time_stamp_dts.set_timestamp_reorder_mode(false); - if (reorder->bEnable == OMX_TRUE) - { - eRet = OMX_ErrorUnsupportedSetting; - } - } - } - break; - case OMX_QcomIndexEnableExtnUserData: - { - eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - } - break; - default: - { - DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); - eRet = OMX_ErrorUnsupportedIndex; - } - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetConfig - -DESCRIPTION - OMX Get Config Method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_INOUT OMX_PTR configData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - if (m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - switch (configIndex) - { - case OMX_QcomIndexConfigInterlaced: - { - OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = - (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; - if (configFmt->nPortIndex == 1) - { - if (configFmt->nIndex == 0) - { - configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; - } - else if (configFmt->nIndex == 1) - { - configFmt->eInterlaceType = - OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; - } - else if (configFmt->nIndex == 2) - { - configFmt->eInterlaceType = - OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; - } - else - { - DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" - " NoMore Interlaced formats\n"); - eRet = OMX_ErrorNoMore; - } - - } - else - { - DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", - (int)configFmt->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - case OMX_QcomIndexQueryNumberOfVideoDecInstance: - { - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = - (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; - ioctl_msg.out = (void*)&decoderinstances->nNumOfInstances; - (void)(ioctl(drv_ctx.video_driver_fd, - VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg)); - break; - } - case OMX_QcomIndexConfigVideoFramePackingArrangement: - { - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = - (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; - h264_parser->get_frame_pack_data(configFmt); - } - else - { - DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); - } - break; - } - case OMX_QcomIndexParamFrameInfoExtraData: - { - OMX_QCOM_EXTRADATA_FRAMEINFO *extradata = - (OMX_QCOM_EXTRADATA_FRAMEINFO *) configData; - - if(m_extradata == NULL){ - DEBUG_PRINT_LOW("get_config: m_extradata not set. " - "Aspect Ratio information missing!!"); - } - else { - extradata->aspectRatio.aspectRatioX = - m_extradata->aspectRatio.aspectRatioX; - extradata->aspectRatio.aspectRatioY = - m_extradata->aspectRatio.aspectRatioY; - } - break; - } - - default: - { - DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); - eRet = OMX_ErrorBadParameter; - } - - } - - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SetConfig - -DESCRIPTION - OMX Set Config method implementation - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_IN OMX_PTR configData) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_VIDEO_CONFIG_NALSIZE *pNal; - - DEBUG_PRINT_LOW("Set Config Called"); - - if (m_state == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n"); - return ret; - } - - if (configIndex == OMX_IndexVendorVideoExtraData) - { - OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; - DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called"); - if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) - { - DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC"); - OMX_U32 extra_size; - // Parsing done here for the AVC atom is definitely not generic - // Currently this piece of code is working, but certainly - // not tested with all .mp4 files. - // Incase of failure, we might need to revisit this - // for a generic piece of code. - - // Retrieve size of NAL length field - // byte #4 contains the size of NAL lenght field - nal_length = (config->pData[4] & 0x03) + 1; - - extra_size = 0; - if (nal_length > 2) - { - /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ - extra_size = (nal_length - 2) * 2; - } - - // SPS starts from byte #6 - OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); - OMX_U8 *pDestBuf; - m_vendor_config.nPortIndex = config->nPortIndex; - - // minus 6 --> SPS starts from byte #6 - // minus 1 --> picture param set byte to be ignored from avcatom - m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; - m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); - OMX_U32 len; - OMX_U8 index = 0; - // case where SPS+PPS is sent as part of set_config - pDestBuf = m_vendor_config.pData; - - DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]", - m_vendor_config.nPortIndex, - m_vendor_config.nDataSize, - m_vendor_config.pData); - while (index < 2) - { - uint8 *psize; - len = *pSrcBuf; - len = len << 8; - len |= *(pSrcBuf + 1); - psize = (uint8 *) & len; - memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); - for (int i = 0; i < nal_length; i++) - { - pDestBuf[i] = psize[nal_length - 1 - i]; - } - //memcpy(pDestBuf,pSrcBuf,(len+2)); - pDestBuf += len + nal_length; - pSrcBuf += len + 2; - index++; - pSrcBuf++; // skip picture param set - len = 0; - } - } - else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || - !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) - { - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); - memcpy(m_vendor_config.pData, config->pData,config->nDataSize); - } - else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) - { - if(m_vendor_config.pData) - { - free(m_vendor_config.pData); - m_vendor_config.pData = NULL; - m_vendor_config.nDataSize = 0; - } - - if (((*((OMX_U32 *) config->pData)) & - VC1_SP_MP_START_CODE_MASK) == - VC1_SP_MP_START_CODE) - { - DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = - (OMX_U8 *) malloc(config->nDataSize); - memcpy(m_vendor_config.pData, config->pData, - config->nDataSize); - m_vc1_profile = VC1_SP_MP_RCV; - } - else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) - { - DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = - (OMX_U8 *) malloc((config->nDataSize)); - memcpy(m_vendor_config.pData, config->pData, - config->nDataSize); - m_vc1_profile = VC1_AP; - } - else if ((config->nDataSize == VC1_STRUCT_C_LEN)) - { - DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); - memcpy(m_vendor_config.pData,config->pData,config->nDataSize); - m_vc1_profile = VC1_SP_MP_RCV; - } - else - { - DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); - } - } - return ret; - } - else if (configIndex == OMX_IndexConfigVideoNalSize) - { - - pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); - nal_length = pNal->nNaluBytes; - m_frame_parser.init_nal_length(nal_length); - DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d",nal_length); - return ret; - } - - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetExtensionIndex - -DESCRIPTION - OMX GetExtensionIndex method implementaion. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_STRING paramName, - OMX_OUT OMX_INDEXTYPE* indexType) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); - return OMX_ErrorInvalidState; - } - else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; - } -#ifdef MAX_RES_1080P - else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) - { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; - } -#endif -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; - } - else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; - } - else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { - DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName); - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; - } - else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; - } -#endif - else { - DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName); - return OMX_ErrorNotImplemented; - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetState - -DESCRIPTION - Returns the state information back to the caller. - -PARAMETERS - . - -RETURN VALUE - Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STATETYPE* state) -{ - *state = m_state; - DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentTunnelRequest - -DESCRIPTION - OMX Component Tunnel Request method implementation. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_HANDLETYPE peerComponent, - OMX_IN OMX_U32 peerPort, - OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) -{ - DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::UseOutputBuffer - -DESCRIPTION - Helper function for Use buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - struct vdec_setbuffer_cmd setbuffers; - OMX_PTR privateAppData = NULL; -#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) - private_handle_t *handle = NULL; -#endif - OMX_U8 *buff = buffer; - - if (!m_out_mem_ptr) { - DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); - eRet = allocate_output_headers(); - -#ifdef MAX_RES_1080P - if(secure_mode) - { - eRet = vdec_alloc_meta_buffers(); - if (eRet) { - DEBUG_PRINT_ERROR("ERROR in allocating meta buffers\n"); - return OMX_ErrorInsufficientResources; - } - } - - if(drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - //allocate H264_mv_buffer - eRet = vdec_alloc_h264_mv(); - if (eRet) { - DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n"); - return OMX_ErrorInsufficientResources; - } - } -#endif - - } - - if (eRet == OMX_ErrorNone) { - for(i=0; i< drv_ctx.op_buf.actualcount; i++) { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - break; - } - } - } - - if(i >= drv_ctx.op_buf.actualcount) { - eRet = OMX_ErrorInsufficientResources; - } - - if (eRet == OMX_ErrorNone) { -#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) - if(m_enable_android_native_buffers) { - if (m_use_android_native_buffers) { - UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; - sp nBuf = params->nativeBuffer; - handle = (private_handle_t *)nBuf->handle; - privateAppData = params->pAppPrivate; - } else { - handle = (private_handle_t *)buff; - privateAppData = appData; - } - - if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { - DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," - " expected %u, got %lu", - drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); - return OMX_ErrorBadParameter; - } - - if (!m_use_android_native_buffers) { - if (!secure_mode) { - buff = (OMX_U8*)mmap(0, handle->size, - PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); - if (buff == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); - return OMX_ErrorInsufficientResources; - } - } - } - -#if defined(_ANDROID_ICS_) - native_buffer[i].nativehandle = handle; -#endif - if(!handle) { - DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); - return OMX_ErrorBadParameter; - } - drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; - drv_ctx.ptr_outputbuffer[i].offset = 0; - drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; - drv_ctx.ptr_outputbuffer[i].mmaped_size = - drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; -#if defined(_ANDROID_ICS_) - if (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) { - int enable = 1; - setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable); - } -#endif - } else -#endif - - if (!ouput_egl_buffers && !m_use_output_pmem) { -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( - drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, - &drv_ctx.op_buf_ion_info[i].ion_alloc_data, - &drv_ctx.op_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED); - if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; -#else - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - open (MEM_DEVICE,O_RDWR); - - if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { - return OMX_ErrorInsufficientResources; - } - - if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) - { - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - open (MEM_DEVICE,O_RDWR); - if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, - drv_ctx.op_buf.buffer_size, - drv_ctx.op_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(drv_ctx.ptr_outputbuffer[i].pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if(!secure_mode) { - drv_ctx.ptr_outputbuffer[i].bufferaddr = - (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, - PROT_READ|PROT_WRITE, MAP_SHARED, - drv_ctx.ptr_outputbuffer[i].pmem_fd,0); - if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { - close(drv_ctx.ptr_outputbuffer[i].pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - drv_ctx.ptr_outputbuffer[i].offset = 0; - privateAppData = appData; - } - else { - - DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); - - if (!appData || !bytes ) - { - DEBUG_PRINT_ERROR("\n Invalid appData or bytes"); - return OMX_ErrorBadParameter; - } - - if(!secure_mode && !buffer) - { - DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case"); - return OMX_ErrorBadParameter; - } - - - OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; - pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; - if (!pmem_list->entryList || !pmem_list->entryList->entry || - !pmem_list->nEntries || - pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { - DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer"); - return OMX_ErrorBadParameter; - } - pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - pmem_list->entryList->entry; - DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x", - pmem_info->pmem_fd); - drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; - drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; - drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; - drv_ctx.ptr_outputbuffer[i].mmaped_size = - drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; - privateAppData = appData; - } - m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; - m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; - - *bufferHdr = (m_out_mem_ptr + i ); - if(secure_mode) - drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; - setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], - sizeof (vdec_bufferpayload)); - - ioctl_msg.in = &setbuffers; - ioctl_msg.out = NULL; - - DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %x, pmem_fd=%0x%x", i, - drv_ctx.ptr_outputbuffer[i],drv_ctx.ptr_outputbuffer[i].pmem_fd ); - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, - &ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set output buffer failed"); - return OMX_ErrorInsufficientResources; - } - // found an empty buffer at i - (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; - if (m_enable_android_native_buffers) { - DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); - (*bufferHdr)->pBuffer = (OMX_U8 *)handle; - } else { - (*bufferHdr)->pBuffer = buff; - } - (*bufferHdr)->pAppPrivate = privateAppData; - BITMASK_SET(&m_out_bm_count,i); - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::use_input_heap_buffers - -DESCRIPTION - OMX Use Buffer Heap allocation method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer); - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!m_inp_heap_ptr) - m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), - drv_ctx.ip_buf.actualcount); - if(!m_phdr_pmem_ptr) - m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) - calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), - drv_ctx.ip_buf.actualcount); - if(!m_inp_heap_ptr || !m_phdr_pmem_ptr) - { - DEBUG_PRINT_ERROR("Insufficent memory"); - eRet = OMX_ErrorInsufficientResources; - } - else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) - { - input_use_buffer = true; - memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); - m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; - m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; - m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; - m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; - m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; - *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; - eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); - DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); - if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], NULL, NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); - return OMX_ErrorInsufficientResources; - } - m_in_alloc_cnt++; - } - else - { - DEBUG_PRINT_ERROR("All i/p buffers have been set!"); - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::UseBuffer - -DESCRIPTION - OMX Use Buffer method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE error = OMX_ErrorNone; - struct vdec_setbuffer_cmd setbuffers; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - - if (bufferHdr == NULL || bytes == 0) - { - DEBUG_PRINT_ERROR("bad param 0x%p %ld",bufferHdr, bytes); - return OMX_ErrorBadParameter; - } - - if(!secure_mode && buffer == NULL) { - DEBUG_PRINT_ERROR("bad param 0x%p",buffer); - return OMX_ErrorBadParameter; - } - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(port == OMX_CORE_INPUT_PORT_INDEX) - error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested - else - { - DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); - error = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error); - if(error == OMX_ErrorNone) - { - if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && - BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && - BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - return error; -} - -OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, - OMX_BUFFERHEADERTYPE *pmem_bufferHdr) -{ - if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) - { - if(m_inp_heap_ptr[bufferindex].pBuffer) - free(m_inp_heap_ptr[bufferindex].pBuffer); - m_inp_heap_ptr[bufferindex].pBuffer = NULL; - } - if (pmem_bufferHdr) - free_input_buffer(pmem_bufferHdr); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - if (bufferHdr == NULL || m_inp_mem_ptr == NULL) - { - return OMX_ErrorBadParameter; - } - - index = bufferHdr - m_inp_mem_ptr; - DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); - - if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) - { - DEBUG_PRINT_LOW("Free Input Buffer index = %d",index); - if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) - { - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - struct vdec_setbuffer_cmd setbuffers; - setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], - sizeof (vdec_bufferpayload)); - ioctl_msg.in = &setbuffers; - ioctl_msg.out = NULL; - int ioctl_r = ioctl (drv_ctx.video_driver_fd, - VDEC_IOCTL_FREE_BUFFER, &ioctl_msg); - if (ioctl_r < 0) - { - DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r); - } - if (!secure_mode) { - DEBUG_PRINT_LOW("unmap the input buffer fd=%d", - drv_ctx.ptr_inputbuffer[index].pmem_fd); - DEBUG_PRINT_LOW("unmap the input buffer size=%d address = %d", - drv_ctx.ptr_inputbuffer[index].mmaped_size, - drv_ctx.ptr_inputbuffer[index].bufferaddr); - munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, - drv_ctx.ptr_inputbuffer[index].mmaped_size); - } - close (drv_ctx.ptr_inputbuffer[index].pmem_fd); - drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; - if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) - { - free(m_desc_buffer_ptr[index].buf_addr); - m_desc_buffer_ptr[index].buf_addr = NULL; - m_desc_buffer_ptr[index].desc_data_size = 0; - } -#ifdef USE_ION - free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); -#endif - } - } - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - - if (bufferHdr == NULL || m_out_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("\nfree_output_buffer ERROR"); - return OMX_ErrorBadParameter; - } - - index = bufferHdr - m_out_mem_ptr; - DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index); - - if (index < drv_ctx.op_buf.actualcount - && drv_ctx.ptr_outputbuffer) - { - DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %x", index, - drv_ctx.ptr_outputbuffer[index].bufferaddr); - - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - struct vdec_setbuffer_cmd setbuffers; - setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], - sizeof (vdec_bufferpayload)); - ioctl_msg.in = &setbuffers; - ioctl_msg.out = NULL; - DEBUG_PRINT_LOW("Release the Output Buffer"); - if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_BUFFER, - &ioctl_msg) < 0) - DEBUG_PRINT_ERROR("\n Release output buffer failed in VCD"); - -#ifdef _ANDROID_ - if(m_enable_android_native_buffers) { - if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { - if(!secure_mode) { - munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, - drv_ctx.ptr_outputbuffer[index].mmaped_size); - } - } - drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; - } else { -#endif - if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) - { - if(!secure_mode) { - DEBUG_PRINT_LOW("unmap the output buffer fd = %d", - drv_ctx.ptr_outputbuffer[index].pmem_fd); - DEBUG_PRINT_LOW("unmap the ouput buffer size=%d address = %d", - drv_ctx.ptr_outputbuffer[index].mmaped_size, - drv_ctx.ptr_outputbuffer[index].bufferaddr); - munmap (drv_ctx.ptr_outputbuffer[index].bufferaddr, - drv_ctx.ptr_outputbuffer[index].mmaped_size); - } - close (drv_ctx.ptr_outputbuffer[index].pmem_fd); - drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[index]); -#endif -#ifdef _ANDROID_ - m_heap_ptr[index].video_heap_ptr = NULL; - m_heap_count = m_heap_count - 1; - if (m_heap_count == 0) - { - free(m_heap_ptr); - m_heap_ptr = NULL; - } -#endif // _ANDROID_ - } -#ifdef _ANDROID_ - } -#endif - } -#ifdef MAX_RES_1080P - if(secure_mode) - { - vdec_dealloc_meta_buffers(); - } - if(drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - vdec_dealloc_h264_mv(); - } -#endif - - return OMX_ErrorNone; - -} - -OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes) -{ - OMX_BUFFERHEADERTYPE *input = NULL; - unsigned char *buf_addr = NULL; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned i = 0; - - /* Sanity Check*/ - if (bufferHdr == NULL) - { - return OMX_ErrorBadParameter; - } - - if (m_inp_heap_ptr == NULL) - { - m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), - drv_ctx.ip_buf.actualcount); - m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), - drv_ctx.ip_buf.actualcount); - - if (m_inp_heap_ptr == NULL) - { - DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - } - - /*Find a Free index*/ - for(i=0; i< drv_ctx.ip_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) - { - DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); - break; - } - } - - if (i < drv_ctx.ip_buf.actualcount) - { - buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); - - if (buf_addr == NULL) - { - return OMX_ErrorInsufficientResources; - } - - *bufferHdr = (m_inp_heap_ptr + i); - input = *bufferHdr; - BITMASK_SET(&m_heap_inp_bm_count,i); - - input->pBuffer = (OMX_U8 *)buf_addr; - input->nSize = sizeof(OMX_BUFFERHEADERTYPE); - input->nVersion.nVersion = OMX_SPEC_VERSION; - input->nAllocLen = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; - input->pAppPrivate = appData; - input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; - DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr ); - eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); - DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] ); - /*Add the Buffers to freeq*/ - if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); - return OMX_ErrorInsufficientResources; - } - } - else - { - return OMX_ErrorBadParameter; - } - - return eRet; - -} - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateInputBuffer - -DESCRIPTION - Helper function for allocate buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_input_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct vdec_setbuffer_cmd setbuffers; - OMX_BUFFERHEADERTYPE *input = NULL; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - unsigned i = 0; - unsigned char *buf_addr = NULL; - int pmem_fd = -1; - - if((bytes + DEVICE_SCRATCH) != drv_ctx.ip_buf.buffer_size) - { - DEBUG_PRINT_LOW("Requested Size is wrong %d epected is %d", - bytes, drv_ctx.ip_buf.buffer_size); - //return OMX_ErrorBadParameter; - } - - if(!m_inp_mem_ptr) - { - DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)", - drv_ctx.ip_buf.actualcount, - drv_ctx.ip_buf.buffer_size); - - m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); - - if (m_inp_mem_ptr == NULL) - { - return OMX_ErrorInsufficientResources; - } - - drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ - calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); - - if (drv_ctx.ptr_inputbuffer == NULL) - { - return OMX_ErrorInsufficientResources; - } -#ifdef USE_ION - drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ - calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); - - if (drv_ctx.ip_buf_ion_info == NULL) - { - return OMX_ErrorInsufficientResources; - } -#endif - - for (i=0; i < drv_ctx.ip_buf.actualcount; i++) - { - drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; -#ifdef USE_ION - drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; -#endif - } - } - - for(i=0; i< drv_ctx.ip_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_inp_bm_count,i)) - { - DEBUG_PRINT_LOW("Free Input Buffer Index %d",i); - break; - } - } - - if(i < drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_LOW("Allocate input Buffer"); - -#ifdef USE_ION - drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( - drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, - &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, - &drv_ctx.ip_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED); - if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; -#else - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); - return OMX_ErrorInsufficientResources; - } - - if (pmem_fd == 0) - { - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, - drv_ctx.ip_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if (!secure_mode) { - buf_addr = (unsigned char *)mmap(NULL, - drv_ctx.ip_buf.buffer_size, - PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); - - if (buf_addr == MAP_FAILED) - { - close(pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); -#endif - DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); - return OMX_ErrorInsufficientResources; - } - } - *bufferHdr = (m_inp_mem_ptr + i); - if (secure_mode) - drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; - else - drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; - drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; - drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; - drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; - drv_ctx.ptr_inputbuffer [i].offset = 0; - - setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer [i], - sizeof (vdec_bufferpayload)); - ioctl_msg.in = &setbuffers; - ioctl_msg.out = NULL; - - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, - &ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set Buffers Failed"); - return OMX_ErrorInsufficientResources; - } - - input = *bufferHdr; - BITMASK_SET(&m_inp_bm_count,i); - DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr); - if (secure_mode) - input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; - else - input->pBuffer = (OMX_U8 *)buf_addr; - input->nSize = sizeof(OMX_BUFFERHEADERTYPE); - input->nVersion.nVersion = OMX_SPEC_VERSION; - input->nAllocLen = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; - input->pAppPrivate = appData; - input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; - input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; - - if (drv_ctx.disable_dmx) - { - eRet = allocate_desc_buffer(i); - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateOutputBuffer - -DESCRIPTION - Helper fn for AllocateBuffer in the output pin - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything went well. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - struct vdec_setbuffer_cmd setbuffers; -#ifdef USE_ION - int ion_device_fd =-1; - struct ion_allocation_data ion_alloc_data; - struct ion_fd_data fd_ion_data; -#endif - - int nBufHdrSize = 0; - int nPlatformEntrySize = 0; - int nPlatformListSize = 0; - int nPMEMInfoSize = 0; - int pmem_fd = -1; - unsigned char *pmem_baseaddress = NULL; - - OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; - - if (!m_out_mem_ptr) - { - DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)", - drv_ctx.op_buf.actualcount, - drv_ctx.op_buf.buffer_size); - - DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)", - drv_ctx.op_buf.actualcount); - - nBufHdrSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_BUFFERHEADERTYPE); - - nPMEMInfoSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); - nPlatformListSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); - nPlatformEntrySize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); - - DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize, - sizeof(OMX_BUFFERHEADERTYPE), - nPMEMInfoSize, - nPlatformListSize); - DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize, - drv_ctx.op_buf.actualcount); - - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - // Alloc mem for platform specific info - char *pPtr=NULL; - pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + - nPMEMInfoSize,1); - drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ - calloc (sizeof(struct vdec_bufferpayload), - drv_ctx.op_buf.actualcount); - drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ - calloc (sizeof (struct vdec_output_frameinfo), - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ - calloc (sizeof(struct vdec_ion), - drv_ctx.op_buf.actualcount); -#endif -#ifdef _ANDROID_ - m_heap_ptr = (struct vidc_heap *)\ - calloc (sizeof(struct vidc_heap), - drv_ctx.op_buf.actualcount); -#endif - - if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer - && drv_ctx.ptr_respbuffer -#ifdef _ANDROID_ - && m_heap_ptr -#endif - ) - { - drv_ctx.ptr_outputbuffer[0].mmaped_size = - (drv_ctx.op_buf.buffer_size * - drv_ctx.op_buf.actualcount); - bufHdr = m_out_mem_ptr; - m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); - m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) - (((char *) m_platform_list) + nPlatformListSize); - m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - (((char *) m_platform_entry) + nPlatformEntrySize); - pPlatformList = m_platform_list; - pPlatformEntry = m_platform_entry; - pPMEMInfo = m_pmem_info; - - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); - - // Settting the entire storage nicely - DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry); - DEBUG_PRINT_LOW("Pmem Info = %p",pPMEMInfo); - for(i=0; i < drv_ctx.op_buf.actualcount ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = 0; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = NULL; - bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - // Platform specific PMEM Information - // Initialize the Platform Entry - //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i); - pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pPlatformEntry->entry = pPMEMInfo; - // Initialize the Platform List - pPlatformList->nEntries = 1; - pPlatformList->entryList = pPlatformEntry; - // Keep pBuffer NULL till vdec is opened - bufHdr->pBuffer = NULL; - - pPMEMInfo->offset = 0; - pPMEMInfo->pmem_fd = 0; - bufHdr->pPlatformPrivate = pPlatformList; - drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; -#endif - /*Create a mapping between buffers*/ - bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; - drv_ctx.ptr_respbuffer[i].client_data = (void *)\ - &drv_ctx.ptr_outputbuffer[i]; -#ifdef _ANDROID_ - m_heap_ptr[i].video_heap_ptr = NULL; -#endif - // Move the buffer and buffer header pointers - bufHdr++; - pPMEMInfo++; - pPlatformEntry++; - pPlatformList++; - } -#ifdef MAX_RES_1080P - if(eRet == OMX_ErrorNone && secure_mode) - { - eRet = vdec_alloc_meta_buffers(); - if (eRet) { - DEBUG_PRINT_ERROR("ERROR in allocating meta buffers\n"); - return OMX_ErrorInsufficientResources; - } - } - - if(eRet == OMX_ErrorNone && drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - //Allocate the h264_mv_buffer - eRet = vdec_alloc_h264_mv(); - if(eRet) { - DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n"); - return OMX_ErrorInsufficientResources; - } - } -#endif - } - else - { - DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ - m_out_mem_ptr, pPtr); - if(m_out_mem_ptr) - { - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(pPtr) - { - free(pPtr); - pPtr = NULL; - } - if(drv_ctx.ptr_outputbuffer) - { - free(drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } - if(drv_ctx.ptr_respbuffer) - { - free(drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif - eRet = OMX_ErrorInsufficientResources; - } - } - - for (i=0; i< drv_ctx.op_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - DEBUG_PRINT_LOW("Found a Free Output Buffer Index %d",i); - break; - } - } - - if (i < drv_ctx.op_buf.actualcount) - { - DEBUG_PRINT_LOW("Allocate Output Buffer"); - -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( - drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, - &drv_ctx.op_buf_ion_info[i].ion_alloc_data, - &drv_ctx.op_buf_ion_info[i].fd_ion_data, ION_FLAG_CACHED); - if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - pmem_fd = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; -#else - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", - drv_ctx.op_buf.buffer_size); - return OMX_ErrorInsufficientResources; - } - - if (pmem_fd == 0) - { - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", - drv_ctx.op_buf.buffer_size); - return OMX_ErrorInsufficientResources; - } - } - - if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size, - drv_ctx.op_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if (!secure_mode) { - pmem_baseaddress = (unsigned char *)mmap(NULL, - drv_ctx.op_buf.buffer_size, - PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); - - if (pmem_baseaddress == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\n MMAP failed for Size %d", - drv_ctx.op_buf.buffer_size); - close(pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - - *bufferHdr = (m_out_mem_ptr + i); - if (secure_mode) - drv_ctx.ptr_outputbuffer [i].bufferaddr = *bufferHdr; - else - drv_ctx.ptr_outputbuffer [i].bufferaddr = pmem_baseaddress; - - drv_ctx.ptr_outputbuffer [i].pmem_fd = pmem_fd; - drv_ctx.ptr_outputbuffer [i].buffer_len = drv_ctx.op_buf.buffer_size; - drv_ctx.ptr_outputbuffer [i].mmaped_size = drv_ctx.op_buf.buffer_size; - drv_ctx.ptr_outputbuffer [i].offset = 0; - -#ifdef _ANDROID_ - #ifdef USE_ION - m_heap_ptr[i].video_heap_ptr = new VideoHeap (drv_ctx.op_buf_ion_info[i].ion_device_fd, - drv_ctx.op_buf.buffer_size, - pmem_baseaddress, - ion_alloc_data.handle, - pmem_fd); - m_heap_count = m_heap_count + 1; -#else - m_heap_ptr[i].video_heap_ptr = new VideoHeap (pmem_fd, - drv_ctx.op_buf.buffer_size, - pmem_baseaddress); -#endif -#endif - - m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; -#ifdef _ANDROID_ - m_pmem_info[i].pmem_fd = (OMX_U32) m_heap_ptr[i].video_heap_ptr.get (); -#else - m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd ; -#endif - setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer [i], - sizeof (vdec_bufferpayload)); - ioctl_msg.in = &setbuffers; - ioctl_msg.out = NULL; - - DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER, - &ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Set output buffer failed"); - return OMX_ErrorInsufficientResources; - } - - // found an empty buffer at i - (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; - (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; - (*bufferHdr)->pAppPrivate = appData; - BITMASK_SET(&m_out_bm_count,i); - - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Output Buffer Index not found"); - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - - -// AllocateBuffer -- API Call -/* ====================================================================== -FUNCTION - omx_vdec::AllocateBuffer - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - unsigned i = 0; - OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type - - DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if(port == OMX_CORE_INPUT_PORT_INDEX) - { - if (arbitrary_bytes) - { - eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); - } - else - { - eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); - } - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - { - eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, - appData,bytes); - } - else - { - DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); - if(eRet == OMX_ErrorNone) - { - if(allocate_done()){ - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - } - DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet); - return eRet; -} - -// Free Buffer - API call -/* ====================================================================== -FUNCTION - omx_vdec::FreeBuffer - -DESCRIPTION - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int nPortIndex; - - DEBUG_PRINT_LOW("In for decoder free_buffer"); - - if(m_state == OMX_StateIdle && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - DEBUG_PRINT_LOW(" free buffer while Component in Loading pending"); - } - else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| - (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) - { - DEBUG_PRINT_LOW("Free Buffer while port %d disabled", port); - } - else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) - { - DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - - return OMX_ErrorIncorrectStateOperation; - } - else if (m_state != OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - } - - if(port == OMX_CORE_INPUT_PORT_INDEX) - { - /*Check if arbitrary bytes*/ - if(!arbitrary_bytes && !input_use_buffer) - nPortIndex = buffer - m_inp_mem_ptr; - else - nPortIndex = buffer - m_inp_heap_ptr; - - DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex); - if(nPortIndex < drv_ctx.ip_buf.actualcount) - { - // Clear the bit associated with it. - BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); - BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); - if (input_use_buffer == true) - { - - DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex); - if(m_phdr_pmem_ptr) - free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); - } - else - { - if (arbitrary_bytes) - { - if(m_phdr_pmem_ptr) - free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); - else - free_input_buffer(nPortIndex,NULL); - } - else - free_input_buffer(buffer); - } - m_inp_bPopulated = OMX_FALSE; - /*Free the Buffer Header*/ - if (release_input_done()) - { - DEBUG_PRINT_HIGH("ALL input buffers are freed/released"); - free_input_buffer_header(); - } - } - else - { - DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) - && release_input_done()) - { - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); - post_event(OMX_CommandPortDisable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - { - // check if the buffer is valid - nPortIndex = buffer - client_buffers.get_il_buf_hdr(); - if(nPortIndex < drv_ctx.op_buf.actualcount) - { - DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex); - // Clear the bit associated with it. - BITMASK_CLEAR(&m_out_bm_count,nPortIndex); - m_out_bPopulated = OMX_FALSE; - client_buffers.free_output_buffer (buffer); - - if (release_output_done()) - { - free_output_buffer_header(); - } - } - else - { - DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) - && release_output_done()) - { - DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it"); - - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); - memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); - } -#endif - - post_event(OMX_CommandPortDisable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else - { - eRet = OMX_ErrorBadPortIndex; - } - if((eRet == OMX_ErrorNone) && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - if(release_done()) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); - post_event(OMX_CommandStateSet, OMX_StateLoaded, - OMX_COMPONENT_GENERATE_EVENT); - } - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::EmptyThisBuffer - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE ret1 = OMX_ErrorNone; - unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; - - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) - { - codec_config_flag = true; - DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); - } - else - { - codec_config_flag = false; - } - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (buffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); - return OMX_ErrorBadParameter; - } - - if (!m_inp_bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled."); - return OMX_ErrorIncorrectStateOperation; - } - - if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) - { - DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %d", buffer->nInputPortIndex); - return OMX_ErrorBadPortIndex; - } - -#ifdef _ANDROID_ - if(iDivXDrmDecrypt) - { - OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer); - if(drmErr != OMX_ErrorNone) { - // this error can be ignored - DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr); - } - } - if (perf_flag) - { - if (!latency) - { - dec_time.stop(); - latency = dec_time.processing_time_us(); - dec_time.start(); - } - } -#endif //_ANDROID_ - - if (arbitrary_bytes) - { - nBufferIndex = buffer - m_inp_heap_ptr; - } - else - { - if (input_use_buffer == true) - { - nBufferIndex = buffer - m_inp_heap_ptr; - m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; - m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; - m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; - buffer = &m_inp_mem_ptr[nBufferIndex]; - DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d", - &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); - } - else{ - nBufferIndex = buffer - m_inp_mem_ptr; - } - } - - if (nBufferIndex > drv_ctx.ip_buf.actualcount ) - { - DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", - buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); - if (arbitrary_bytes) - { - post_event ((unsigned)hComp,(unsigned)buffer, - OMX_COMPONENT_GENERATE_ETB_ARBITRARY); - } - else - { - if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) - set_frame_rate(buffer->nTimeStamp); - post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::empty_this_buffer_proxy - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - int push_cnt = 0,i=0; - unsigned nPortIndex = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - struct vdec_input_frameinfo frameinfo; - struct vdec_bufferpayload *temp_buffer; - struct vdec_ioctl_msg ioctl_msg; - struct vdec_seqheader seq_header; - bool port_setting_changed = true; -#ifdef MAX_RES_1080P - bool not_coded_vop = false; -#endif - - /*Should we generate a Aync error event*/ - if (buffer == NULL || buffer->pInputPortPrivate == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); - return OMX_ErrorBadParameter; - } - - nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - - if (nPortIndex > drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", - nPortIndex); - return OMX_ErrorBadParameter; - } - - pending_input_buffers++; - - /* return zero length and not an EOS buffer */ - if (!arbitrary_bytes && (buffer->nFilledLen == 0) && - ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) - { - DEBUG_PRINT_HIGH("return zero legth buffer"); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorNone; - } - -#ifdef MAX_RES_1080P - if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){ - mp4StreamType psBits; - psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); - psBits.numBytes = buffer->nFilledLen; - mp4_headerparser.parseHeader(&psBits); - not_coded_vop = mp4_headerparser.is_notcodec_vop( - (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); - if(not_coded_vop) { - DEBUG_PRINT_HIGH("Found Not coded vop len %d frame number %d", - buffer->nFilledLen,frame_count); - if(buffer->nFlags & OMX_BUFFERFLAG_EOS){ - DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero"); - not_coded_vop = false; - buffer->nFilledLen = 0; - } - } - } -#endif - if(input_flush_progress == true -#ifdef MAX_RES_1080P - || not_coded_vop -#endif - ) - { - DEBUG_PRINT_LOW("Flush in progress return buffer "); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorNone; - } - - temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; - - if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) - { - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - /*for use buffer we need to memcpy the data*/ - temp_buffer->buffer_len = buffer->nFilledLen; - - if (input_use_buffer) - { - if (buffer->nFilledLen <= temp_buffer->buffer_len) - { - if(arbitrary_bytes) - { - memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); - } - else - { - memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), - buffer->nFilledLen); - } - } - else - { - return OMX_ErrorBadParameter; - } - - } - - frameinfo.bufferaddr = temp_buffer->bufferaddr; - frameinfo.client_data = (void *) buffer; - frameinfo.datalen = temp_buffer->buffer_len; - frameinfo.flags = 0; - frameinfo.offset = buffer->nOffset; - frameinfo.pmem_fd = temp_buffer->pmem_fd; - frameinfo.pmem_offset = temp_buffer->offset; - frameinfo.timestamp = buffer->nTimeStamp; - if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) - { - DEBUG_PRINT_LOW("ETB: dmx enabled"); - if (m_demux_entries == 0) - { - extract_demux_addr_offsets(buffer); - } - - DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries); - handle_demux_data(buffer); - frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; - frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; - } - else - { - frameinfo.desc_addr = NULL; - frameinfo.desc_size = 0; - } - if(!arbitrary_bytes) - { - frameinfo.flags |= buffer->nFlags; - } - - -#ifdef _ANDROID_ - if (m_debug_timestamp) - { - if(arbitrary_bytes) - { - DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); - m_timestamp_list.insert_ts(buffer->nTimeStamp); - } - else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) - { - DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); - m_timestamp_list.insert_ts(buffer->nTimeStamp); - } - } -#endif - -#ifdef INPUT_BUFFER_LOG - if (inputBufferFile1) - { - fwrite((const char *)temp_buffer->bufferaddr, - temp_buffer->buffer_len,1,inputBufferFile1); - } - -#endif - if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) - { - frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; - } - - if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) - { - DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached"); - frameinfo.flags |= VDEC_BUFFERFLAG_EOS; - h264_scratch.nFilledLen = 0; - nal_count = 0; - look_ahead_nal = false; - frame_count = 0; - if (m_frame_parser.mutils) - m_frame_parser.mutils->initialize_frame_checking_environment(); - m_frame_parser.flush(); - h264_last_au_ts = LLONG_MAX; - h264_last_au_flags = 0; - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - } - DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", - frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); - ioctl_msg.in = &frameinfo; - ioctl_msg.out = NULL; - if (ioctl(drv_ctx.video_driver_fd,VDEC_IOCTL_DECODE_FRAME, - &ioctl_msg) < 0) - { - /*Generate an async error and move to invalid state*/ - DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy VDEC_IOCTL_DECODE_FRAME failed"); - if (!arbitrary_bytes) - { - DEBUG_PRINT_LOW("Return failed buffer"); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - } - return OMX_ErrorBadParameter; - } else - time_stamp_dts.insert_timestamp(buffer); - - return ret; -} - -/* ====================================================================== -FUNCTION - omx_vdec::FillThisBuffer - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("FTB in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (!m_out_bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled."); - return OMX_ErrorIncorrectStateOperation; - } - - if (buffer == NULL || - ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) - { - return OMX_ErrorBadParameter; - } - - if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) - { - DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex); - return OMX_ErrorBadPortIndex; - } - - DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - post_event((unsigned) hComp, (unsigned)buffer,m_fill_output_msg); - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_vdec::fill_this_buffer_proxy - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) -{ - OMX_ERRORTYPE nRet = OMX_ErrorNone; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - OMX_BUFFERHEADERTYPE *buffer = bufferAdd; - struct vdec_fillbuffer_cmd fillbuffer; - struct vdec_bufferpayload *ptr_outputbuffer = NULL; - struct vdec_output_frameinfo *ptr_respbuffer = NULL; - - - if (bufferAdd == NULL || ((buffer - client_buffers.get_il_buf_hdr()) > - drv_ctx.op_buf.actualcount) ) - return OMX_ErrorBadParameter; - - DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", - bufferAdd, bufferAdd->pBuffer); - /*Return back the output buffer to client*/ - if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true) - { - DEBUG_PRINT_LOW("Output Buffers return flush/disable condition"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - return OMX_ErrorNone; - } - pending_output_buffers++; - buffer = client_buffers.get_dr_buf_hdr(bufferAdd); - ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; - if (ptr_respbuffer) - { - ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; - } - - if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) - { - DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - pending_output_buffers--; - return OMX_ErrorBadParameter; - } - - memcpy (&fillbuffer.buffer,ptr_outputbuffer,\ - sizeof(struct vdec_bufferpayload)); - fillbuffer.client_data = buffer; - -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - // Acquire a write lock on this buffer. - if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle, - GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { - DEBUG_PRINT_ERROR("Failed to acquire genlock"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - pending_output_buffers--; - return OMX_ErrorInsufficientResources; - } else { - native_buffer[buffer - m_out_mem_ptr].inuse = true; - } - } -#endif - - ioctl_msg.in = &fillbuffer; - ioctl_msg.out = NULL; - if (ioctl (drv_ctx.video_driver_fd, - VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n Decoder frame failed"); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - // Unlock the buffer - if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { - DEBUG_PRINT_ERROR("Releasing genlock failed"); - return OMX_ErrorInsufficientResources; - } else { - native_buffer[buffer - m_out_mem_ptr].inuse = false; - } - } -#endif - m_cb.FillBufferDone (hComp,m_app_data,buffer); - pending_output_buffers--; - return OMX_ErrorBadParameter; - } - - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SetCallbacks - -DESCRIPTION - Set the callbacks. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_CALLBACKTYPE* callbacks, - OMX_IN OMX_PTR appData) -{ - - m_cb = *callbacks; - DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ - m_cb.EventHandler,m_cb.FillBufferDone); - m_app_data = appData; - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentDeInit - -DESCRIPTION - Destroys the component and release memory allocated to the heap. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) -{ -#ifndef JB_MR1 - sp sm; - sp hwcBinder = NULL; -#endif -#ifdef _ANDROID_ - if(iDivXDrmDecrypt) - { - delete iDivXDrmDecrypt; - iDivXDrmDecrypt=NULL; - } -#endif //_ANDROID_ - int i = 0; - if (OMX_StateLoaded != m_state) - { - DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ - m_state); - DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); - } - else - { - DEBUG_PRINT_HIGH("Playback Ended - PASSED"); - } -#ifndef JB_MR1 - if (secure_mode) { - sm = defaultServiceManager(); - hwcBinder = - interface_cast(sm->getService(String16("display.hwcservice"))); - if (hwcBinder != NULL) { - hwcBinder->setCloseSecureStart(); - } else { - DEBUG_PRINT_HIGH("Failed to get hwcbinder, " - "failed to call close secure start"); - } - } -#endif - /*Check if the output buffers have to be cleaned up*/ - if(m_out_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing the Output Memory"); - for (i=0; i < drv_ctx.op_buf.actualcount; i++ ) - { - free_output_buffer (&m_out_mem_ptr[i]); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - if (native_buffer[i].inuse) - { - if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) { - DEBUG_PRINT_ERROR("Unlocking genlock failed"); - } - native_buffer[i].inuse = false; - } - } -#endif - } -#ifdef _ANDROID_ICS_ - memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); -#endif - } - - /*Check if the input buffers have to be cleaned up*/ - if(m_inp_mem_ptr || m_inp_heap_ptr) - { - DEBUG_PRINT_LOW("Freeing the Input Memory"); - for (i=0; isetCloseSecureEnd(); - } else { - DEBUG_PRINT_HIGH("Failed to get hwcbinder, " - "failed to call close secure start"); - } - } -#endif - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::UseEGLImage - -DESCRIPTION - OMX Use EGL Image method implementation . - -PARAMETERS - . - -RETURN VALUE - Not Implemented error. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN void* eglImage) -{ - OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; - -#ifdef USE_EGL_IMAGE_GPU - PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; - EGLint fd = -1, offset = 0,pmemPtr = 0; -#else - int fd = -1, offset = 0; -#endif - DEBUG_PRINT_HIGH("use EGL image support for decoder"); - if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { - DEBUG_PRINT_ERROR("\n "); - } -#ifdef USE_EGL_IMAGE_GPU - if(m_display_id == NULL) { - DEBUG_PRINT_ERROR("Display ID is not set by IL client \n"); - return OMX_ErrorInsufficientResources; - } - egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) - eglGetProcAddress("eglQueryImageKHR"); - egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); - egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); - egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); -#else //with OMX test app - struct temp_egl { - int pmem_fd; - int offset; - }; - struct temp_egl *temp_egl_id = NULL; - void * pmemPtr = (void *) eglImage; - temp_egl_id = (struct temp_egl *)eglImage; - if (temp_egl_id != NULL) - { - fd = temp_egl_id->pmem_fd; - offset = temp_egl_id->offset; - } -#endif - if (fd < 0) { - DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd); - return OMX_ErrorInsufficientResources; - } - pmem_info.pmem_fd = (OMX_U32) fd; - pmem_info.offset = (OMX_U32) offset; - pmem_entry.entry = (void *) &pmem_info; - pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pmem_list.entryList = &pmem_entry; - pmem_list.nEntries = 1; - ouput_egl_buffers = true; - if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, - (void *)&pmem_list, drv_ctx.op_buf.buffer_size, - (OMX_U8 *)pmemPtr)) { - DEBUG_PRINT_ERROR("use buffer call failed for egl image\n"); - return OMX_ErrorInsufficientResources; - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentRoleEnum - -DESCRIPTION - OMX Component Role Enum method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_U8* role, - OMX_IN OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s",role); - } - else - { - DEBUG_PRINT_LOW("No more roles"); - eRet = OMX_ErrorNoMore; - } - } -#ifdef MAX_RES_1080P - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) - ) -#else - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) -#endif - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s",role); - } - else - { - DEBUG_PRINT_LOW("No more roles"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s",role); - } - else - { - DEBUG_PRINT_LOW("No more roles"); - eRet = OMX_ErrorNoMore; - } - } - else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s",role); - } - else - { - DEBUG_PRINT_LOW("No more roles"); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component"); - eRet = OMX_ErrorInvalidComponentName; - } - return eRet; -} - - - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateDone - -DESCRIPTION - Checks if entire buffer pool is allocated by IL Client or not. - Need this to move to IDLE state. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_vdec::allocate_done(void) -{ - bool bRet = false; - bool bRet_In = false; - bool bRet_Out = false; - - bRet_In = allocate_input_done(); - bRet_Out = allocate_output_done(); - - if(bRet_In && bRet_Out) - { - bRet = true; - } - - return bRet; -} -/* ====================================================================== -FUNCTION - omx_vdec::AllocateInputDone - -DESCRIPTION - Checks if I/P buffer pool is allocated by IL Client or not. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_vdec::allocate_input_done(void) -{ - bool bRet = false; - unsigned i=0; - - if (m_inp_mem_ptr == NULL) - { - return bRet; - } - if(m_inp_mem_ptr ) - { - for(;i= drv_ctx.op_buf.actualcount) - { - DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer); - return OMX_ErrorBadParameter; - } - else if (output_flush_progress) - { - DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); - buffer->nFilledLen = 0; - buffer->nTimeStamp = 0; - buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; - buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; - } - -#ifdef _ANDROID_ - char value[PROPERTY_VALUE_MAX]; - property_get("vidc.dec.debug.panframedata", value, NULL); - - if (atoi(value)) - { - if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) - { - DEBUG_PRINT_HIGH("\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - } - - if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) - { - DEBUG_PRINT_HIGH("\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - } - } -#endif - - DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", - buffer, buffer->pBuffer); - pending_output_buffers --; - - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) - { - DEBUG_PRINT_HIGH("Output EOS has been reached"); - if (!output_flush_progress) - post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE); - - if (psource_frame) - { - m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); - psource_frame = NULL; - } - if (pdest_frame) - { - pdest_frame->nFilledLen = 0; - m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); - pdest_frame = NULL; - } - } - - DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer); -#ifdef OUTPUT_BUFFER_LOG - if (outputBufferFile1) - { - OMX_U32 index = buffer - m_out_mem_ptr; - OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; - - fwrite (pBuffer,1,buffer->nFilledLen, - outputBufferFile1); - } -#endif - - /* For use buffer we need to copy the data */ - if (!output_flush_progress) - { - time_stamp_dts.get_next_timestamp(buffer, - (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - } - if (m_cb.FillBufferDone) - { - if (buffer->nFilledLen > 0) - { - if (client_extradata) - { - if(secure_mode) - handle_extradata_secure(buffer); - else - handle_extradata(buffer); - } - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - // Keep min timestamp interval to handle corrupted bit stream scenario - set_frame_rate(buffer->nTimeStamp); - else if (arbitrary_bytes) - adjust_timestamp(buffer->nTimeStamp); -#ifdef _ANDROID_ - if (perf_flag) - { - if (!proc_frms) - { - dec_time.stop(); - latency = dec_time.processing_time_us() - latency; - DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); - dec_time.start(); - fps_metrics.start(); - } - proc_frms++; - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) - { - OMX_U64 proc_time = 0; - fps_metrics.stop(); - proc_time = fps_metrics.processing_time_us(); - DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", - proc_frms, (float)proc_time / 1e6, - (float)(1e6 * proc_frms) / proc_time); - proc_frms = 0; - } - } -#endif //_ANDROID_ - -#ifdef OUTPUT_EXTRADATA_LOG - if (outputExtradataFile) - { - - OMX_U32 index = buffer - m_out_mem_ptr; - OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; - - OMX_OTHER_EXTRADATATYPE *p_extra = NULL; - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(pBuffer + buffer->nOffset + - buffer->nFilledLen + 3)&(~3)); - while(p_extra && - (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) - { - DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); - fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); - if (p_extra->eType == OMX_ExtraDataNone) - { - break; - } - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - } -#endif - } - if (buffer->nFlags & OMX_BUFFERFLAG_EOS){ - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } - - pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) - buffer->pPlatformPrivate)->entryList->entry; - DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - if (native_buffer[buffer - m_out_mem_ptr].inuse) { - if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { - DEBUG_PRINT_ERROR("Unlocking genlock failed"); - return OMX_ErrorInsufficientResources; - } - else { - native_buffer[buffer - m_out_mem_ptr].inuse = false; - } - } - } -#endif - OMX_BUFFERHEADERTYPE *il_buffer; - il_buffer = client_buffers.get_il_buf_hdr(buffer); - if (il_buffer) - m_cb.FillBufferDone (hComp,m_app_data,il_buffer); - else { - DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd); - } - else - { - return OMX_ErrorBadParameter; - } - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE* buffer) -{ - - if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) - { - DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer); - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", - buffer, buffer->pBuffer); - pending_input_buffers--; - - if (arbitrary_bytes) - { - if (pdest_frame == NULL && input_flush_progress == false) - { - DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer); - pdest_frame = buffer; - buffer->nFilledLen = 0; - buffer->nTimeStamp = LLONG_MAX; - push_input_buffer (hComp); - } - else - { - DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer); - buffer->nFilledLen = 0; - if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); - } - } - } - else if(m_cb.EmptyBufferDone) - { - buffer->nFilledLen = 0; - if (input_use_buffer == true){ - buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; - } - m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); - } - return OMX_ErrorNone; -} - - -int omx_vdec::async_message_process (void *context, void* message) -{ - omx_vdec* omx = NULL; - struct vdec_msginfo *vdec_msg = NULL; - OMX_BUFFERHEADERTYPE* omxhdr = NULL; - struct vdec_output_frameinfo *output_respbuf = NULL; - - if (context == NULL || message == NULL) - { - DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); - return -1; - } - vdec_msg = (struct vdec_msginfo *)message; - - omx = reinterpret_cast(context); - -#ifdef _ANDROID_ - if (omx->m_debug_timestamp) - { - if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) && - !(omx->output_flush_progress) ) - { - OMX_TICKS expected_ts = 0; - omx->m_timestamp_list.pop_min_ts(expected_ts); - DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", - vdec_msg->msgdata.output_frame.time_stamp, expected_ts); - - if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts) - { - DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check"); - } - } - } -#endif - - switch (vdec_msg->msgcode) - { - - case VDEC_MSG_EVT_HW_ERROR: - omx->post_event (NULL,vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_HARDWARE_ERROR); - break; - - case VDEC_MSG_RESP_START_DONE: - omx->post_event (NULL,vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_START_DONE); - break; - - case VDEC_MSG_RESP_STOP_DONE: - omx->post_event (NULL,vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - break; - - case VDEC_MSG_RESP_RESUME_DONE: - omx->post_event (NULL,vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_RESUME_DONE); - break; - - case VDEC_MSG_RESP_PAUSE_DONE: - omx->post_event (NULL,vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_PAUSE_DONE); - break; - - case VDEC_MSG_RESP_FLUSH_INPUT_DONE: - omx->post_event (NULL,vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); - break; - case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: - omx->post_event (NULL,vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); - break; - case VDEC_MSG_RESP_INPUT_FLUSHED: - case VDEC_MSG_RESP_INPUT_BUFFER_DONE: - - omxhdr = (OMX_BUFFERHEADERTYPE* )\ - vdec_msg->msgdata.input_frame_clientdata; - - - if (omxhdr == NULL || - ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) - { - omxhdr = NULL; - vdec_msg->status_code = VDEC_S_EFATAL; - } - - omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, - OMX_COMPONENT_GENERATE_EBD); - break; - case VDEC_MSG_EVT_INFO_FIELD_DROPPED: - int64_t *timestamp; - timestamp = (int64_t *) malloc(sizeof(int64_t)); - if (timestamp) { - *timestamp = vdec_msg->msgdata.output_frame.time_stamp; - omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); - DEBUG_PRINT_HIGH("Field dropped time stamp is %lld", - vdec_msg->msgdata.output_frame.time_stamp); - } - break; - case VDEC_MSG_RESP_OUTPUT_FLUSHED: - case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: - omxhdr = (OMX_BUFFERHEADERTYPE*)vdec_msg->msgdata.output_frame.client_data; - DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", - omxhdr, vdec_msg->msgdata.output_frame.time_stamp, - vdec_msg->msgdata.output_frame.pic_type); - - /* update SYNCFRAME flag */ - if (omx->eCompressionFormat == OMX_VIDEO_CodingAVC) - { - /* set SYNCFRAME flag if picture type is IDR for h264 */ - if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_IDR) - vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME; - else - vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME; - } - else - { - /* set SYNCFRAME flag if picture type is I_TYPE */ - if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_I) - vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME; - else - vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME; - } - - if (omxhdr && omxhdr->pOutputPortPrivate && - ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && - (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate - - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) - { - if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) - { - omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; - omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; - omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; - omxhdr->nFlags = (vdec_msg->msgdata.output_frame.flags); - - output_respbuf = (struct vdec_output_frameinfo *)\ - omxhdr->pOutputPortPrivate; - output_respbuf->framesize.bottom = - vdec_msg->msgdata.output_frame.framesize.bottom; - output_respbuf->framesize.left = - vdec_msg->msgdata.output_frame.framesize.left; - output_respbuf->framesize.right = - vdec_msg->msgdata.output_frame.framesize.right; - output_respbuf->framesize.top = - vdec_msg->msgdata.output_frame.framesize.top; - output_respbuf->len = vdec_msg->msgdata.output_frame.len; - output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; - output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp; - output_respbuf->flags = vdec_msg->msgdata.output_frame.flags; - output_respbuf->pic_type = vdec_msg->msgdata.output_frame.pic_type; - output_respbuf->interlaced_format = vdec_msg->msgdata.output_frame.interlaced_format; - output_respbuf->aspect_ratio_info = - vdec_msg->msgdata.output_frame.aspect_ratio_info; - - if (omx->output_use_buffer) - memcpy ( omxhdr->pBuffer, - (vdec_msg->msgdata.output_frame.bufferaddr + - vdec_msg->msgdata.output_frame.offset), - vdec_msg->msgdata.output_frame.len ); - } - else - omxhdr->nFilledLen = 0; - omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_FBD); - } - else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) - omx->post_event (NULL, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_EOS_DONE); - else - omx->post_event (NULL, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_HARDWARE_ERROR); - break; - case VDEC_MSG_EVT_CONFIG_CHANGED: - DEBUG_PRINT_HIGH("Port settings changed"); - omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, - OMX_COMPONENT_GENERATE_PORT_RECONFIG); - break; - case VDEC_MSG_EVT_INFO_CONFIG_CHANGED: - { - DEBUG_PRINT_HIGH("Port settings changed info"); - // get_buffer_req and populate port defn structure - OMX_ERRORTYPE eRet = OMX_ErrorNone; - omx->m_port_def.nPortIndex = 1; - eRet = omx->update_portdef(&(omx->m_port_def)); - omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, - OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG); - break; - } - default: - break; - } - return 1; -} - -OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ) -{ - unsigned address,p2,id; - DEBUG_PRINT_LOW("Empty this arbitrary"); - - if (buffer == NULL) - { - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %d, timestamp %u", - buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp); - - /* return zero length and not an EOS buffer */ - /* return buffer if input flush in progress */ - if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && - ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) - { - DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress"); - m_cb.EmptyBufferDone (hComp,m_app_data,buffer); - return OMX_ErrorNone; - } - - if (psource_frame == NULL) - { - DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp); - psource_frame = buffer; - DEBUG_PRINT_LOW("Try to Push One Input Buffer "); - push_input_buffer (hComp); - } - else - { - DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer); - if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL)) - { - return OMX_ErrorBadParameter; - } - } - - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) -{ - unsigned address,p2,id; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (pdest_frame == NULL || psource_frame == NULL) - { - /*Check if we have a destination buffer*/ - if (pdest_frame == NULL) - { - DEBUG_PRINT_LOW("Get a Destination buffer from the queue"); - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *)address; - pdest_frame->nFilledLen = 0; - pdest_frame->nTimeStamp = LLONG_MAX; - DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame); - } - } - - /*Check if we have a destination buffer*/ - if (psource_frame == NULL) - { - DEBUG_PRINT_LOW("Get a source buffer from the queue"); - if (m_input_pending_q.m_size) - { - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *)address; - DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame, - psource_frame->nTimeStamp); - DEBUG_PRINT_LOW("Next source Buffer flag %d length %d", - psource_frame->nFlags,psource_frame->nFilledLen); - - } - } - - } - - while ((pdest_frame != NULL) && (psource_frame != NULL)) - { - switch (codec_type_parse) - { - case CODEC_TYPE_MPEG4: - case CODEC_TYPE_H263: - case CODEC_TYPE_MPEG2: - ret = push_input_sc_codec(hComp); - break; - case CODEC_TYPE_H264: - ret = push_input_h264(hComp); - break; - case CODEC_TYPE_VC1: - ret = push_input_vc1(hComp); - break; - } - if (ret != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); - omx_report_error (); - break; - } - } - - return ret; -} - -OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) -{ - OMX_U32 partial_frame = 1; - OMX_BOOL generate_ebd = OMX_TRUE; - unsigned address,p2,id; - - DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %d", - psource_frame,psource_frame->nTimeStamp); - if (m_frame_parser.parse_sc_frame(psource_frame, - pdest_frame,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); - return OMX_ErrorBadParameter; - } - - if (partial_frame == 0) - { - DEBUG_PRINT_LOW("Frame size %d source %p frame count %d", - pdest_frame->nFilledLen,psource_frame,frame_count); - - - DEBUG_PRINT_LOW("TimeStamp updated %d",pdest_frame->nTimeStamp); - /*First Parsed buffer will have only header Hence skip*/ - if (frame_count == 0) - { - DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame "); -#ifdef MAX_RES_1080P - if(codec_type_parse == CODEC_TYPE_MPEG4 || - codec_type_parse == CODEC_TYPE_DIVX) { - mp4StreamType psBits; - psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; - psBits.numBytes = pdest_frame->nFilledLen; - mp4_headerparser.parseHeader(&psBits); - } -#endif - frame_count++; - } - else - { - pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; - if(pdest_frame->nFilledLen) - { - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *) address; - pdest_frame->nFilledLen = 0; - } - } - else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) - { - DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL"); - m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL); - pdest_frame = NULL; - } - } - } - else - { - DEBUG_PRINT_LOW("Not a Complete Frame %d",pdest_frame->nFilledLen); - /*Check if Destination Buffer is full*/ - if (pdest_frame->nAllocLen == - pdest_frame->nFilledLen + pdest_frame->nOffset) - { - DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); - return OMX_ErrorStreamCorrupt; - } - } - - if (psource_frame->nFilledLen == 0) - { - if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) - { - if (pdest_frame) - { - pdest_frame->nFlags |= psource_frame->nFlags; - DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("Found a frame size = %d number = %d", - pdest_frame->nFilledLen,frame_count++); - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - } - else - { - DEBUG_PRINT_LOW("Last frame in else dest addr") ; - generate_ebd = OMX_FALSE; - } - } - if(generate_ebd) - { - DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame); - m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); - psource_frame = NULL; - - if (m_input_pending_q.m_size) - { - DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame, - psource_frame->nTimeStamp); - DEBUG_PRINT_LOW("Next source Buffer flag %d length %d", - psource_frame->nFlags,psource_frame->nFilledLen); - } - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) -{ - OMX_U32 partial_frame = 1; - unsigned address,p2,id; - OMX_BOOL isNewFrame = OMX_FALSE; - OMX_BOOL generate_ebd = OMX_TRUE; - - if (h264_scratch.pBuffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %d " - "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); - DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); - if (h264_scratch.nFilledLen && look_ahead_nal) - { - look_ahead_nal = false; - if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame"); - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - if (nal_length == 0) - { - DEBUG_PRINT_LOW("Zero NAL, hence parse using start code"); - if (m_frame_parser.parse_sc_frame(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); - return OMX_ErrorBadParameter; - } - } - else - { - DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); - if (m_frame_parser.parse_h264_nallength(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); - return OMX_ErrorBadParameter; - } - } - - if (partial_frame == 0) - { - if (nal_count == 0 && h264_scratch.nFilledLen == 0) - { - DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip"); - nal_count++; - h264_scratch.nTimeStamp = psource_frame->nTimeStamp; - h264_scratch.nFlags = psource_frame->nFlags; - } - else - { - DEBUG_PRINT_LOW("Parsed New NAL Length = %d",h264_scratch.nFilledLen); - if(h264_scratch.nFilledLen) - { - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, - NALU_TYPE_SPS); -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, - h264_scratch.nFilledLen, NALU_TYPE_SEI); - else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - // If timeinfo is present frame info from SEI is already processed - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, - h264_scratch.nFilledLen, NALU_TYPE_SEI); -#endif - m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); - nal_count++; - if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { - pdest_frame->nTimeStamp = h264_last_au_ts; - pdest_frame->nFlags = h264_last_au_flags; -#ifdef PANSCAN_HDLR - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - h264_parser->update_panscan_data(h264_last_au_ts); -#endif - } - if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || - m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { - h264_last_au_ts = h264_scratch.nTimeStamp; - h264_last_au_flags = h264_scratch.nFlags; -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); - if (!VALID_TS(h264_last_au_ts)) - h264_last_au_ts = ts_in_sei; - } -#endif - } else - h264_last_au_ts = LLONG_MAX; - } - - if (!isNewFrame) - { - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %d", - h264_scratch.nFilledLen); - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) - pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\n Error:2: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - else - { - look_ahead_nal = true; - DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("Found a frame size = %d number = %d", - pdest_frame->nFilledLen,frame_count++); - - if (pdest_frame->nFilledLen == 0) - { - DEBUG_PRINT_LOW("Copy the Current Frame since and push it"); - look_ahead_nal = false; - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - else - { - if(psource_frame->nFilledLen || h264_scratch.nFilledLen) - { - DEBUG_PRINT_LOW("Reset the EOS Flag"); - pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; - } - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - //frame_count++; - pdest_frame = NULL; - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame); - pdest_frame->nFilledLen = 0; - pdest_frame->nFlags = 0; - pdest_frame->nTimeStamp = LLONG_MAX; - } - } - } - } - } - else - { - DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); - /*Check if Destination Buffer is full*/ - if (h264_scratch.nAllocLen == - h264_scratch.nFilledLen + h264_scratch.nOffset) - { - DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); - return OMX_ErrorStreamCorrupt; - } - } - - if (!psource_frame->nFilledLen) - { - DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame); - - if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) - { - if (pdest_frame) - { - DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer"); - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; - pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; -#ifdef MAX_RES_720P - if (frame_count == 0) - { - DEBUG_PRINT_HIGH("No frames sent to driver yet, " - "So send zero length EOS buffer"); - pdest_frame->nFilledLen = 0; - } -#endif - DEBUG_PRINT_LOW("pdest_frame->nFilledLen = %d, nFlags = 0x%x, TimeStamp = %x", - pdest_frame->nFilledLen, pdest_frame->nFlags, pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++); -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); - if (!VALID_TS(pdest_frame->nTimeStamp)) - pdest_frame->nTimeStamp = ts_in_sei; - } -#endif - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - } - else - { - DEBUG_PRINT_LOW("Last frame in else dest addr %p size %d", - pdest_frame,h264_scratch.nFilledLen); - generate_ebd = OMX_FALSE; - } - } - } - if(generate_ebd && !psource_frame->nFilledLen) - { - m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); - psource_frame = NULL; - if (m_input_pending_q.m_size) - { - DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame); - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("Next source Buffer flag %d src length %d", - psource_frame->nFlags,psource_frame->nFilledLen); - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) -{ - OMX_U8 *buf, *pdest; - OMX_U32 partial_frame = 1; - OMX_U32 buf_len, dest_len; - - if(first_frame == 0) - { - first_frame = 1; - DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes"); - if(!m_vendor_config.pData) - { - DEBUG_PRINT_LOW("Check profile type in 1st source buffer"); - buf = psource_frame->pBuffer; - buf_len = psource_frame->nFilledLen; - - if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == - VC1_SP_MP_START_CODE) - { - m_vc1_profile = VC1_SP_MP_RCV; - } - else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) - { - m_vc1_profile = VC1_AP; - } - else - { - DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer"); - return OMX_ErrorStreamCorrupt; - } - } - else - { - pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + - pdest_frame->nOffset; - dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + - pdest_frame->nOffset); - - if(dest_len < m_vendor_config.nDataSize) - { - DEBUG_PRINT_ERROR("\nDestination buffer full"); - return OMX_ErrorBadParameter; - } - else - { - memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); - pdest_frame->nFilledLen += m_vendor_config.nDataSize; - } - } - } - - switch(m_vc1_profile) - { - case VC1_AP: - DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code"); - if (push_input_sc_codec(hComp) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); - return OMX_ErrorBadParameter; - } - break; - - case VC1_SP_MP_RCV: - default: - DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode"); - return OMX_ErrorBadParameter; - } - return OMX_ErrorNone; -} - -#ifndef USE_ION -bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, - OMX_U32 alignment) -{ - struct pmem_allocation allocation; - allocation.size = buffer_size; - allocation.align = clip2(alignment); - if (allocation.align < 4096) - { - allocation.align = 4096; - } - if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) - { - DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", - allocation.align, allocation.size); - return false; - } - return true; -} -#endif - -#ifdef USE_ION -int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, - OMX_U32 alignment, struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data,int flag) -{ - int fd = -EINVAL; - int rc = -EINVAL; - int ion_dev_flag; - struct vdec_ion ion_buf_info; - if (!alloc_data || buffer_size <= 0 || !fd_data) { - DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n"); - return -EINVAL; - } - - ion_dev_flag = O_RDONLY; - fd = open (MEM_DEVICE, ion_dev_flag); - if (fd < 0) { - DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd); - return fd; - } - alloc_data->flags = 0; - if(!secure_mode && (flag & ION_FLAG_CACHED)) - { - alloc_data->flags |= ION_FLAG_CACHED; - } - - alloc_data->len = buffer_size; - alloc_data->align = clip2(alignment); - if (alloc_data->align < 4096) - { - alloc_data->align = 4096; - } - if(secure_mode) { - if(external_meta_buffer) { - alloc_data->heap_mask = ION_HEAP(ION_CP_MFC_HEAP_ID); - alloc_data->flags |= ION_SECURE; - } else if (external_meta_buffer_iommu) { - alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); - } else { - alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); - alloc_data->flags |= ION_SECURE; - } - } else { -#ifdef MAX_RES_720P - alloc_data->len = (buffer_size + (alloc_data->align - 1)) & ~(alloc_data->align - 1); - alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); -#else - alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID)); -#endif - } - - rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); - if (rc || !alloc_data->handle) { - DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); - alloc_data->handle = NULL; - close(fd); - fd = -ENOMEM; - return fd; - } - fd_data->handle = alloc_data->handle; - rc = ioctl(fd,ION_IOC_MAP,fd_data); - if (rc) { - DEBUG_PRINT_ERROR("\n ION MAP failed "); - ion_buf_info.ion_alloc_data = *alloc_data; - ion_buf_info.ion_device_fd = fd; - ion_buf_info.fd_ion_data = *fd_data; - free_ion_memory(&ion_buf_info); - fd_data->fd =-1; - close(fd); - fd = -ENOMEM; - } - DEBUG_PRINT_HIGH("ION: alloc_data: handle(0x%X), len(%u), align(%u), " - "flags(0x%x), fd_data: handle(0x%x), fd(0x%x)", - alloc_data->handle, alloc_data->len, alloc_data->align, - alloc_data->flags, fd_data->handle, fd_data->fd); - return fd; -} - -void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) { - - if(!buf_ion_info) { - DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata"); - return; - } - DEBUG_PRINT_HIGH("ION: free: handle(0x%X), len(%u), fd(0x%x)", - buf_ion_info->ion_alloc_data.handle, - buf_ion_info->ion_alloc_data.len, - buf_ion_info->fd_ion_data.fd); - if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, - &buf_ion_info->ion_alloc_data.handle)) { - DEBUG_PRINT_ERROR("\n ION: free failed" ); - } - close(buf_ion_info->ion_device_fd); - buf_ion_info->ion_device_fd = -1; - buf_ion_info->ion_alloc_data.handle = NULL; - buf_ion_info->fd_ion_data.fd = -1; -} -#endif -void omx_vdec::free_output_buffer_header() -{ - DEBUG_PRINT_HIGH("ALL output buffers are freed/released"); - output_use_buffer = false; - ouput_egl_buffers = false; - - if (m_out_mem_ptr) - { - free (m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - - if(m_platform_list) - { - free(m_platform_list); - m_platform_list = NULL; - } - - if (drv_ctx.ptr_respbuffer) - { - free (drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } - if (drv_ctx.ptr_outputbuffer) - { - free (drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif -} - -void omx_vdec::free_input_buffer_header() -{ - input_use_buffer = false; - if (arbitrary_bytes) - { - if (m_frame_parser.mutils) - { - DEBUG_PRINT_LOW("Free utils parser"); - delete (m_frame_parser.mutils); - m_frame_parser.mutils = NULL; - } - - if (m_inp_heap_ptr) - { - DEBUG_PRINT_LOW("Free input Heap Pointer"); - free (m_inp_heap_ptr); - m_inp_heap_ptr = NULL; - } - - if (m_phdr_pmem_ptr) - { - DEBUG_PRINT_LOW("Free input pmem header Pointer"); - free (m_phdr_pmem_ptr); - m_phdr_pmem_ptr = NULL; - } - } - if (m_inp_mem_ptr) - { - DEBUG_PRINT_LOW("Free input pmem Pointer area"); - free (m_inp_mem_ptr); - m_inp_mem_ptr = NULL; - } - if (drv_ctx.ptr_inputbuffer) - { - DEBUG_PRINT_LOW("Free Driver Context pointer"); - free (drv_ctx.ptr_inputbuffer); - drv_ctx.ptr_inputbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.ip_buf_ion_info) { - DEBUG_PRINT_LOW("Free ion context"); - free(drv_ctx.ip_buf_ion_info); - drv_ctx.ip_buf_ion_info = NULL; - } -#endif -} - -OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) -{ - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int buf_size = 0, extra_data_size = 0; - DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - ioctl_msg.in = NULL; - ioctl_msg.out = buffer_prop; - if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_GET_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - buf_size = buffer_prop->buffer_size; - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - { - DEBUG_PRINT_HIGH("Frame info extra data enabled!"); - extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; - } - if (client_extradata & OMX_INTERLACE_EXTRADATA) - { - DEBUG_PRINT_HIGH("Interlace extra data enabled!"); - extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; - } - if (client_extradata & OMX_PORTDEF_EXTRADATA) - { - extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; - DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d", - extra_data_size); - } - if (extra_data_size) - { - extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator - buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit - } - buf_size += extra_data_size; - buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); - DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size, buf_size); - if (in_reconfig) // BufReq will be set to driver when port is disabled - buffer_prop->buffer_size = buf_size; - else if (buf_size != buffer_prop->buffer_size) - { - buffer_prop->buffer_size = buf_size; - eRet = set_buffer_req(buffer_prop); - } - } - DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - return eRet; -} - -OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) -{ - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned buf_size = 0; - DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); - if (buf_size != buffer_prop->buffer_size) - { - DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", - buffer_prop->buffer_size, buf_size); - eRet = OMX_ErrorBadParameter; - } - else - { - ioctl_msg.in = buffer_prop; - ioctl_msg.out = NULL; - if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Setting buffer requirements failed"); - eRet = OMX_ErrorInsufficientResources; - } else { - if (!client_buffers.update_buffer_req()) { - DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); - eRet = OMX_ErrorInsufficientResources; - } - } - } - return eRet; -} - -OMX_ERRORTYPE omx_vdec::start_port_reconfig() -{ - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - eRet = update_picture_resolution(); - if (eRet == OMX_ErrorNone) - { - ioctl_msg.out = &drv_ctx.interlace; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_INTERLACE_FORMAT, &ioctl_msg)) - { - DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_INTERLACE_FORMAT"); - eRet = OMX_ErrorHardware; - } - else - { - if (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - { - DEBUG_PRINT_HIGH("Interlace format detected (%x)!", drv_ctx.interlace); - client_extradata |= OMX_INTERLACE_EXTRADATA; - } - in_reconfig = true; - op_buf_rcnfg.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - eRet = get_buffer_req(&op_buf_rcnfg); - } - } - - if (eRet == OMX_ErrorNone) { - //update power HAL with new width, height and bitrate - power_module_deregister(); - power_module_register(); - } - - return eRet; -} - -OMX_ERRORTYPE omx_vdec::update_picture_resolution() -{ - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - ioctl_msg.in = NULL; - ioctl_msg.out = &drv_ctx.video_resolution; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)) - { - DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES"); - eRet = OMX_ErrorHardware; - } - return eRet; -} - -OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (!portDefn) - { - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("omx_vdec::update_portdef"); - portDefn->nVersion.nVersion = OMX_SPEC_VERSION; - portDefn->nSize = sizeof(portDefn); - portDefn->eDomain = OMX_PortDomainVideo; - if (drv_ctx.frame_rate.fps_denominator > 0) - portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / - drv_ctx.frame_rate.fps_denominator; - else { - DEBUG_PRINT_ERROR("Error: Divide by zero \n"); - return OMX_ErrorBadParameter; - } - if (0 == portDefn->nPortIndex) - { - portDefn->eDir = OMX_DirInput; - portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; - portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; - portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH; - portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; - portDefn->format.video.eCompressionFormat = eCompressionFormat; - portDefn->bEnabled = m_inp_bEnabled; - portDefn->bPopulated = m_inp_bPopulated; - } - else if (1 == portDefn->nPortIndex) - { - portDefn->eDir = OMX_DirOutput; - if (update_picture_resolution() != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("update_picture_resolution failed \n"); - return OMX_ErrorHardware; - } - if (!client_buffers.update_buffer_req()) { - DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed"); - return OMX_ErrorHardware; - } - if (in_reconfig) - { - portDefn->nBufferCountActual = op_buf_rcnfg.actualcount; - portDefn->nBufferCountMin = op_buf_rcnfg.mincount; - portDefn->nBufferSize = op_buf_rcnfg.buffer_size; - } - else - { - portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; - portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; - portDefn->nBufferSize = drv_ctx.op_buf.buffer_size; - } - unsigned int buf_size = 0; - if (!client_buffers.get_buffer_req(buf_size)) { - DEBUG_PRINT_ERROR("\n update buffer requirements"); - return OMX_ErrorHardware; - } - portDefn->nBufferSize = buf_size; - portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - portDefn->bEnabled = m_out_bEnabled; - portDefn->bPopulated = m_out_bPopulated; - if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { - DEBUG_PRINT_ERROR("\n Error in getting color format"); - return OMX_ErrorHardware; - } - } - else - { - portDefn->eDir = OMX_DirMax; - DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; - portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; - portDefn->format.video.nStride = drv_ctx.video_resolution.stride; - portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; - DEBUG_PRINT_LOW("update_portdef: PortIndex = %u, Width = %d Height = %d " - "Stride = %u SliceHeight = %u output format = 0x%x, eColorFormat = 0x%x", - portDefn->nPortIndex, - portDefn->format.video.nFrameHeight, - portDefn->format.video.nFrameWidth, - portDefn->format.video.nStride, - portDefn->format.video.nSliceHeight, - drv_ctx.output_format, - portDefn->format.video.eColorFormat); - return eRet; -} - -OMX_ERRORTYPE omx_vdec::allocate_output_headers() -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr = NULL; - unsigned i= 0; - - if(!m_out_mem_ptr) { - DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation"); - int nBufHdrSize = 0; - int nPlatformEntrySize = 0; - int nPlatformListSize = 0; - int nPMEMInfoSize = 0; - OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; - - DEBUG_PRINT_LOW("Setting First Output Buffer(%d)", - drv_ctx.op_buf.actualcount); - nBufHdrSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_BUFFERHEADERTYPE); - - nPMEMInfoSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); - nPlatformListSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); - nPlatformEntrySize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); - - DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize, - sizeof(OMX_BUFFERHEADERTYPE), - nPMEMInfoSize, - nPlatformListSize); - DEBUG_PRINT_LOW("PE %d bmSize %d ",nPlatformEntrySize, - m_out_bm_count); - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - // Alloc mem for platform specific info - char *pPtr=NULL; - pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + - nPMEMInfoSize,1); - drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ - calloc (sizeof(struct vdec_bufferpayload), - drv_ctx.op_buf.actualcount); - drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ - calloc (sizeof (struct vdec_output_frameinfo), - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ - calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); -#endif - - if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer - && drv_ctx.ptr_respbuffer) - { - bufHdr = m_out_mem_ptr; - m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); - m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) - (((char *) m_platform_list) + nPlatformListSize); - m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - (((char *) m_platform_entry) + nPlatformEntrySize); - pPlatformList = m_platform_list; - pPlatformEntry = m_platform_entry; - pPMEMInfo = m_pmem_info; - - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); - - // Settting the entire storage nicely - DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, - m_out_mem_ptr,pPlatformEntry); - DEBUG_PRINT_LOW(" Pmem Info = %p ",pPMEMInfo); - for(i=0; i < drv_ctx.op_buf.actualcount ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = 0; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = NULL; - bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pPlatformEntry->entry = pPMEMInfo; - // Initialize the Platform List - pPlatformList->nEntries = 1; - pPlatformList->entryList = pPlatformEntry; - // Keep pBuffer NULL till vdec is opened - bufHdr->pBuffer = NULL; - pPMEMInfo->offset = 0; - pPMEMInfo->pmem_fd = 0; - bufHdr->pPlatformPrivate = pPlatformList; - drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; -#endif - /*Create a mapping between buffers*/ - bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; - drv_ctx.ptr_respbuffer[i].client_data = (void *) \ - &drv_ctx.ptr_outputbuffer[i]; - // Move the buffer and buffer header pointers - bufHdr++; - pPMEMInfo++; - pPlatformEntry++; - pPlatformList++; - } - } - else - { - DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\ - m_out_mem_ptr, pPtr); - if(m_out_mem_ptr) - { - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(pPtr) - { - free(pPtr); - pPtr = NULL; - } - if(drv_ctx.ptr_outputbuffer) - { - free(drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } - if(drv_ctx.ptr_respbuffer) - { - free(drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif - eRet = OMX_ErrorInsufficientResources; - } - } else { - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - -void omx_vdec::complete_pending_buffer_done_cbs() -{ - unsigned p1; - unsigned p2; - unsigned ident; - omx_cmd_queue tmp_q, pending_bd_q; - pthread_mutex_lock(&m_lock); - // pop all pending GENERATE FDB from ftb queue - while (m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_FBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to ftb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_ftb_q.insert_entry(p1,p2,ident); - } - // pop all pending GENERATE EDB from etb queue - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_EBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to etb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_etb_q.insert_entry(p1,p2,ident); - } - pthread_mutex_unlock(&m_lock); - // process all pending buffer dones - while(pending_bd_q.m_size) - { - pending_bd_q.pop_entry(&p1,&p2,&ident); - switch(ident) - { - case OMX_COMPONENT_GENERATE_EBD: - if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); - omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FBD: - if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); - omx_report_error (); - } - break; - } - } -} - -void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) -{ - OMX_U32 new_frame_interval = 0; - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts - && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000)) - { - new_frame_interval = (act_timestamp > prev_ts)? - act_timestamp - prev_ts : - prev_ts - act_timestamp; - if (new_frame_interval < frm_int || frm_int == 0) - { - frm_int = new_frame_interval; - if(frm_int) - { - drv_ctx.frame_rate.fps_numerator = 1e6; - drv_ctx.frame_rate.fps_denominator = frm_int; - DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", - frm_int, drv_ctx.frame_rate.fps_numerator / - (float)drv_ctx.frame_rate.fps_denominator); - ioctl_msg.in = &drv_ctx.frame_rate; - if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Setting frame rate failed"); - } - } - } - } - prev_ts = act_timestamp; -} - -void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) -{ - if (rst_prev_ts && VALID_TS(act_timestamp)) - { - prev_ts = act_timestamp; - rst_prev_ts = false; - } - else if (VALID_TS(prev_ts)) - { - bool codec_cond = (drv_ctx.timestamp_adjust)? - (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? - (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): - (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); - if(frm_int > 0 && codec_cond) - { - DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); - act_timestamp = prev_ts + frm_int; - DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); - prev_ts = act_timestamp; - } - else - set_frame_rate(act_timestamp); - } - else if (frm_int > 0) // In this case the frame rate was set along - { // with the port definition, start ts with 0 - act_timestamp = prev_ts = 0; // and correct if a valid ts is received. - rst_prev_ts = true; - } -} - -void omx_vdec::handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr) -{ - OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_extn_user[32]; - struct vdec_output_frameinfo *output_respbuf; - OMX_U32 num_conceal_MB = 0; - OMX_S64 ts_in_sei = 0; - OMX_U32 frame_rate = 0; - OMX_U32 extn_user_data_cnt = 0; - - OMX_U32 index = p_buf_hdr - m_out_mem_ptr; - OMX_U8 *meta_buffer_virtual = (OMX_U8 *)meta_buff.buffer; - - - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(meta_buffer_virtual + - index * drv_ctx.op_buf.meta_buffer_size + 3)&(~3)); - - //mapping of ouput buffer to the corresponding meta buffer - output_respbuf = (struct vdec_output_frameinfo *)\ - p_buf_hdr->pOutputPortPrivate; - output_respbuf->metadata_info.metabufaddr = (OMX_U8 *)p_extra; - output_respbuf->metadata_info.size = - drv_ctx.op_buf.meta_buffer_size; - - meta_buffer_virtual = (OMX_U8 *)p_extra; - - if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)) - { - // Process driver extradata - while(p_extra && p_extra->eType != VDEC_EXTRADATA_NONE) - { - DEBUG_PRINT_LOW("handle_extradata_secure : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)", - p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize); - if (p_extra->nSize < p_extra->nDataSize) - { - DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d", - p_extra->nSize, p_extra->nDataSize); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - if((OMX_U8*)p_extra > (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size) || - p_extra->nDataSize == 0 || p_extra->nSize == 0) - p_extra = NULL; - continue; - } - if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP) - { - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - num_conceal_MB = count_MB_in_extradata(p_extra); - if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP) - // Map driver extradata to corresponding OMX type - p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB; - else - p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client -#ifdef _ANDROID_ - if (m_debug_concealedmb) { - DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB); - } -#endif /* _ANDROID_ */ - } - else if (p_extra->eType == VDEC_EXTRADATA_SEI) - { - p_sei = p_extra; -#ifdef MAX_RES_1080P - h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); -#endif - p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client - } - else if (p_extra->eType == VDEC_EXTRADATA_VUI) - { - p_vui = p_extra; -#ifdef MAX_RES_1080P - h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); -#endif - p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client - } - else if (p_extra->eType == VDEC_EXTRADATA_EXT_DATA) - { - OMX_U8 *data_ptr = (OMX_U8*)p_extra->data; - OMX_U32 value = 0; - p_extn_user[extn_user_data_cnt] = p_extra; - extn_user_data_cnt++; - if((*data_ptr & 0xf0) == 0x20) - { - value = ((*data_ptr) & 0x01); - data_ptr++; - if (value) - data_ptr += 3; - value = *((OMX_U32*)data_ptr); - value = ((value << 24) | (((value >> 8)<<24)>>8) | - (((value >> 16)<<24)>>16) | (value >> 24)); - m_disp_hor_size = (value & 0xfffc0000)>>18; - m_disp_vert_size = (value & 0x0001fff8)>>3; - DEBUG_PRINT_LOW("Display Vertical Size = %d Display Horizontal Size = %d", - m_disp_vert_size, m_disp_hor_size); - } - } - else if (p_extra->eType == VDEC_EXTRADATA_USER_DATA) - { - p_extn_user[extn_user_data_cnt] = p_extra; - extn_user_data_cnt++; - } - print_debug_extradata(p_extra); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - - if((OMX_U8*)p_extra > (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size) || - p_extra->nDataSize == 0 || p_extra->nSize == 0) - p_extra = NULL; - } - if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)) - { - //moving p_extra to the starting location of the metadata buffer - p_extra = (OMX_OTHER_EXTRADATATYPE *)meta_buffer_virtual; - // Driver extradata is only exposed if MB map is requested by client, - // otherwise can be overwritten by omx extradata. - p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - } - } - - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - if (p_vui) - h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); - if (p_sei) - h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); - ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp); - if (!VALID_TS(p_buf_hdr->nTimeStamp)) - p_buf_hdr->nTimeStamp = ts_in_sei; - } - else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei) - // If timeinfo is present frame info from SEI is already processed - h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); - } - - if (client_extradata & OMX_EXTNUSER_EXTRADATA && p_extra) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - for(int i = 0; i < extn_user_data_cnt; i++) - { - if (((OMX_U8*)p_extra + p_extn_user[i]->nSize) < - (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) - { - if (p_extn_user[i]->eType == VDEC_EXTRADATA_EXT_DATA) - { - append_extn_extradata(p_extra, p_extn_user[i]); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - else if (p_extn_user[i]->eType == VDEC_EXTRADATA_USER_DATA) - { - append_user_extradata(p_extra, p_extn_user[i]); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - } - } - } - if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra && - ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) < - (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - append_interlace_extradata(p_extra, - ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format, index); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra && - ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < - (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - /* vui extra data (frame_rate) information */ - if (h264_parser) - h264_parser->get_frame_rate(&frame_rate); - append_frame_info_extradata(p_extra, num_conceal_MB, - ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, - p_buf_hdr->nTimeStamp, frame_rate, - &((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - if ((client_extradata & OMX_PORTDEF_EXTRADATA) && - p_extra != NULL && - ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) < - (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - append_portdef_extradata(p_extra); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) - if (p_extra && - ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < - (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) - append_terminator_extradata(p_extra); - else - { - DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added"); - p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - } -} - -void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) -{ - OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_extn_user[32]; - OMX_U32 num_conceal_MB = 0; - OMX_S64 ts_in_sei = 0; - OMX_U32 frame_rate = 0; - OMX_U32 extn_user_data_cnt = 0; - - OMX_U32 index = p_buf_hdr - m_out_mem_ptr; - OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr; - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(pBuffer + p_buf_hdr->nOffset + - p_buf_hdr->nFilledLen + 3)&(~3)); - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) - p_extra = NULL; - if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)) - { - // Process driver extradata - while(p_extra && p_extra->eType != VDEC_EXTRADATA_NONE) - { - DEBUG_PRINT_LOW("handle_extradata : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)", - p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize); - if (p_extra->nSize < p_extra->nDataSize) - { - DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d", - p_extra->nSize, p_extra->nDataSize); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) || - p_extra->nDataSize == 0 || p_extra->nSize == 0) - p_extra = NULL; - continue; - } - if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP) - { - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - num_conceal_MB = count_MB_in_extradata(p_extra); - if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP) - // Map driver extradata to corresponding OMX type - p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB; - else - p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client -#ifdef _ANDROID_ - if (m_debug_concealedmb) { - DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB); - } -#endif /* _ANDROID_ */ - } - else if (p_extra->eType == VDEC_EXTRADATA_SEI) - { - p_sei = p_extra; -#ifdef MAX_RES_1080P - h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); -#endif - p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client - } - else if (p_extra->eType == VDEC_EXTRADATA_VUI) - { - p_vui = p_extra; -#ifdef MAX_RES_1080P - h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); -#endif - p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client - } - else if (p_extra->eType == VDEC_EXTRADATA_EXT_DATA) - { - OMX_U8 *data_ptr = (OMX_U8*)p_extra->data; - OMX_U32 value = 0; - p_extn_user[extn_user_data_cnt] = p_extra; - extn_user_data_cnt++; - if((*data_ptr & 0xf0) == 0x20) - { - value = ((*data_ptr) & 0x01); - data_ptr++; - if (value) - data_ptr += 3; - value = *((OMX_U32*)data_ptr); - value = ((value << 24) | (((value >> 8)<<24)>>8) | - (((value >> 16)<<24)>>16) | (value >> 24)); - m_disp_hor_size = (value & 0xfffc0000)>>18; - m_disp_vert_size = (value & 0x0001fff8)>>3; - DEBUG_PRINT_LOW("Display Vertical Size = %d Display Horizontal Size = %d", - m_disp_vert_size, m_disp_hor_size); - } - } - else if (p_extra->eType == VDEC_EXTRADATA_USER_DATA) - { - p_extn_user[extn_user_data_cnt] = p_extra; - extn_user_data_cnt++; - } - print_debug_extradata(p_extra); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) || - p_extra->nDataSize == 0 || p_extra->nSize == 0) - p_extra = NULL; - } - if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)) - { - // Driver extradata is only exposed if MB map is requested by client, - // otherwise can be overwritten by omx extradata. - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(pBuffer + p_buf_hdr->nOffset + - p_buf_hdr->nFilledLen + 3)&(~3)); - p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - } - } - -#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - if (p_vui) - h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false); - if (p_sei) - h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); - ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp); - if (!VALID_TS(p_buf_hdr->nTimeStamp)) - p_buf_hdr->nTimeStamp = ts_in_sei; - } - else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei) - // If timeinfo is present frame info from SEI is already processed - h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI); - } -#endif - if (client_extradata & OMX_EXTNUSER_EXTRADATA && p_extra) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - for(int i = 0; i < extn_user_data_cnt; i++) - { - if (((OMX_U8*)p_extra + p_extn_user[i]->nSize) < - (pBuffer + p_buf_hdr->nAllocLen)) - { - if (p_extn_user[i]->eType == VDEC_EXTRADATA_EXT_DATA) - { - append_extn_extradata(p_extra, p_extn_user[i]); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - else if (p_extn_user[i]->eType == VDEC_EXTRADATA_USER_DATA) - { - append_user_extradata(p_extra, p_extn_user[i]); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - } - } - } - if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra && - ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) < - (pBuffer + p_buf_hdr->nAllocLen)) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - append_interlace_extradata(p_extra, - ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format, index); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra && - ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < - (pBuffer + p_buf_hdr->nAllocLen)) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - /* vui extra data (frame_rate) information */ - if (h264_parser) - h264_parser->get_frame_rate(&frame_rate); - append_frame_info_extradata(p_extra, num_conceal_MB, - ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, - p_buf_hdr->nTimeStamp, frame_rate, - &((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - if ((client_extradata & OMX_PORTDEF_EXTRADATA) && - p_extra != NULL && - ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) < - (pBuffer + p_buf_hdr->nAllocLen)) - { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - append_portdef_extradata(p_extra); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) - if (p_extra && - ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) < - (pBuffer + p_buf_hdr->nAllocLen)) - append_terminator_extradata(p_extra); - else - { - DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added"); - p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - } -} - -OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, bool enable) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_U32 driver_extradata = 0, extradata_size = 0; - struct vdec_ioctl_msg ioctl_msg = {NULL, NULL}; - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); - return OMX_ErrorIncorrectStateOperation; - } - if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) - extradata_size += OMX_FRAMEINFO_EXTRADATA_SIZE; - if (requested_extradata & OMX_INTERLACE_EXTRADATA) - extradata_size += OMX_INTERLACE_EXTRADATA_SIZE; - if (requested_extradata & OMX_PORTDEF_EXTRADATA) - { - extradata_size += OMX_PORTDEF_EXTRADATA_SIZE; - } - DEBUG_PRINT_ERROR("enable_extradata: actual[%x] requested[%x] enable[%d]", - client_extradata, requested_extradata, enable); - - if (enable) - requested_extradata |= client_extradata; - else - { - requested_extradata = client_extradata & ~requested_extradata; - extradata_size *= -1; - } - - driver_extradata = requested_extradata & DRIVER_EXTRADATA_MASK; - - if(secure_mode) - driver_extradata = driver_extradata | VDEC_EXTRADATA_EXT_BUFFER; - - if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) - driver_extradata |= VDEC_EXTRADATA_MB_ERROR_MAP; // Required for conceal MB frame info - if (drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) - { - driver_extradata |= ((requested_extradata & OMX_EXTNUSER_EXTRADATA)? - VDEC_EXTRADATA_EXT_DATA | VDEC_EXTRADATA_USER_DATA : 0); - } -#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - driver_extradata |= ((requested_extradata & OMX_FRAMEINFO_EXTRADATA)? - VDEC_EXTRADATA_SEI : 0); // Required for pan scan frame info - driver_extradata |= ((requested_extradata & OMX_TIMEINFO_EXTRADATA)? - VDEC_EXTRADATA_VUI | VDEC_EXTRADATA_SEI : 0); //Required for time info - } - -#endif - if (driver_extradata != drv_ctx.extradata) - { - client_extradata = requested_extradata; - drv_ctx.extradata = driver_extradata; - ioctl_msg.in = &drv_ctx.extradata; - ioctl_msg.out = NULL; - if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_EXTRADATA, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nSet extradata failed"); - ret = OMX_ErrorUnsupportedSetting; - } - else - ret = get_buffer_req(&drv_ctx.op_buf); - } - else if ((client_extradata & ~DRIVER_EXTRADATA_MASK) != (requested_extradata & ~DRIVER_EXTRADATA_MASK)) - { - client_extradata = requested_extradata; - drv_ctx.op_buf.buffer_size += extradata_size; - // align the buffer size - drv_ctx.op_buf.buffer_size = (drv_ctx.op_buf.buffer_size + drv_ctx.op_buf.alignment - 1)&(~(drv_ctx.op_buf.alignment - 1)); - DEBUG_PRINT_LOW("Aligned buffer size with exreadata = %d", drv_ctx.op_buf.buffer_size); - if (!(client_extradata & ~DRIVER_EXTRADATA_MASK)) // If no omx extradata is required remove space for terminator - drv_ctx.op_buf.buffer_size -= sizeof(OMX_OTHER_EXTRADATATYPE); - ret = set_buffer_req(&drv_ctx.op_buf); - } - return ret; -} - -OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; - OMX_U8 *data_ptr = extra->data, data = 0; - while (byte_count < extra->nDataSize) - { - data = *data_ptr; - while (data) - { - num_MB += (data&0x01); - data >>= 1; - } - data_ptr++; - byte_count++; - } - num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * - (drv_ctx.video_resolution.frame_height + 15)) >> 8; - return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); -} - -void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ -#ifdef _ANDROID_ - if (!m_debug_extradata) - return; - - DEBUG_PRINT_HIGH( - "============== Extra Data ==============\n" - " Size: %u \n" - " Version: %u \n" - " PortIndex: %u \n" - " Type: %x \n" - " DataSize: %u \n", - extra->nSize, extra->nVersion.nVersion, - extra->nPortIndex, extra->eType, extra->nDataSize); - - if (extra->eType == OMX_ExtraDataInterlaceFormat) - { - OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; - DEBUG_PRINT_HIGH( - "------ Interlace Format ------\n" - " Size: %u \n" - " Version: %u \n" - " PortIndex: %u \n" - " Is Interlace Format: %u \n" - " Interlace Formats: %u \n" - "=========== End of Interlace ===========\n", - intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, - intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); - } - else if (extra->eType == OMX_ExtraDataFrameInfo) - { - OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; - - DEBUG_PRINT_HIGH( - "-------- Frame Format --------\n" - " Picture Type: %u \n" - " Interlace Type: %u \n" - " Pan Scan Total Frame Num: %u \n" - " Concealed Macro Blocks: %u \n" - " frame rate: %u \n" - " Aspect Ratio X: %u \n" - " Aspect Ratio Y: %u \n", - fminfo->ePicType, - fminfo->interlaceType, - fminfo->panScan.numWindows, - fminfo->nConcealedMacroblocks, - fminfo->nFrameRate, - fminfo->aspectRatio.aspectRatioX, - fminfo->aspectRatio.aspectRatioY); - - for (int i = 0; i < fminfo->panScan.numWindows; i++) - { - DEBUG_PRINT_HIGH( - "------------------------------\n" - " Pan Scan Frame Num: %d \n" - " Rectangle x: %d \n" - " Rectangle y: %d \n" - " Rectangle dx: %d \n" - " Rectangle dy: %d \n", - i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, - fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); - } - - DEBUG_PRINT_HIGH("========= End of Frame Format =========="); - } - else if (extra->eType == OMX_ExtraDataNone) - { - DEBUG_PRINT_HIGH("========== End of Terminator ==========="); - } - else - { - DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); - } -#endif /* _ANDROID_ */ -} - -void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 interlaced_format_type, OMX_U32 buf_index) -{ - OMX_STREAMINTERLACEFORMAT *interlace_format; - OMX_U32 mbaff = 0; -#if defined(_ANDROID_ICS_) - OMX_U32 enable = 0; - private_handle_t *handle = NULL; - handle = (private_handle_t *)native_buffer[buf_index].nativehandle; - if(!handle) - DEBUG_PRINT_LOW("%s: Native Buffer handle is NULL",__func__); -#endif - extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; - extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); - interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; - interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); - interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; - interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; - if ((interlaced_format_type == VDEC_InterlaceFrameProgressive) && !mbaff) - { - interlace_format->bInterlaceFormat = OMX_FALSE; - interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; -#if defined(_ANDROID_ICS_) - if(handle) - { - setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable); - } -#endif - } - else - { - interlace_format->bInterlaceFormat = OMX_TRUE; - interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; - drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; -#if defined(_ANDROID_ICS_) - enable = 1; - if(handle) - { - setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable); - } -#endif - } - print_debug_extradata(extra); -} - -void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_S64 timestamp, - OMX_U32 frame_rate, struct vdec_aspectratioinfo *aspect_ratio_info) -{ - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; - extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; - extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); - frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; - - switch (picture_type) - { - case PICTURE_TYPE_I: - frame_info->ePicType = OMX_VIDEO_PictureTypeI; - break; - case PICTURE_TYPE_P: - frame_info->ePicType = OMX_VIDEO_PictureTypeP; - break; - case PICTURE_TYPE_B: - frame_info->ePicType = OMX_VIDEO_PictureTypeB; - break; - default: - frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; - } - if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) - frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; - else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) - frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; - else - frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; - memset(&frame_info->panScan,0,sizeof(frame_info->panScan)); - memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); - memset(&frame_info->displayAspectRatio, 0, sizeof(frame_info->displayAspectRatio)); - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - h264_parser->fill_pan_scan_data(&frame_info->panScan, timestamp); - } - - fill_aspect_ratio_info(aspect_ratio_info, frame_info); - if (drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) - { - if (m_disp_hor_size && m_disp_vert_size) - { - frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size; - frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size; - } - } - frame_info->nConcealedMacroblocks = num_conceal_mb; - frame_info->nFrameRate = frame_rate; - print_debug_extradata(extra); -} - -void omx_vdec::fill_aspect_ratio_info( - struct vdec_aspectratioinfo *aspect_ratio_info, - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) -{ - m_extradata = frame_info; - if(drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) - { - switch(aspect_ratio_info->aspect_ratio) - { - case 1: - m_extradata->aspectRatio.aspectRatioX = 1; - m_extradata->aspectRatio.aspectRatioY = 1; - break; - case 2: - if (m_disp_hor_size && m_disp_vert_size) - { - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * - m_disp_vert_size; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * - m_disp_hor_size; - } - else - { - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * - drv_ctx.video_resolution.frame_height; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * - drv_ctx.video_resolution.frame_width; - } - break; - case 3: - if (m_disp_hor_size && m_disp_vert_size) - { - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * - m_disp_vert_size; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * - m_disp_hor_size; - } - else - { - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * - drv_ctx.video_resolution.frame_height; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * - drv_ctx.video_resolution.frame_width; - } - break; - case 4: - if (m_disp_hor_size && m_disp_vert_size) - { - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * - m_disp_vert_size; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * - m_disp_hor_size; - } - else - { - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width * - drv_ctx.video_resolution.frame_height; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height * - drv_ctx.video_resolution.frame_width; - } - break; - default: - m_extradata->aspectRatio.aspectRatioX = 1; - m_extradata->aspectRatio.aspectRatioY = 1; - } - } - else - { - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; - } - DEBUG_PRINT_LOW("aspectRatioX %d aspectRatioX %d", m_extradata->aspectRatio.aspectRatioX, - m_extradata->aspectRatio.aspectRatioY); -} - -void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; - extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; - extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; - *portDefn = m_port_def; - DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u" - "sliceheight = %u",portDefn->format.video.nFrameHeight, - portDefn->format.video.nFrameWidth, - portDefn->format.video.nStride, - portDefn->format.video.nSliceHeight); -} - -void omx_vdec::append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_OTHER_EXTRADATATYPE *p_extn) -{ - extra->nDataSize = p_extn->nDataSize; - extra->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + extra->nDataSize); - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2ExtnData; - if (extra->data && p_extn->data && extra->nDataSize) - memcpy(extra->data, p_extn->data, extra->nDataSize); -} - -void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_OTHER_EXTRADATATYPE *p_user) -{ - extra->nDataSize = p_user->nDataSize; - extra->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + extra->nDataSize); - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData; - if (extra->data && p_user->data && extra->nDataSize) - memcpy(extra->data, p_user->data, extra->nDataSize); -} - -void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->eType = OMX_ExtraDataNone; - extra->nDataSize = 0; - extra->data[0] = 0; - - print_debug_extradata(extra); -} - -OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (index >= drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found"); - return OMX_ErrorInsufficientResources; - } - if (m_desc_buffer_ptr == NULL) - { - m_desc_buffer_ptr = (desc_buffer_hdr*) \ - calloc( (sizeof(desc_buffer_hdr)), - drv_ctx.ip_buf.actualcount); - if (m_desc_buffer_ptr == NULL) - { - DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - } - - m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); - if (m_desc_buffer_ptr[index].buf_addr == NULL) - { - DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed "); - return OMX_ErrorInsufficientResources; - } - - return eRet; -} - -void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) -{ - DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries); - if (m_demux_entries < 8192) - { - m_demux_offsets[m_demux_entries++] = address_offset; - } - return; -} - -void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) -{ - OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; - OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; - OMX_U32 index = 0; - OMX_U32 prev_sc_index = 0; - - m_demux_entries = 0; - - while (index < bytes_to_parse) - { - if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && - (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || - ((buf[index] == 0x00) && (buf[index+1] == 0x00) && - (buf[index+2] == 0x01)) ) - { - if ((((index+3) - prev_sc_index) <= 4) && m_demux_entries) - { - DEBUG_PRINT_ERROR("FOUND Consecutive start Code, Hence skip one"); - m_demux_entries--; - } - //Found start code, insert address offset - insert_demux_addr_offset(index); - if (buf[index+2] == 0x01) // 3 byte start code - index += 3; - else //4 byte start code - index += 4; - prev_sc_index = index; - } - else - index++; - } - DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries); - return; -} - -OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) -{ - //fix this, handle 3 byte start code, vc1 terminator entry - OMX_U8 *p_demux_data = NULL; - OMX_U32 desc_data = 0; - OMX_U32 start_addr = 0; - OMX_U32 nal_size = 0; - OMX_U32 suffix_byte = 0; - OMX_U32 demux_index = 0; - OMX_U32 buffer_index = 0; - - if (m_desc_buffer_ptr == NULL) - { - DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); - return OMX_ErrorBadParameter; - } - - buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - if (buffer_index > drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index); - return OMX_ErrorBadParameter; - } - - p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; - - if ( ((OMX_U8*)p_demux_data == NULL) || - ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) - { - DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); - return OMX_ErrorBadParameter; - } - else - { - for (; demux_index < m_demux_entries; demux_index++) - { - desc_data = 0; - start_addr = m_demux_offsets[demux_index]; - if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) - { - suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; - } - else - { - suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; - } - if (demux_index < (m_demux_entries - 1)) - { - nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; - } - else - { - nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; - } - DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)", - start_addr, - suffix_byte, - nal_size, - demux_index); - desc_data = (start_addr >> 3) << 1; - desc_data |= (start_addr & 7) << 21; - desc_data |= suffix_byte << 24; - - memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); - memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); - memset(p_demux_data + 8, 0, sizeof(OMX_U32)); - memset(p_demux_data + 12, 0, sizeof(OMX_U32)); - - p_demux_data += 16; - } - if (codec_type_parse == CODEC_TYPE_VC1) - { - DEBUG_PRINT_LOW("VC1 terminator entry"); - desc_data = 0; - desc_data = 0x82 << 24; - memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); - memset(p_demux_data + 4, 0, sizeof(OMX_U32)); - memset(p_demux_data + 8, 0, sizeof(OMX_U32)); - memset(p_demux_data + 12, 0, sizeof(OMX_U32)); - p_demux_data += 16; - m_demux_entries++; - } - //Add zero word to indicate end of descriptors - memset(p_demux_data, 0, sizeof(OMX_U32)); - - m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); - DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size); - } - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - DEBUG_PRINT_LOW("Demux table complete!"); - return OMX_ErrorNone; -} - -#ifdef MAX_RES_1080P - -OMX_ERRORTYPE omx_vdec::vdec_alloc_meta_buffers() -{ - OMX_U32 pmem_fd = -1, pmem_fd_iommu = -1; - OMX_U32 size, alignment; - void *buf_addr = NULL; - struct vdec_ioctl_msg ioctl_msg; -#ifndef USE_ION - struct pmem_allocation allocation; -#endif - struct vdec_meta_buffers meta_buffer; - - memset ((unsigned char*)&meta_buffer,0,sizeof (struct vdec_meta_buffers)); - - //we already have meta buffer size. - size = drv_ctx.op_buf.meta_buffer_size * drv_ctx.op_buf.actualcount; - alignment = 8192; - - -#ifdef USE_ION - external_meta_buffer = true; - drv_ctx.meta_buffer.ion_device_fd = alloc_map_ion_memory( - size, 8192, - &drv_ctx.meta_buffer.ion_alloc_data, - &drv_ctx.meta_buffer.fd_ion_data, 0); - if (drv_ctx.meta_buffer.ion_device_fd < 0) { - external_meta_buffer = false; - return OMX_ErrorInsufficientResources; - } - external_meta_buffer = false; - pmem_fd = drv_ctx.meta_buffer.fd_ion_data.fd; - - external_meta_buffer_iommu = true; - drv_ctx.meta_buffer_iommu.ion_device_fd = alloc_map_ion_memory( - size, 8192, - &drv_ctx.meta_buffer_iommu.ion_alloc_data, - &drv_ctx.meta_buffer_iommu.fd_ion_data, 0); - if (drv_ctx.meta_buffer_iommu.ion_device_fd < 0) { - external_meta_buffer_iommu = false; - return OMX_ErrorInsufficientResources; - } - external_meta_buffer_iommu = false; - pmem_fd_iommu = drv_ctx.meta_buffer_iommu.fd_ion_data.fd; -#else - allocation.size = size; - allocation.align = clip2(alignment); - if (allocation.align != 8192) - allocation.align = 8192; - - pmem_fd = open(MEM_DEVICE, O_RDWR); - - if ((int)(pmem_fd) < 0) - return OMX_ErrorInsufficientResources; - - if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) - { - DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", - allocation.align, allocation.size); - return OMX_ErrorInsufficientResources; - } -#endif - - buf_addr = mmap(NULL, size, - PROT_READ | PROT_WRITE, - MAP_SHARED, pmem_fd_iommu, 0); - - if (buf_addr == (void*) MAP_FAILED) - { - close(pmem_fd); - close(pmem_fd_iommu); -#ifdef USE_ION - free_ion_memory(&drv_ctx.meta_buffer); - free_ion_memory(&drv_ctx.meta_buffer_iommu); -#endif - pmem_fd = -1; - pmem_fd_iommu = -1; - DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr); - return OMX_ErrorInsufficientResources; - } - - meta_buffer.size = size; - meta_buffer.count = drv_ctx.op_buf.actualcount; - meta_buffer.pmem_fd = pmem_fd; - meta_buffer.pmem_fd_iommu = pmem_fd_iommu; - meta_buffer.offset = 0; - - ioctl_msg.in = (void*)&meta_buffer; - ioctl_msg.out = NULL; - - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_META_BUFFERS, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Failed to set the meta_buffers\n"); - return OMX_ErrorInsufficientResources; - } - - meta_buff.buffer = (unsigned char *) buf_addr; - meta_buff.size = size; - meta_buff.count = drv_ctx.op_buf.actualcount; - meta_buff.offset = 0; - meta_buff.pmem_fd = pmem_fd; - meta_buff.pmem_fd_iommu = pmem_fd_iommu; - DEBUG_PRINT_HIGH("Saving virt:%p, FD: %d and FD_IOMMU %d of size %d count: %d", meta_buff.buffer, - meta_buff.pmem_fd, meta_buff.pmem_fd_iommu, meta_buff.size, drv_ctx.op_buf.actualcount); - return OMX_ErrorNone; -} - -void omx_vdec::vdec_dealloc_meta_buffers() -{ - if(meta_buff.pmem_fd > 0) - { - if(ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_META_BUFFERS,NULL) < 0) - DEBUG_PRINT_ERROR("VDEC_IOCTL_FREE_META_BUFFERS failed"); - close(meta_buff.pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.meta_buffer); -#endif - } - if(meta_buff.pmem_fd_iommu > 0) - { - munmap(meta_buff.buffer, meta_buff.size); - close(meta_buff.pmem_fd_iommu); -#ifdef USE_ION - free_ion_memory(&drv_ctx.meta_buffer_iommu); -#endif - DEBUG_PRINT_LOW("Cleaning Meta buffer of size %d",meta_buff.size); - meta_buff.pmem_fd = -1; - meta_buff.pmem_fd_iommu = -1; - meta_buff.offset = 0; - meta_buff.size = 0; - meta_buff.count = 0; - meta_buff.buffer = NULL; - } -} - -OMX_ERRORTYPE omx_vdec::vdec_alloc_h264_mv() -{ - OMX_U32 pmem_fd = -1; - OMX_U32 width, height, size, alignment; - void *buf_addr = NULL; - struct vdec_ioctl_msg ioctl_msg; -#ifndef USE_ION - struct pmem_allocation allocation; -#endif - struct vdec_h264_mv h264_mv; - struct vdec_mv_buff_size mv_buff_size; - - mv_buff_size.width = drv_ctx.video_resolution.stride; - mv_buff_size.height = drv_ctx.video_resolution.scan_lines>>2; - - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&mv_buff_size; - - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_GET_MV_BUFFER_SIZE, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n GET_MV_BUFFER_SIZE Failed for width: %d, Height %d" , - mv_buff_size.width, mv_buff_size.height); - return OMX_ErrorInsufficientResources; - } - - DEBUG_PRINT_ERROR("GET_MV_BUFFER_SIZE returned: Size: %d and alignment: %d", - mv_buff_size.size, mv_buff_size.alignment); - - size = mv_buff_size.size * drv_ctx.op_buf.actualcount; - alignment = mv_buff_size.alignment; - - DEBUG_PRINT_LOW("Entered vdec_alloc_h264_mv act_width: %d, act_height: %d, size: %d, alignment %d", - drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height,size,alignment); - - -#ifdef USE_ION - drv_ctx.h264_mv.ion_device_fd = alloc_map_ion_memory( - size, 8192, - &drv_ctx.h264_mv.ion_alloc_data, - &drv_ctx.h264_mv.fd_ion_data,ION_FLAG_CACHED); - if (drv_ctx.h264_mv.ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - pmem_fd = drv_ctx.h264_mv.fd_ion_data.fd; -#else - allocation.size = size; - allocation.align = clip2(alignment); - if (allocation.align != 8192) - allocation.align = 8192; - - pmem_fd = open(MEM_DEVICE, O_RDWR); - - if ((int)(pmem_fd) < 0) - return OMX_ErrorInsufficientResources; - - if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) - { - DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", - allocation.align, allocation.size); - return OMX_ErrorInsufficientResources; - } -#endif - if(!secure_mode) { - buf_addr = mmap(NULL, size, - PROT_READ | PROT_WRITE, - MAP_SHARED, pmem_fd, 0); - - if (buf_addr == (void*) MAP_FAILED) - { - close(pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.h264_mv); -#endif - pmem_fd = -1; - DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr); - return OMX_ErrorInsufficientResources; - } - } else - buf_addr =(unsigned char *) (pmem_fd + 1234); - DEBUG_PRINT_LOW("Allocated virt:%p, FD: %d of size %d count: %d", buf_addr, - pmem_fd, size, drv_ctx.op_buf.actualcount); - - h264_mv.size = size; - h264_mv.count = drv_ctx.op_buf.actualcount; - h264_mv.pmem_fd = pmem_fd; - h264_mv.offset = 0; - - ioctl_msg.in = (void*)&h264_mv; - ioctl_msg.out = NULL; - - if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_H264_MV_BUFFER, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Failed to set the H264_mv_buffers\n"); - return OMX_ErrorInsufficientResources; - } - - h264_mv_buff.buffer = (unsigned char *) buf_addr; - h264_mv_buff.size = size; - h264_mv_buff.count = drv_ctx.op_buf.actualcount; - h264_mv_buff.offset = 0; - h264_mv_buff.pmem_fd = pmem_fd; - DEBUG_PRINT_LOW("Saving virt:%p, FD: %d of size %d count: %d", h264_mv_buff.buffer, - h264_mv_buff.pmem_fd, h264_mv_buff.size, drv_ctx.op_buf.actualcount); - return OMX_ErrorNone; -} - -void omx_vdec::vdec_dealloc_h264_mv() -{ - if(h264_mv_buff.pmem_fd > 0) - { - if(ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_H264_MV_BUFFER,NULL) < 0) - DEBUG_PRINT_ERROR("VDEC_IOCTL_FREE_H264_MV_BUFFER failed"); - if(!secure_mode) - munmap(h264_mv_buff.buffer, h264_mv_buff.size); - close(h264_mv_buff.pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.h264_mv); -#endif - DEBUG_PRINT_LOW("Cleaning H264_MV buffer of size %d",h264_mv_buff.size); - h264_mv_buff.pmem_fd = -1; - h264_mv_buff.offset = 0; - h264_mv_buff.size = 0; - h264_mv_buff.count = 0; - h264_mv_buff.buffer = NULL; - } -} - -#endif - -#ifdef _ANDROID_ -OMX_ERRORTYPE omx_vdec::createDivxDrmContext() -{ - OMX_ERRORTYPE err = OMX_ErrorNone; - iDivXDrmDecrypt = DivXDrmDecrypt::Create(); - if (iDivXDrmDecrypt) { - OMX_ERRORTYPE err = iDivXDrmDecrypt->Init(); - if(err!=OMX_ErrorNone) { - DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err); - delete iDivXDrmDecrypt; - iDivXDrmDecrypt = NULL; - } - } - else { - DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM"); - err = OMX_ErrorUndefined; - } - return err; -} -#endif //_ANDROID_ - -OMX_ERRORTYPE omx_vdec::power_module_register() -{ - char powerHintMetadata[512]; - - if (m_power_hinted) { - return OMX_ErrorBadParameter; //need a proper error code - } - - PowerModule * pm = PowerModule::getInstance(); - - if (pm == NULL) { - DEBUG_PRINT_ERROR("failed to get power module instance"); - return OMX_ErrorBadParameter; - } - - power_module_t * ph = pm->getPowerModuleHandle(); - - if (ph == NULL) { - DEBUG_PRINT_ERROR("failed to get power module handle"); - return OMX_ErrorBadParameter; - } - - if (ph->powerHint) { - snprintf(powerHintMetadata, sizeof(powerHintMetadata) - 1, - "state=1;framewidth=%u;frameheight=%u;bitrate=%u", - m_port_def.format.video.nFrameWidth, m_port_def.format.video.nFrameHeight, - m_port_def.format.video.nBitrate); - powerHintMetadata[sizeof(powerHintMetadata) - 1] = '\0'; - - ph->powerHint(ph, POWER_HINT_VIDEO_DECODE, (void *)powerHintMetadata); - m_power_hinted = true; - } else { - DEBUG_PRINT_ERROR("No hint called for register"); - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::power_module_deregister() -{ - if (!m_power_hinted) { - return OMX_ErrorBadParameter; //need a proper error code - } - - PowerModule * pm = PowerModule::getInstance(); - - if (pm == NULL) { - DEBUG_PRINT_ERROR("failed to get power module instance"); - return OMX_ErrorBadParameter; - } - - power_module_t * ph = pm->getPowerModuleHandle(); - - if (ph == NULL) { - DEBUG_PRINT_ERROR("failed to get power module handle"); - return OMX_ErrorBadParameter; - } - - if (ph->powerHint) { - ph->powerHint(ph, POWER_HINT_VIDEO_DECODE, (void *)"state=0"); - m_power_hinted = false; - } else { - DEBUG_PRINT_ERROR("No hint called for deregister"); - } - return OMX_ErrorNone; -} -omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() -{ - enabled = false; - omx = NULL; - init_members(); - ColorFormat = OMX_COLOR_FormatMax; -} - -void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) -{ - omx = reinterpret_cast(client); -} - -void omx_vdec::allocate_color_convert_buf::init_members() { - allocated_count = 0; - buffer_size_req = 0; - buffer_alignment_req = 0; - memset(m_platform_list_client,0,sizeof(m_platform_list_client)); - memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); - memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); - memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); - memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); - for (int i = 0; i < MAX_COUNT;i++) - pmem_fd[i] = -1; -} - -omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() { - c2d.destroy(); -} - -bool omx_vdec::allocate_color_convert_buf::update_buffer_req() -{ - bool status = true; - unsigned int src_size = 0, destination_size = 0; - OMX_COLOR_FORMATTYPE drv_color_format; - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid client in color convert"); - return false; - } - if (!enabled){ - DEBUG_PRINT_ERROR("\n No color conversion required"); - return status; - } - if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_TILE_4x2 && - ColorFormat != OMX_COLOR_FormatYUV420Planar) { - DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion"); - return false; - } - c2d.close(); - status = c2d.open(omx->drv_ctx.video_resolution.frame_height, - omx->drv_ctx.video_resolution.frame_width, - YCbCr420Tile,YCbCr420P); - if (status) { - status = c2d.get_buffer_size(C2D_INPUT,src_size); - if (status) - status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); - } - if (status) { - if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || - !destination_size) { - DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d" - "driver size %d destination size %d", - src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); - status = false; - c2d.close(); - buffer_size_req = 0; - } else { - buffer_size_req = destination_size; - if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) - buffer_size_req = omx->drv_ctx.op_buf.buffer_size; - if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) - buffer_alignment_req = omx->drv_ctx.op_buf.alignment; - } - } - return status; -} - -bool omx_vdec::allocate_color_convert_buf::set_color_format( - OMX_COLOR_FORMATTYPE dest_color_format) -{ - bool status = true; - OMX_COLOR_FORMATTYPE drv_color_format; - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid client in color convert"); - return false; - } - if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2) - drv_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; - else { - DEBUG_PRINT_ERROR("\n Incorrect color format"); - status = false; - } - if (status && (drv_color_format != dest_color_format)) { - DEBUG_PRINT_ERROR(""); - if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { - DEBUG_PRINT_ERROR("\n Unsupported color format for c2d"); - status = false; - } else { - ColorFormat = OMX_COLOR_FormatYUV420Planar; - if (enabled) - c2d.destroy(); - enabled = false; - if (!c2d.init()) { - DEBUG_PRINT_ERROR("\n open failed for c2d"); - status = false; - } else - enabled = true; - } - } else { - if (enabled) - c2d.destroy(); - enabled = false; - } - return status; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return omx->m_out_mem_ptr; - return m_out_mem_ptr_client; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr - (OMX_BUFFERHEADERTYPE *bufadd) -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return bufadd; - unsigned index = 0; - index = bufadd - omx->m_out_mem_ptr; - if (index < omx->drv_ctx.op_buf.actualcount) { - m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); - m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; - bool status; - if (!omx->in_reconfig && !omx->output_flush_progress) { - status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, - bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]); - m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; - if (!status){ - DEBUG_PRINT_ERROR("\n Failed color conversion %d", status); - return NULL; - } - } else - m_out_mem_ptr_client[index].nFilledLen = 0; - return &m_out_mem_ptr_client[index]; - } - DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr"); - return NULL; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr - (OMX_BUFFERHEADERTYPE *bufadd) -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return bufadd; - unsigned index = 0; - index = bufadd - m_out_mem_ptr_client; - if (index < omx->drv_ctx.op_buf.actualcount) { - return &omx->m_out_mem_ptr[index]; - } - DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr"); - return NULL; -} -bool omx_vdec::allocate_color_convert_buf::get_buffer_req - (unsigned int &buffer_size) -{ - if (!enabled) - buffer_size = omx->drv_ctx.op_buf.buffer_size; - else - if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { - DEBUG_PRINT_ERROR("\n Get buffer size failed"); - return false; - } - if (buffer_size < omx->drv_ctx.op_buf.buffer_size) - buffer_size = omx->drv_ctx.op_buf.buffer_size; - if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) - buffer_alignment_req = omx->drv_ctx.op_buf.alignment; - return true; -} -OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( - OMX_BUFFERHEADERTYPE *bufhdr) { - unsigned int index = 0; - - if (!enabled) - return omx->free_output_buffer(bufhdr); - if (enabled && omx->is_component_secure()) - return OMX_ErrorNone; - if (!allocated_count || !bufhdr) { - DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr); - return OMX_ErrorBadParameter; - } - index = bufhdr - m_out_mem_ptr_client; - if (index >= omx->drv_ctx.op_buf.actualcount){ - DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer"); - return OMX_ErrorBadParameter; - } - if (pmem_fd[index] > 0) { - munmap(pmem_baseaddress[index], buffer_size_req); - close(pmem_fd[index]); - } - pmem_fd[index] = -1; - omx->free_ion_memory(&op_buf_ion_info[index]); - m_heap_ptr[index].video_heap_ptr = NULL; - if (allocated_count > 0) - allocated_count--; - else - allocated_count = 0; - if (!allocated_count) { - c2d.close(); - init_members(); - } - return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); -} - -OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (!enabled){ - eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); - return eRet; - } - if (enabled && omx->is_component_secure()) { - DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d", - omx->is_component_secure()); - return OMX_ErrorUnsupportedSetting; - } - if (!bufferHdr || bytes > buffer_size_req) { - DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr); - DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %d", - buffer_size_req,bytes); - return OMX_ErrorBadParameter; - } - if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert"); - return OMX_ErrorInsufficientResources; - } - OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; - eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, - port,appData,omx->drv_ctx.op_buf.buffer_size); - if (eRet != OMX_ErrorNone || !temp_bufferHdr){ - DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert"); - return eRet; - } - if ((temp_bufferHdr - omx->m_out_mem_ptr) >= - omx->drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("\n Invalid header index %d", - (temp_bufferHdr - omx->m_out_mem_ptr)); - return OMX_ErrorUndefined; - } - unsigned int i = allocated_count; - op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( - buffer_size_req,buffer_alignment_req, - &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, - ION_FLAG_CACHED); - - pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; - if (op_buf_ion_info[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert"); - return OMX_ErrorInsufficientResources; - } - pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, - PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); - - if (pmem_baseaddress[i] == MAP_FAILED) { - DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req); - close(pmem_fd[i]); - omx->free_ion_memory(&op_buf_ion_info[i]); - return OMX_ErrorInsufficientResources; - } - m_heap_ptr[i].video_heap_ptr = new VideoHeap ( - op_buf_ion_info[i].ion_device_fd,buffer_size_req, - pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); - m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); - m_pmem_info_client[i].offset = 0; - m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; - m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - m_platform_list_client[i].nEntries = 1; - m_platform_list_client[i].entryList = &m_platform_entry_client[i]; - m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; - m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; - m_out_mem_ptr_client[i].nFilledLen = 0; - m_out_mem_ptr_client[i].nFlags = 0; - m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); - m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; - m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; - m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; - m_out_mem_ptr_client[i].pAppPrivate = appData; - *bufferHdr = &m_out_mem_ptr_client[i]; - DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr); - allocated_count++; - return eRet; -} - -bool omx_vdec::is_component_secure() -{ - return secure_mode; -} - -bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) -{ - bool status = true; - if (!enabled) { - if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2) - dest_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; - else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) - dest_color_format = OMX_COLOR_FormatYUV420SemiPlanar; - else - status = false; - } else { - if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { - status = false; - } else - dest_color_format = OMX_COLOR_FormatYUV420Planar; - } - return status; -} diff --git a/mm-video/vidc/vdec/src/omx_vdec_hevc.cpp b/mm-video/vidc/vdec/src/omx_vdec_hevc.cpp deleted file mode 100644 index 2b8fc200..00000000 --- a/mm-video/vidc/vdec/src/omx_vdec_hevc.cpp +++ /dev/null @@ -1,9516 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -/*============================================================================ - O p e n M A X w r a p p e r s - O p e n M A X C o r e - -*//** @file omx_vdec.cpp - This module contains the implementation of the OpenMAX core & component. - -*//*========================================================================*/ - -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include "omx_vdec_hevc.h" -#include -#include -#include - -#ifndef _ANDROID_ -#include -#include -#endif //_ANDROID_ - -#ifdef _ANDROID_ -#include -#undef USE_EGL_IMAGE_GPU -#endif - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -#include -#endif - -#if defined (_ANDROID_ICS_) -#include -#include -#endif - -#ifdef _ANDROID_ -#include "DivXDrmDecrypt.h" -#endif //_ANDROID_ - -#ifdef USE_EGL_IMAGE_GPU -#include -#include -#define EGL_BUFFER_HANDLE_QCOM 0x4F00 -#define EGL_BUFFER_OFFSET_QCOM 0x4F01 -#endif - -#ifdef INPUT_BUFFER_LOG -#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" -#define INPUT_BUFFER_FILE_NAME_LEN 30 -FILE *inputBufferFile1; -char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; -#endif -#ifdef OUTPUT_BUFFER_LOG -FILE *outputBufferFile1; -char outputfilename [] = "/data/output.yuv"; -#endif -#ifdef OUTPUT_EXTRADATA_LOG -FILE *outputExtradataFile; -char ouputextradatafilename [] = "/data/extradata"; -#endif - -#define DEFAULT_FPS 30 -#define MAX_INPUT_ERROR DEFAULT_FPS -#define MAX_SUPPORTED_FPS 120 - -#define VC1_SP_MP_START_CODE 0xC5000000 -#define VC1_SP_MP_START_CODE_MASK 0xFF000000 -#define VC1_AP_SEQ_START_CODE 0x0F010000 -#define VC1_STRUCT_C_PROFILE_MASK 0xF0 -#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 -#define VC1_SIMPLE_PROFILE 0 -#define VC1_MAIN_PROFILE 1 -#define VC1_ADVANCE_PROFILE 3 -#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 -#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 -#define VC1_STRUCT_C_LEN 4 -#define VC1_STRUCT_C_POS 8 -#define VC1_STRUCT_A_POS 12 -#define VC1_STRUCT_B_POS 24 -#define VC1_SEQ_LAYER_SIZE 36 -#define POLL_TIMEOUT 0x7fffffff - -#define MEM_DEVICE "/dev/ion" -#define MEM_HEAP_ID ION_CP_MM_HEAP_ID - -#ifdef _ANDROID_ - extern "C"{ - #include - } -#endif//_ANDROID_ - -#define SZ_4K 0x1000 -#define SZ_1M 0x100000 - -#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } -#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } -#define EXTRADATA_IDX(__num_planes) (__num_planes - 1) - -#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA) -void* async_message_thread (void *input) -{ - OMX_BUFFERHEADERTYPE *buffer; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - struct pollfd pfd; - struct v4l2_buffer v4l2_buf; - memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); - struct v4l2_event dqevent; - omx_vdec *omx = reinterpret_cast(input); - pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; - pfd.fd = omx->drv_ctx.video_driver_fd; - int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; - DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n"); - prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); - while (1) - { - rc = poll(&pfd, 1, POLL_TIMEOUT); - if (!rc) { - DEBUG_PRINT_ERROR("Poll timedout\n"); - break; - } else if (rc < 0) { - DEBUG_PRINT_ERROR("Error while polling: %d\n", rc); - break; - } - if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { - struct vdec_msginfo vdec_msg; - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - v4l2_buf.memory = V4L2_MEMORY_USERPTR; - v4l2_buf.length = omx->drv_ctx.num_planes; - v4l2_buf.m.planes = plane; - while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { - vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; - vdec_msg.msgdata.output_frame.len=plane[0].bytesused; - vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; - vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + - (uint64_t)v4l2_buf.timestamp.tv_usec; - if (vdec_msg.msgdata.output_frame.len) { - vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2]; - vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3]; - vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4]; - vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5]; - } - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } - } - if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { - struct vdec_msginfo vdec_msg; - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - v4l2_buf.memory = V4L2_MEMORY_USERPTR; - v4l2_buf.length = 1; - v4l2_buf.m.planes = plane; - while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { - vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } - } - if (pfd.revents & POLLPRI){ - rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); - if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { - struct vdec_msginfo vdec_msg; - vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT ) { - struct vdec_msginfo vdec_msg; - vdec_msg.msgcode=VDEC_MSG_EVT_INFO_CONFIG_CHANGED; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { - struct vdec_msginfo vdec_msg; - vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("\n VIDC Flush Done Recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { - DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n"); - break; - } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { - struct vdec_msginfo vdec_msg; - vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("\n SYS Error Recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } else { - DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n"); - continue; - } - } - } - DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n"); - return NULL; -} - -void* message_thread(void *input) -{ - omx_vdec* omx = reinterpret_cast(input); - unsigned char id; - int n; - if (omx == NULL) - { - DEBUG_PRINT_ERROR("message thread null pointer rxd\n"); - return NULL; - } - - DEBUG_PRINT_HIGH("omx_vdec: message thread start\n"); - prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); - while (1) - { - - n = read(omx->m_pipe_in, &id, 1); - - if(0 == n) - { - break; - } - - if (1 == n) - { - omx->process_event_cb(omx, id); - } - if ((n < 0) && (errno != EINTR)) - { - DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); - break; - } - } - DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n"); - return NULL; -} - -void post_message(omx_vdec *omx, unsigned char id) -{ - int ret_value; - - if (omx == NULL) - { - DEBUG_PRINT_ERROR("message thread null pointer rxd\n"); - return; - } - DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out); - ret_value = write(omx->m_pipe_out, &id, 1); - DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value); -} - -// omx_cmd_queue destructor -omx_vdec::omx_cmd_queue::~omx_cmd_queue() -{ - // Nothing to do -} - -// omx cmd queue constructor -omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) -{ - memset(m_q,0,sizeof(m_q)); -} - -// omx cmd queue insert -bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) -{ - bool ret = true; - if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_q[m_write].id = id; - m_q[m_write].param1 = p1; - m_q[m_write].param2 = p2; - m_write++; - m_size ++; - if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_write = 0; - } - } - else - { - ret = false; - DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__); - } - return ret; -} - -// omx cmd queue pop -bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) -{ - bool ret = true; - if (m_size > 0) - { - *id = m_q[m_read].id; - *p1 = m_q[m_read].param1; - *p2 = m_q[m_read].param2; - // Move the read pointer ahead - ++m_read; - --m_size; - if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_read = 0; - } - } - else - { - ret = false; - } - return ret; -} - -// Retrieve the first mesg type in the queue -unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() -{ - return m_q[m_read].id; -} - -#ifdef _ANDROID_ -omx_vdec::ts_arr_list::ts_arr_list() -{ - //initialize timestamps array - memset(m_ts_arr_list, 0, sizeof(m_ts_arr_list) ); -} -omx_vdec::ts_arr_list::~ts_arr_list() -{ - //free m_ts_arr_list? -} - -bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) -{ - bool ret = true; - bool duplicate_ts = false; - int idx = 0; - - //insert at the first available empty location - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - if (!m_ts_arr_list[idx].valid) - { - //found invalid or empty entry, save timestamp - m_ts_arr_list[idx].valid = true; - m_ts_arr_list[idx].timestamp = ts; - DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", - ts, idx); - break; - } - } - - if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) - { - DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); - ret = false; - } - return ret; -} - -bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) -{ - bool ret = true; - int min_idx = -1; - OMX_TICKS min_ts = 0; - int idx = 0; - - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - - if (m_ts_arr_list[idx].valid) - { - //found valid entry, save index - if (min_idx < 0) - { - //first valid entry - min_ts = m_ts_arr_list[idx].timestamp; - min_idx = idx; - } - else if (m_ts_arr_list[idx].timestamp < min_ts) - { - min_ts = m_ts_arr_list[idx].timestamp; - min_idx = idx; - } - } - - } - - if (min_idx < 0) - { - //no valid entries found - DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); - ts = 0; - ret = false; - } - else - { - ts = m_ts_arr_list[min_idx].timestamp; - m_ts_arr_list[min_idx].valid = false; - DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", - ts, min_idx); - } - - return ret; - -} - - -bool omx_vdec::ts_arr_list::reset_ts_list() -{ - bool ret = true; - int idx = 0; - - DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - m_ts_arr_list[idx].valid = false; - } - return ret; -} -#endif - -// factory function executed by the core to create instances -void *get_omx_component_factory_fn(void) -{ - return (new omx_vdec); -} - -#ifdef _ANDROID_ -#ifdef USE_ION -VideoHeap::VideoHeap(int devicefd, size_t size, void* base, - struct ion_handle *handle, int ionMapfd) -{ -// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); -} -#else -VideoHeap::VideoHeap(int fd, size_t size, void* base) -{ - // dup file descriptor, map once, use pmem - init(dup(fd), base, size, 0 , MEM_DEVICE); -} -#endif -#endif // _ANDROID_ -/* ====================================================================== -FUNCTION - omx_vdec::omx_vdec - -DESCRIPTION - Constructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_vdec::omx_vdec(): m_error_propogated(false), - m_state(OMX_StateInvalid), - m_app_data(NULL), - m_inp_mem_ptr(NULL), - m_out_mem_ptr(NULL), - m_inp_err_count(0), - input_flush_progress (false), - output_flush_progress (false), - input_use_buffer (false), - output_use_buffer (false), - ouput_egl_buffers(false), - m_use_output_pmem(OMX_FALSE), - m_out_mem_region_smi(OMX_FALSE), - m_out_pvt_entry_pmem(OMX_FALSE), - pending_input_buffers(0), - pending_output_buffers(0), - m_out_bm_count(0), - m_inp_bm_count(0), - m_inp_bPopulated(OMX_FALSE), - m_out_bPopulated(OMX_FALSE), - m_flags(0), -#ifdef _ANDROID_ - m_heap_ptr(NULL), -#endif - m_inp_bEnabled(OMX_TRUE), - m_out_bEnabled(OMX_TRUE), - m_in_alloc_cnt(0), - m_platform_list(NULL), - m_platform_entry(NULL), - m_pmem_info(NULL), - arbitrary_bytes (true), - psource_frame (NULL), - pdest_frame (NULL), - m_inp_heap_ptr (NULL), - m_phdr_pmem_ptr(NULL), - m_heap_inp_bm_count (0), - codec_type_parse ((codec_type)0), - first_frame_meta (true), - frame_count (0), - nal_count (0), - nal_length(0), - look_ahead_nal (false), - first_frame(0), - first_buffer(NULL), - first_frame_size (0), - m_device_file_ptr(NULL), - m_vc1_profile((vc1_profile_type)0), - h264_last_au_ts(LLONG_MAX), - h264_last_au_flags(0), - prev_ts(LLONG_MAX), - rst_prev_ts(true), - frm_int(0), - in_reconfig(false), - m_display_id(NULL), - h264_parser(NULL), - client_extradata(0), -#ifdef _ANDROID_ - m_enable_android_native_buffers(OMX_FALSE), - m_use_android_native_buffers(OMX_FALSE), - iDivXDrmDecrypt(NULL), -#endif - m_desc_buffer_ptr(NULL), - secure_mode(false) -{ - /* Assumption is that , to begin with , we have all the frames with decoder */ - DEBUG_PRINT_HIGH("In OMX vdec Constructor"); -#ifdef _ANDROID_ - char property_value[PROPERTY_VALUE_MAX] = {0}; - property_get("vidc.dec.debug.perf", property_value, "0"); - perf_flag = atoi(property_value); - if (perf_flag) - { - DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); - dec_time.start(); - proc_frms = latency = 0; - } - property_value[0] = '\0'; - property_get("vidc.dec.debug.ts", property_value, "0"); - m_debug_timestamp = atoi(property_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); - if (m_debug_timestamp) - { - time_stamp_dts.set_timestamp_reorder_mode(true); - time_stamp_dts.enable_debug_print(true); - } - - property_value[0] = '\0'; - property_get("vidc.dec.debug.concealedmb", property_value, "0"); - m_debug_concealedmb = atoi(property_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); - -#endif - memset(&m_cmp,0,sizeof(m_cmp)); - memset(&m_cb,0,sizeof(m_cb)); - memset (&drv_ctx,0,sizeof(drv_ctx)); - memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); - memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); - memset(m_demux_offsets, 0, sizeof(m_demux_offsets) ); - m_demux_entries = 0; -#ifdef _ANDROID_ICS_ - memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); -#endif - memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); - drv_ctx.timestamp_adjust = false; - drv_ctx.video_driver_fd = -1; - m_vendor_config.pData = NULL; - pthread_mutex_init(&m_lock, NULL); - pthread_mutex_init(&c_lock, NULL); - sem_init(&m_cmd_lock,0,0); - streaming[CAPTURE_PORT] = - streaming[OUTPUT_PORT] = false; -#ifdef _ANDROID_ - char extradata_value[PROPERTY_VALUE_MAX] = {0}; - property_get("vidc.dec.debug.extradata", extradata_value, "0"); - m_debug_extradata = atoi(extradata_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); -#endif - m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; - client_buffers.set_vdec_client(this); -} - -static const int event_type[] = { - V4L2_EVENT_MSM_VIDC_FLUSH_DONE, - V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, - V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, - V4L2_EVENT_MSM_VIDC_CLOSE_DONE, - V4L2_EVENT_MSM_VIDC_SYS_ERROR -}; - -static OMX_ERRORTYPE subscribe_to_events(int fd) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_event_subscription sub; - int array_sz = sizeof(event_type)/sizeof(int); - int i,rc; - if (fd < 0) { - printf("Invalid input: %d\n", fd); - return OMX_ErrorBadParameter; - } - - for (i = 0; i < array_sz; ++i) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); - if (rc) { - printf("Failed to subscribe event: 0x%x\n", sub.type); - break; - } - } - if (i < array_sz) { - for (--i; i >=0 ; i--) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); - if (rc) - printf("Failed to unsubscribe event: 0x%x\n", sub.type); - } - eRet = OMX_ErrorNotImplemented; - } - return eRet; -} - - -static OMX_ERRORTYPE unsubscribe_to_events(int fd) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_event_subscription sub; - int array_sz = sizeof(event_type)/sizeof(int); - int i,rc; - if (fd < 0) { - printf("Invalid input: %d\n", fd); - return OMX_ErrorBadParameter; - } - - for (i = 0; i < array_sz; ++i) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); - if (rc) { - printf("Failed to unsubscribe event: 0x%x\n", sub.type); - break; - } - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::~omx_vdec - -DESCRIPTION - Destructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_vdec::~omx_vdec() -{ - m_pmem_info = NULL; - struct v4l2_decoder_cmd dec; - DEBUG_PRINT_HIGH("In OMX vdec Destructor"); - if(m_pipe_in) close(m_pipe_in); - if(m_pipe_out) close(m_pipe_out); - m_pipe_in = -1; - m_pipe_out = -1; - DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); - pthread_join(msg_thread_id,NULL); - DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); - dec.cmd = V4L2_DEC_CMD_STOP; - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) - { - DEBUG_PRINT_ERROR("\n STOP Command failed\n"); - } - pthread_join(async_thread_id,NULL); - unsubscribe_to_events(drv_ctx.video_driver_fd); - close(drv_ctx.video_driver_fd); - pthread_mutex_destroy(&m_lock); - pthread_mutex_destroy(&c_lock); - sem_destroy(&m_cmd_lock); - if (perf_flag) - { - DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); - dec_time.end(); - } - DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); -} - -int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) { - struct v4l2_requestbuffers bufreq; - int rc = 0; - if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = 0; - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); - } - return rc; -} - -/* ====================================================================== -FUNCTION - omx_vdec::OMXCntrlProcessMsgCb - -DESCRIPTION - IL Client callbacks are generated through this routine. The decoder - provides the thread context for this routine. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -void omx_vdec::process_event_cb(void *ctxt, unsigned char id) -{ - signed int p1; // Parameter - 1 - signed int p2; // Parameter - 2 - unsigned int ident; - unsigned int qsize=0; // qsize - omx_vdec *pThis = (omx_vdec *) ctxt; - - if(!pThis) - { - DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n", - __func__); - return; - } - - // Protect the shared queue data structure - do - { - /*Read the message id's from the queue*/ - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if(qsize) - { - pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); - } - - if (qsize == 0 && pThis->m_state != OMX_StatePause) - { - qsize = pThis->m_ftb_q.m_size; - if (qsize) - { - pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); - } - } - - if (qsize == 0 && pThis->m_state != OMX_StatePause) - { - qsize = pThis->m_etb_q.m_size; - if (qsize) - { - pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); - } - } - pthread_mutex_unlock(&pThis->m_lock); - - /*process message if we have one*/ - if(qsize > 0) - { - id = ident; - switch (id) - { - case OMX_COMPONENT_GENERATE_EVENT: - if (pThis->m_cb.EventHandler) - { - switch (p1) - { - case OMX_CommandStateSet: - pThis->m_state = (OMX_STATETYPE) p2; - DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d", - pThis->m_state); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL); - break; - - case OMX_EventError: - if(p2 == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); - pThis->m_state = (OMX_STATETYPE) p2; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError, OMX_ErrorInvalidState, p2, NULL); - } - else if (p2 == OMX_ErrorHardware) - { - pThis->omx_report_error(); - } - else - { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError, p2, (OMX_U32)NULL, NULL ); - } - break; - - case OMX_CommandPortDisable: - DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2); - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) - { - BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); - break; - } - if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig) - { - OMX_ERRORTYPE eRet = OMX_ErrorNone; - pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); - if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) - DEBUG_PRINT_HIGH("Failed to release output buffers\n"); - OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); - pThis->in_reconfig = false; - if(eRet != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); - pThis->omx_report_error(); - break; - } - } - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - case OMX_CommandPortEnable: - DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - default: - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__); - } - break; - case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: - if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); - pThis->omx_report_error (); - } - break; - case OMX_COMPONENT_GENERATE_ETB: - if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FTB: - if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_COMMAND: - pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ - (OMX_U32)p2,(OMX_PTR)NULL); - break; - - case OMX_COMPONENT_GENERATE_EBD: - - if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); - pThis->omx_report_error (); - } - else - { - if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) - { - pThis->m_inp_err_count++; - pThis->time_stamp_dts.remove_time_stamp( - ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, - (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - } - else - { - pThis->m_inp_err_count = 0; - } - if ( pThis->empty_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); - pThis->omx_report_error (); - } - if(pThis->m_inp_err_count >= MAX_INPUT_ERROR) - { - DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); - pThis->omx_report_error (); - } - } - break; - case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: - { - int64_t *timestamp = (int64_t *)p1; - if (p1) - { - pThis->time_stamp_dts.remove_time_stamp(*timestamp, - (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - free(timestamp); - } - } - break; - case OMX_COMPONENT_GENERATE_FBD: - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); - pThis->omx_report_error (); - } - else if ( pThis->fill_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: - DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete"); - if (!pThis->input_flush_progress) - { - DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); - } - else - { - pThis->execute_input_flush(); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); - pThis->omx_report_error (); - } - else - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_INPUT_FLUSH_PENDING)) - { - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); - DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client"); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - OMX_CORE_INPUT_PORT_INDEX,NULL ); - } - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_IDLE_PENDING)) - { - if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { - DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n"); - pThis->omx_report_error (); - } else { - pThis->streaming[OUTPUT_PORT] = false; - } - if (!pThis->output_flush_progress) - { - DEBUG_PRINT_LOW("\n Input flush done hence issue stop"); - pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - } - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: - DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete"); - if (!pThis->output_flush_progress) - { - DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); - } - else - { - pThis->execute_output_flush(); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); - pThis->omx_report_error (); - } - else - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) - { - DEBUG_PRINT_LOW("\n Notify Output Flush done"); - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - OMX_CORE_OUTPUT_PORT_INDEX,NULL ); - } - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) - { - DEBUG_PRINT_LOW("\n Internal flush complete"); - BITMASK_CLEAR (&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) - { - pThis->post_event(OMX_CommandPortDisable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - BITMASK_CLEAR (&pThis->m_flags, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); - - } - } - - if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) - { - if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { - DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n"); - pThis->omx_report_error (); - break; - } - pThis->streaming[CAPTURE_PORT] = false; - if (!pThis->input_flush_progress) - { - DEBUG_PRINT_LOW("\n Output flush done hence issue stop"); - pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - } - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_START_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE"); - - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); - pThis->omx_report_error (); - } - else - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("\n Move to executing"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting, NULL); - } - else if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_PAUSE_PENDING)) - { - if (/*ioctl (pThis->drv_ctx.video_driver_fd, - VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); - pThis->omx_report_error (); - } - } - } - } - else - { - DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); - } - break; - - case OMX_COMPONENT_GENERATE_PAUSE_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); - pThis->omx_report_error (); - } - else - { - pThis->complete_pending_buffer_done_cbs(); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); - //Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); - pThis->m_state = OMX_StatePause; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StatePause, NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_RESUME_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); - pThis->omx_report_error (); - } - else - { - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("\n Moving the decoder to execute state"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting,NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_STOP_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); - pThis->omx_report_error (); - } - else - { - pThis->complete_pending_buffer_done_cbs(); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); - pThis->m_state = OMX_StateIdle; - DEBUG_PRINT_LOW("\n Move to Idle State"); - pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateIdle,NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_PORT_RECONFIG: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); - - if (p2 == OMX_IndexParamPortDefinition) { - pThis->in_reconfig = true; - } - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventPortSettingsChanged, p1, p2, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - { - OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; - OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; - if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) - format = OMX_InterlaceInterleaveFrameTopFieldFirst; - else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) - format = OMX_InterlaceInterleaveFrameBottomFieldFirst; - else //unsupported interlace format; raise a error - event = OMX_EventError; - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - event, format, 0, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_EOS_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, - OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - pThis->prev_ts = LLONG_MAX; - pThis->rst_prev_ts = true; - break; - - case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); - pThis->omx_report_error (); - break; - case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: - { - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - default: - break; - } - } - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if (pThis->m_state != OMX_StatePause) - qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); - pthread_mutex_unlock(&pThis->m_lock); - } - while(qsize>0); - -} - -void omx_vdec::update_resolution(int width, int height) -{ - drv_ctx.video_resolution.frame_height = height; - drv_ctx.video_resolution.frame_width = width; - drv_ctx.video_resolution.scan_lines = height; - drv_ctx.video_resolution.stride = width; - rectangle.nLeft = 0; - rectangle.nTop = 0; - rectangle.nWidth = drv_ctx.video_resolution.frame_width; - rectangle.nHeight = drv_ctx.video_resolution.frame_height; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentInit - -DESCRIPTION - Initialize the component. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_fmtdesc fdesc; - struct v4l2_format fmt; - struct v4l2_requestbuffers bufreq; - struct v4l2_control control; - unsigned int alignment = 0,buffer_size = 0; - int fds[2]; - int r,ret=0; - bool codec_ambiguous = false; - OMX_STRING device_name = (OMX_STRING)"/dev/video/q6_dec"; - drv_ctx.video_driver_fd = open(device_name, O_RDWR); - - DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open device %s returned fd %d, errno %d", - device_name, drv_ctx.video_driver_fd, errno); - - if(drv_ctx.video_driver_fd == 0){ - drv_ctx.video_driver_fd = open(device_name, O_RDWR); - } - - if(drv_ctx.video_driver_fd < 0) - { - DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno); - return OMX_ErrorInsufficientResources; - } - drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; - drv_ctx.frame_rate.fps_denominator = 1; - - ret = pthread_create(&async_thread_id,0,async_message_thread,this); - if(ret < 0) { - close(drv_ctx.video_driver_fd); - DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n"); - return OMX_ErrorInsufficientResources; - } - -#ifdef INPUT_BUFFER_LOG - strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); -#endif -#ifdef OUTPUT_BUFFER_LOG - outputBufferFile1 = fopen (outputfilename, "ab"); -#endif -#ifdef OUTPUT_EXTRADATA_LOG - outputExtradataFile = fopen (ouputextradatafilename, "ab"); -#endif - - // Copy the role information which provides the decoder kind - strlcpy(drv_ctx.kind,role,128); - - if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE); - drv_ctx.timestamp_adjust = true; - drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; - eCompressionFormat = OMX_VIDEO_CodingMPEG4; - output_capability=V4L2_PIX_FMT_MPEG4; - /*Initialize Start Code for MPEG4*/ - codec_type_parse = CODEC_TYPE_MPEG4; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "m4v"); -#endif - } - else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ - OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; - output_capability = V4L2_PIX_FMT_MPEG2; - eCompressionFormat = OMX_VIDEO_CodingMPEG2; - /*Initialize Start Code for MPEG2*/ - codec_type_parse = CODEC_TYPE_MPEG2; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "mpg"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("\n H263 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_H263; - eCompressionFormat = OMX_VIDEO_CodingH263; - output_capability = V4L2_PIX_FMT_H263; - codec_type_parse = CODEC_TYPE_H263; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "263"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; - output_capability = V4L2_PIX_FMT_DIVX_311; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - m_frame_parser.init_start_codes (codec_type_parse); - - eRet = createDivxDrmContext(); - if (eRet != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - return eRet; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; - output_capability = V4L2_PIX_FMT_DIVX; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - codec_ambiguous = true; - m_frame_parser.init_start_codes (codec_type_parse); - - eRet = createDivxDrmContext(); - if (eRet != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - return eRet; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; - output_capability = V4L2_PIX_FMT_DIVX; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - codec_ambiguous = true; - m_frame_parser.init_start_codes (codec_type_parse); - - eRet = createDivxDrmContext(); - if (eRet != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - return eRet; - } - - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_H264; - output_capability=V4L2_PIX_FMT_H264; - eCompressionFormat = OMX_VIDEO_CodingAVC; - codec_type_parse = CODEC_TYPE_H264; - m_frame_parser.init_start_codes (codec_type_parse); - m_frame_parser.init_nal_length(nal_length); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "264"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC; - output_capability=V4L2_PIX_FMT_HEVC; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; - codec_type_parse = CODEC_TYPE_HEVC; - m_frame_parser.init_start_codes (codec_type_parse); - m_frame_parser.init_nal_length(nal_length); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "265"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; - eCompressionFormat = OMX_VIDEO_CodingWMV; - codec_type_parse = CODEC_TYPE_VC1; - output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "vc1"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; - eCompressionFormat = OMX_VIDEO_CodingWMV; - codec_type_parse = CODEC_TYPE_VC1; - output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "vc1"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); - output_capability=V4L2_PIX_FMT_VP8; - eCompressionFormat = OMX_VIDEO_CodingVPX; - codec_type_parse = CODEC_TYPE_VP8; - arbitrary_bytes = false; - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } -#ifdef INPUT_BUFFER_LOG - inputBufferFile1 = fopen (inputfilename, "ab"); -#endif - if (eRet == OMX_ErrorNone) - { - - drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; - OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - if (!client_buffers.set_color_format(dest_color_format)) { - DEBUG_PRINT_ERROR("\n Setting color format failed"); - eRet = OMX_ErrorInsufficientResources; - } - - capture_capability= V4L2_PIX_FMT_NV12; - ret = subscribe_to_events(drv_ctx.video_driver_fd); - if (ret) { - DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n"); - return OMX_ErrorInsufficientResources; - } - - struct v4l2_capability cap; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap); - if (ret) { - DEBUG_PRINT_ERROR("Failed to query capabilities\n"); - /*TODO: How to handle this case */ - } else { - DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s," - " version = %d, capabilities = %x\n", cap.driver, cap.card, - cap.bus_info, cap.version, cap.capabilities); - } - ret=0; - fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fdesc.index=0; - while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { - DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, - fdesc.pixelformat, fdesc.flags); - fdesc.index++; - } - fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fdesc.index=0; - while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { - - DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, - fdesc.pixelformat, fdesc.flags); - fdesc.index++; - } - update_resolution(320, 240); - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = output_capability; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to set format on output port\n"); - } - DEBUG_PRINT_HIGH("\n Set Format was successful \n "); - if (codec_ambiguous) { - if (output_capability == V4L2_PIX_FMT_DIVX) { - struct v4l2_control divx_ctrl; - - if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { - divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; - } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { - divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; - } else { - divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; - } - - divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); - if (ret) { - DEBUG_PRINT_ERROR("Failed to set divx version\n"); - } - } else { - DEBUG_PRINT_ERROR("Codec should not be ambiguous"); - } - } - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = capture_capability; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to set format on capture port\n"); - } - DEBUG_PRINT_HIGH("\n Set Format was successful \n "); - if(secure_mode){ - control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; - control.value = 1; - DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret); - ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); - if (ret) { - DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret); - close(drv_ctx.video_driver_fd); - return OMX_ErrorInsufficientResources; - } - } - - /*Get the Buffer requirements for input and output ports*/ - drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; - drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - if (secure_mode) { - drv_ctx.op_buf.alignment=SZ_1M; - drv_ctx.ip_buf.alignment=SZ_1M; - } else { - drv_ctx.op_buf.alignment=SZ_4K; - drv_ctx.ip_buf.alignment=SZ_4K; - } - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; - drv_ctx.extradata = 0; - drv_ctx.picture_order = VDEC_ORDER_DISPLAY; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; - control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - drv_ctx.idr_only_decoding = 0; - - m_state = OMX_StateLoaded; -#ifdef DEFAULT_EXTRADATA - if (eRet == OMX_ErrorNone && !secure_mode) - enable_extradata(DEFAULT_EXTRADATA, true, true); -#endif - eRet=get_buffer_req(&drv_ctx.ip_buf); - DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size); - get_buffer_req(&drv_ctx.op_buf); - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 || - drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC) - { - h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; - h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); - h264_scratch.nFilledLen = 0; - h264_scratch.nOffset = 0; - - if (h264_scratch.pBuffer == NULL) - { - DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); - return OMX_ErrorInsufficientResources; - } - } - - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - if (m_frame_parser.mutils == NULL) - { - m_frame_parser.mutils = new H264_Utils(); - - if (m_frame_parser.mutils == NULL) - { - DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); - eRet = OMX_ErrorInsufficientResources; - } - else - { - m_frame_parser.mutils->initialize_frame_checking_environment(); - m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); - } - } - - h264_parser = new h264_stream_parser(); - if (!h264_parser) - { - DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); - eRet = OMX_ErrorInsufficientResources; - } - } - - if(pipe(fds)) - { - DEBUG_PRINT_ERROR("pipe creation failed\n"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - int temp1[2]; - if(fds[0] == 0 || fds[1] == 0) - { - if (pipe (temp1)) - { - DEBUG_PRINT_ERROR("pipe creation failed\n"); - return OMX_ErrorInsufficientResources; - } - //close (fds[0]); - //close (fds[1]); - fds[0] = temp1 [0]; - fds[1] = temp1 [1]; - } - m_pipe_in = fds[0]; - m_pipe_out = fds[1]; - r = pthread_create(&msg_thread_id,0,message_thread,this); - - if(r < 0) - { - DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); - eRet = OMX_ErrorInsufficientResources; - } - } - } - - if (eRet != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Component Init Failed"); - DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG"); - (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG, - NULL); - DEBUG_PRINT_HIGH("\n Calling close() on Video Driver"); - close (drv_ctx.video_driver_fd); - drv_ctx.video_driver_fd = -1; - } - else - { - DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success"); - } - //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetComponentVersion - -DESCRIPTION - Returns the component version. - -PARAMETERS - TBD. - -RETURN VALUE - OMX_ErrorNone. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_component_version - ( - OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STRING componentName, - OMX_OUT OMX_VERSIONTYPE* componentVersion, - OMX_OUT OMX_VERSIONTYPE* specVersion, - OMX_OUT OMX_UUIDTYPE* componentUUID - ) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n"); - return OMX_ErrorInvalidState; - } - /* TBD -- Return the proper version */ - if (specVersion) - { - specVersion->nVersion = OMX_SPEC_VERSION; - } - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_vdec::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX - && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) - { - DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush " - "to invalid port: %lu", param1); - return OMX_ErrorBadPortIndex; - } - post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); - sem_wait(&m_cmd_lock); - DEBUG_PRINT_LOW("\n send_command: Command Processed\n"); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_STATETYPE eState = (OMX_STATETYPE) param1; - int bFlag = 1,sem_posted = 0,ret=0; - - DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd); - DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d", - m_state, eState); - - if(cmd == OMX_CommandStateSet) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued"); - DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState); - /***************************/ - /* Current State is Loaded */ - /***************************/ - if(m_state == OMX_StateLoaded) - { - if(eState == OMX_StateIdle) - { - //if all buffers are allocated or all ports disabled - if(allocate_done() || - (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) - { - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n"); - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Loaded to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Loaded to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n"); - } - /* Requesting transition from Loaded to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ - eState); - eRet = OMX_ErrorBadParameter; - } - } - - /***************************/ - /* Current State is IDLE */ - /***************************/ - else if(m_state == OMX_StateIdle) - { - if(eState == OMX_StateLoaded) - { - if(release_done()) - { - /* - Since error is None , we will post an event at the end - of this function definition - */ - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n"); - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Idle to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); - //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); - bFlag = 1; - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); - m_state=OMX_StateExecuting; - DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n"); - } - /* Requesting transition from Idle to Idle */ - else if(eState == OMX_StateIdle) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Idle to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Idle to Pause */ - else if(eState == OMX_StatePause) - { - /*To pause the Video core we need to start the driver*/ - if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, - NULL) < */0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n"); - bFlag = 0; - } - } - /* Requesting transition from Idle to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - - /******************************/ - /* Current State is Executing */ - /******************************/ - else if(m_state == OMX_StateExecuting) - { - DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting"); - /* Requesting transition from Executing to Idle */ - if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition - */ - DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n"); - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - execute_omx_flush(OMX_ALL); - } - bFlag = 0; - } - /* Requesting transition from Executing to Paused */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_LOW("\n PAUSE Command Issued"); - m_state = OMX_StatePause; - bFlag = 1; - } - /* Requesting transition from Executing to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Executing to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is Pause */ - /***************************/ - else if(m_state == OMX_StatePause) - { - /* Requesting transition from Pause to Executing */ - if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_LOW("\n Pause --> Executing \n"); - m_state = OMX_StateExecuting; - bFlag = 1; - } - /* Requesting transition from Pause to Idle */ - else if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("\n Pause --> Idle \n"); - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - execute_omx_flush(OMX_ALL); - } - bFlag = 0; - } - /* Requesting transition from Pause to loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Pause to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is WaitForResources */ - /***************************/ - else if(m_state == OMX_StateWaitForResources) - { - /* Requesting transition from WaitForResources to Loaded */ - if(eState == OMX_StateLoaded) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n"); - } - /* Requesting transition from WaitForResources to WaitForResources */ - else if (eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorSameState, - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from WaitForResources to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - /* Requesting transition from WaitForResources to Loaded - - is NOT tested by Khronos TS */ - - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); - eRet = OMX_ErrorBadParameter; - } - } - /********************************/ - /* Current State is Invalid */ - /*******************************/ - else if(m_state == OMX_StateInvalid) - { - /* State Transition from Inavlid to any state */ - if(eState == (OMX_StateLoaded || OMX_StateWaitForResources - || OMX_StateIdle || OMX_StateExecuting - || OMX_StatePause || OMX_StateInvalid)) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); - post_event(OMX_EventError,OMX_ErrorInvalidState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - } - else if (cmd == OMX_CommandFlush) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued" - "with param1: %lu", param1); - if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); - } - if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) - { - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - } - if (!sem_posted){ - sem_posted = 1; - DEBUG_PRINT_LOW("\n Set the Semaphore"); - sem_post (&m_cmd_lock); - execute_omx_flush(param1); - } - bFlag = 0; - } - else if ( cmd == OMX_CommandPortEnable) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued" - "with param1: %lu", param1); - if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_inp_bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || allocate_input_done()) - { - post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) - { - DEBUG_PRINT_LOW("\n Enable output Port command recieved"); - m_out_bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || (allocate_output_done())) - { - post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - } - else if (cmd == OMX_CommandPortDisable) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued" - "with param1: %lu", param1); - if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_inp_bEnabled = OMX_FALSE; - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_input_done()) - { - post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - } - execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); - } - - // Skip the event notification - bFlag = 0; - } - } - if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_out_bEnabled = OMX_FALSE; - DEBUG_PRINT_LOW("\n Disable output Port command recieved"); - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_output_done()) - { - post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - if (!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - } - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); - execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); - } - // Skip the event notification - bFlag = 0; - - } - } - } - else - { - DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); - eRet = OMX_ErrorNotImplemented; - } - if(eRet == OMX_ErrorNone && bFlag) - { - post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); - } - if(!sem_posted) - { - sem_post(&m_cmd_lock); - } - - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ExecuteOmxFlush - -DESCRIPTION - Executes the OMX flush. - -PARAMETERS - flushtype - input flush(1)/output flush(0)/ both. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_vdec::execute_omx_flush(OMX_U32 flushType) -{ - bool bRet = false; - struct v4l2_plane plane; - struct v4l2_buffer v4l2_buf; - struct v4l2_decoder_cmd dec; - DEBUG_PRINT_LOW("in %s", __func__); - memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); - dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; - switch (flushType) - { - case OMX_CORE_INPUT_PORT_INDEX: - input_flush_progress = true; - dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT; - break; - case OMX_CORE_OUTPUT_PORT_INDEX: - output_flush_progress = true; - dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; - break; - default: - input_flush_progress = true; - output_flush_progress = true; - dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | - V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; - } - - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) - { - DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType); - bRet = false; - } - - return bRet; -} -/*========================================================================= -FUNCTION : execute_output_flush - -DESCRIPTION - Executes the OMX flush at OUTPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_vdec::execute_output_flush() -{ - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate FBD for all Buffers in the FTBq*/ - pthread_mutex_lock(&m_lock); - DEBUG_PRINT_LOW("\n Initiate Output Flush"); - while (m_ftb_q.m_size) - { - DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d", - m_ftb_q.m_size,pending_output_buffers); - m_ftb_q.pop_entry(&p1,&p2,&ident); - DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2); - if(ident == m_fill_output_msg ) - { - m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); - } - else if (ident == OMX_COMPONENT_GENERATE_FBD) - { - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - pthread_mutex_unlock(&m_lock); - output_flush_progress = false; - - if (arbitrary_bytes) - { - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } - DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); - return bRet; -} -/*========================================================================= -FUNCTION : execute_input_flush - -DESCRIPTION - Executes the OMX flush at INPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_vdec::execute_input_flush() -{ - unsigned i =0; - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate EBD for all Buffers in the ETBq*/ - DEBUG_PRINT_LOW("\n Initiate Input Flush \n"); - - pthread_mutex_lock(&m_lock); - DEBUG_PRINT_LOW("\n Check if the Queue is empty \n"); - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - - if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) - { - DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); - m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_ETB) - { - pending_input_buffers++; - DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", - (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if (ident == OMX_COMPONENT_GENERATE_EBD) - { - DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", - (OMX_BUFFERHEADERTYPE *)p1); - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - time_stamp_dts.flush_timestamp(); - /*Check if Heap Buffers are to be flushed*/ - if (arbitrary_bytes) - { - DEBUG_PRINT_LOW("\n Reset all the variables before flusing"); - h264_scratch.nFilledLen = 0; - nal_count = 0; - look_ahead_nal = false; - frame_count = 0; - h264_last_au_ts = LLONG_MAX; - h264_last_au_flags = 0; - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - DEBUG_PRINT_LOW("\n Initialize parser"); - if (m_frame_parser.mutils) - { - m_frame_parser.mutils->initialize_frame_checking_environment(); - } - - while (m_input_pending_q.m_size) - { - m_input_pending_q.pop_entry(&p1,&p2,&ident); - m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); - } - - if (psource_frame) - { - m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); - psource_frame = NULL; - } - - if (pdest_frame) - { - pdest_frame->nFilledLen = 0; - m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL, - (unsigned int)NULL); - pdest_frame = NULL; - } - m_frame_parser.flush(); - } - pthread_mutex_unlock(&m_lock); - input_flush_progress = false; - if (!arbitrary_bytes) - { - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } -#ifdef _ANDROID_ - if (m_debug_timestamp) - { - m_timestamp_list.reset_ts_list(); - } -#endif - DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); - return bRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::SendCommandEvent - -DESCRIPTION - Send the event to decoder pipe. This is needed to generate the callbacks - in decoder thread context. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_vdec::post_event(unsigned int p1, - unsigned int p2, - unsigned int id) -{ - bool bRet = false; - - - pthread_mutex_lock(&m_lock); - - if (id == m_fill_output_msg || - id == OMX_COMPONENT_GENERATE_FBD) - { - m_ftb_q.insert_entry(p1,p2,id); - } - else if (id == OMX_COMPONENT_GENERATE_ETB || - id == OMX_COMPONENT_GENERATE_EBD || - id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) - { - m_etb_q.insert_entry(p1,p2,id); - } - else - { - m_cmd_q.insert_entry(p1,p2,id); - } - - bRet = true; - DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); - post_message(this, id); - - pthread_mutex_unlock(&m_lock); - - return bRet; -} - -OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNoMore; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 0) { - if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) - { - // TODO - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - eRet = OMX_ErrorNoMore; - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; - profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetParameter - -DESCRIPTION - OMX Get Parameter method implementation - -PARAMETERS - . - -RETURN VALUE - Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_INOUT OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - DEBUG_PRINT_LOW("get_parameter: \n"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_LOW("Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - switch((unsigned long)paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn = - (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); - eRet = update_portdef(portDefn); - if (eRet == OMX_ErrorNone) - m_port_def = *portDefn; - break; - } - case OMX_IndexParamVideoInit: - { - OMX_PORT_PARAM_TYPE *portParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); - - portParamType->nVersion.nVersion = OMX_SPEC_VERSION; - portParamType->nSize = sizeof(portParamType); - portParamType->nPorts = 2; - portParamType->nStartPortNumber = 0; - break; - } - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); - - portFmt->nVersion.nVersion = OMX_SPEC_VERSION; - portFmt->nSize = sizeof(portFmt); - - if (0 == portFmt->nPortIndex) - { - if (0 == portFmt->nIndex) - { - portFmt->eColorFormat = OMX_COLOR_FormatUnused; - portFmt->eCompressionFormat = eCompressionFormat; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ - " NoMore compression formats\n"); - eRet = OMX_ErrorNoMore; - } - } - else if (1 == portFmt->nPortIndex) - { - portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; - - if(0 == portFmt->nIndex) - portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - else if (1 == portFmt->nIndex) - portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ - " NoMore Color formats\n"); - eRet = OMX_ErrorNoMore; - } - ALOGE("returning %d\n", portFmt->eColorFormat); - } - else - { - DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", - (int)portFmt->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamAudioInit: - { - OMX_PORT_PARAM_TYPE *audioPortParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); - audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; - audioPortParamType->nSize = sizeof(audioPortParamType); - audioPortParamType->nPorts = 0; - audioPortParamType->nStartPortNumber = 0; - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamImageInit: - { - OMX_PORT_PARAM_TYPE *imagePortParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); - imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; - imagePortParamType->nSize = sizeof(imagePortParamType); - imagePortParamType->nPorts = 0; - imagePortParamType->nStartPortNumber = 0; - break; - - } - /*Component should support this port definition*/ - case OMX_IndexParamOtherInit: - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", - paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - break; - } - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - comp_role->nVersion.nVersion = OMX_SPEC_VERSION; - comp_role->nSize = sizeof(*comp_role); - - DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", - paramIndex); - strlcpy((char*)comp_role->cRole,(const char*)m_cRole, - OMX_MAX_STRINGNAME_SIZE); - break; - } - /* Added for parameter test */ - case OMX_IndexParamPriorityMgmt: - { - - OMX_PRIORITYMGMTTYPE *priorityMgmType = - (OMX_PRIORITYMGMTTYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); - priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; - priorityMgmType->nSize = sizeof(priorityMgmType); - - break; - } - /* Added for parameter test */ - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = - (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); - - bufferSupplierType->nSize = sizeof(bufferSupplierType); - bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; - if(0 == bufferSupplierType->nPortIndex) - bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; - else if (1 == bufferSupplierType->nPortIndex) - bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; - else - eRet = OMX_ErrorBadPortIndex; - - - break; - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoH263: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg4: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg2: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex); - OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = - (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; - eRet = get_supported_profile_level_for_1080p(profileLevelType); - break; - } -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: - { - DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n"); - GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; - if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { - - if(secure_mode) { - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | - GRALLOC_USAGE_PRIVATE_UNCACHED); - } else { -#ifdef _HEVC_USE_ADSP_HEAP_ - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); -#else - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED); -#endif - DEBUG_PRINT_HIGH("nativeBuffersUsage->nUsage %x\n", (unsigned int)nativeBuffersUsage->nUsage); - } - } else { - DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n"); - eRet = OMX_ErrorBadParameter; - } - } - break; -#endif - - default: - { - DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - } - - } - - DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n", - drv_ctx.video_resolution.frame_width, - drv_ctx.video_resolution.frame_height, - drv_ctx.video_resolution.stride, - drv_ctx.video_resolution.scan_lines); - - return eRet; -} - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) -{ - DEBUG_PRINT_LOW("Inside use_android_native_buffer"); - OMX_ERRORTYPE eRet = OMX_ErrorNone; - UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; - - if((params == NULL) || - (params->nativeBuffer == NULL) || - (params->nativeBuffer->handle == NULL) || - !m_enable_android_native_buffers) - return OMX_ErrorBadParameter; - m_use_android_native_buffers = OMX_TRUE; - sp nBuf = params->nativeBuffer; - private_handle_t *handle = (private_handle_t *)nBuf->handle; - if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port - OMX_U8 *buffer = NULL; - if(!secure_mode) { - buffer = (OMX_U8*)mmap(0, handle->size, - PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); - if(buffer == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); - return OMX_ErrorInsufficientResources; - } - } - eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); - } else { - eRet = OMX_ErrorBadParameter; - } - return eRet; -} -#endif -/* ====================================================================== -FUNCTION - omx_vdec::Setparameter - -DESCRIPTION - OMX Set Parameter method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_IN OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - int ret=0; - struct v4l2_format fmt; - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - if((m_state != OMX_StateLoaded) && - BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && - (m_out_bEnabled == OMX_TRUE) && - BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && - (m_inp_bEnabled == OMX_TRUE)) { - DEBUG_PRINT_ERROR("Set Param in Invalid State \n"); - return OMX_ErrorIncorrectStateOperation; - } - switch((unsigned long)paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has - //been called. - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", - (int)portDefn->format.video.nFrameHeight, - (int)portDefn->format.video.nFrameWidth); - if(OMX_DirOutput == portDefn->eDir) - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n"); - m_display_id = portDefn->format.video.pNativeWindow; - unsigned int buffer_size; - if (!client_buffers.get_buffer_req(buffer_size)) { - DEBUG_PRINT_ERROR("\n Error in getting buffer requirements"); - eRet = OMX_ErrorBadParameter; - } else { - if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && - portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) - { - drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; - drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; - eRet = set_buffer_req(&drv_ctx.op_buf); - if (eRet == OMX_ErrorNone) - m_port_def = *portDefn; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n", - drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, - portDefn->nBufferCountActual, portDefn->nBufferSize); - eRet = OMX_ErrorBadParameter; - } - } - } - else if(OMX_DirInput == portDefn->eDir) - { - if((portDefn->format.video.xFramerate >> 16) > 0 && - (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) - { - // Frame rate only should be set if this is a "known value" or to - // activate ts prediction logic (arbitrary mode only) sending input - // timestamps with max value (LLONG_MAX). - DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu", - portDefn->format.video.xFramerate >> 16); - Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, - drv_ctx.frame_rate.fps_denominator); - if(!drv_ctx.frame_rate.fps_numerator) - { - DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); - drv_ctx.frame_rate.fps_numerator = 30; - } - if(drv_ctx.frame_rate.fps_denominator) - drv_ctx.frame_rate.fps_numerator = (int) - drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; - drv_ctx.frame_rate.fps_denominator = 1; - frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / - drv_ctx.frame_rate.fps_numerator; - DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)", - frm_int, drv_ctx.frame_rate.fps_numerator / - (float)drv_ctx.frame_rate.fps_denominator); - } - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n"); - if(drv_ctx.video_resolution.frame_height != - portDefn->format.video.nFrameHeight || - drv_ctx.video_resolution.frame_width != - portDefn->format.video.nFrameWidth) - { - DEBUG_PRINT_LOW("\n SetParam IP: WxH(%d x %d)\n", - portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight); - if (portDefn->format.video.nFrameHeight != 0x0 && - portDefn->format.video.nFrameWidth != 0x0) - { - update_resolution(portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight); - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = output_capability; - DEBUG_PRINT_LOW("\n fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d \n",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) - { - DEBUG_PRINT_ERROR("\n Set Resolution failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - else - eRet = get_buffer_req(&drv_ctx.op_buf); - } - } - else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount - || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) - { - vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; - drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; - drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & - (~(buffer_prop->alignment - 1)); - eRet = set_buffer_req(buffer_prop); - } - else - { - DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n", - drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, - portDefn->nBufferCountActual, portDefn->nBufferSize); - eRet = OMX_ErrorBadParameter; - } - } - else if (portDefn->eDir == OMX_DirMax) - { - DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - } - break; - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - int ret=0; - struct v4l2_format fmt; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", - portFmt->eColorFormat); - - if(1 == portFmt->nPortIndex) - { - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = capture_capability; - enum vdec_output_fromat op_format; - if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) || - (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar)) - op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; - else if(portFmt->eColorFormat == - (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) - op_format = VDEC_YUV_FORMAT_TILE_4x2; - else - eRet = OMX_ErrorBadParameter; - - if(eRet == OMX_ErrorNone) - { - drv_ctx.output_format = op_format; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if(ret) - { - DEBUG_PRINT_ERROR("\n Set output format failed"); - eRet = OMX_ErrorUnsupportedSetting; - /*TODO: How to handle this case */ - } - else - { - eRet = get_buffer_req(&drv_ctx.op_buf); - } - } - if (eRet == OMX_ErrorNone){ - if (!client_buffers.set_color_format(portFmt->eColorFormat)) { - DEBUG_PRINT_ERROR("\n Set color format failed"); - eRet = OMX_ErrorBadParameter; - } - } - } - } - break; - - case OMX_QcomIndexPortDefn: - { - OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = - (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n", - portFmt->nFramePackingFormat); - - /* Input port */ - if (portFmt->nPortIndex == 0) - { - if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) - { - if(secure_mode) { - arbitrary_bytes = false; - DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); - eRet = OMX_ErrorUnsupportedSetting; - } else { - arbitrary_bytes = true; - } - } - else if (portFmt->nFramePackingFormat == - OMX_QCOM_FramePacking_OnlyOneCompleteFrame) - { - arbitrary_bytes = false; - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n", - portFmt->nFramePackingFormat); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n"); - if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && - portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && - portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) - { - m_out_mem_region_smi = OMX_TRUE; - if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n"); - m_use_output_pmem = OMX_TRUE; - } - } - } - } - break; - - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", - comp_role->cRole); - - if((m_state == OMX_StateLoaded)&& - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("Set Parameter called in valid state"); - } - else - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((char*)comp_role->cRole,"video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || - (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) - { - strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind); - eRet = OMX_ErrorInvalidComponentName; - } - break; - } - - case OMX_IndexParamPriorityMgmt: - { - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", - priorityMgmtype->nGroupID); - - DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", - priorityMgmtype->nGroupPriority); - - m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; - m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; - - break; - } - - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", - bufferSupplierType->eBufferSupplier); - if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) - m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; - - else - - eRet = OMX_ErrorBadPortIndex; - - break; - - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoH263: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg4: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg2: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n", - paramIndex); - break; - } - case OMX_QcomIndexParamVideoDecoderPictureOrder: - { - QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = - (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; - struct v4l2_control control; - int pic_order,rc=0; - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n", - pictureOrder->eOutputPictureOrder); - if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { - pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; - } - else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){ - pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; - time_stamp_dts.set_timestamp_reorder_mode(false); - } - else - eRet = OMX_ErrorBadParameter; - if (eRet == OMX_ErrorNone) - { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; - control.value = pic_order; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - if(rc) - { - DEBUG_PRINT_ERROR("\n Set picture order failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - } - break; - } - case OMX_QcomIndexParamConcealMBMapExtraData: - if(!secure_mode) - eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - case OMX_QcomIndexParamFrameInfoExtraData: - { - if(!secure_mode) - eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - } - case OMX_QcomIndexParamInterlaceExtraData: - if(!secure_mode) - eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - case OMX_QcomIndexParamH264TimeInfo: - if(!secure_mode) - eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - case OMX_QcomIndexParamVideoDivx: - { - QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; - } - break; - case OMX_QcomIndexPlatformPvt: - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n"); - OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; - if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) - { - DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); - eRet = OMX_ErrorUnsupportedSetting; - } - else - { - m_out_pvt_entry_pmem = OMX_TRUE; - if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n"); - m_use_output_pmem = OMX_TRUE; - } - } - - } - break; - case OMX_QcomIndexParamVideoSyncFrameDecodingMode: - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); - DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); - struct v4l2_control control; - int rc; - drv_ctx.idr_only_decoding = 1; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; - control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - if(rc) - { - DEBUG_PRINT_ERROR("\n Set picture order failed"); - eRet = OMX_ErrorUnsupportedSetting; - } else { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; - control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - if(rc) - { - DEBUG_PRINT_ERROR("\n Sync frame setting failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - } - } - break; - - case OMX_QcomIndexParamIndexExtraDataType: - { - if(!secure_mode) { - QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; - if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && - (extradataIndexType->bEnabled == OMX_TRUE) && - (extradataIndexType->nPortIndex == 1)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n"); - eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); - - } - } - } - break; - case OMX_QcomIndexParamEnableSmoothStreaming: - { - struct v4l2_control control; - struct v4l2_format fmt; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; - control.value = 1; - int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); - if(rc < 0) { - DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); - eRet = OMX_ErrorHardware; - } - } - break; -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - /* Need to allow following two set_parameters even in Idle - * state. This is ANDROID architecture which is not in sync - * with openmax standard. */ - case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: - { - EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; - if(enableNativeBuffers) { - m_enable_android_native_buffers = enableNativeBuffers->enable; - } - } - break; - case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: - { - eRet = use_android_native_buffer(hComp, paramData); - } - break; -#endif - case OMX_QcomIndexParamEnableTimeStampReorder: - { - QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; - if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { - if (reorder->bEnable == OMX_TRUE) { - frm_int =0; - time_stamp_dts.set_timestamp_reorder_mode(true); - } - else - time_stamp_dts.set_timestamp_reorder_mode(false); - } else { - time_stamp_dts.set_timestamp_reorder_mode(false); - if (reorder->bEnable == OMX_TRUE) - { - eRet = OMX_ErrorUnsupportedSetting; - } - } - } - break; - default: - { - DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); - eRet = OMX_ErrorUnsupportedIndex; - } - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetConfig - -DESCRIPTION - OMX Get Config Method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_INOUT OMX_PTR configData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - if (m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - switch ((unsigned long)configIndex) - { - case OMX_QcomIndexConfigInterlaced: - { - OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = - (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; - if (configFmt->nPortIndex == 1) - { - if (configFmt->nIndex == 0) - { - configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; - } - else if (configFmt->nIndex == 1) - { - configFmt->eInterlaceType = - OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; - } - else if (configFmt->nIndex == 2) - { - configFmt->eInterlaceType = - OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; - } - else - { - DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" - " NoMore Interlaced formats\n"); - eRet = OMX_ErrorNoMore; - } - - } - else - { - DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", - (int)configFmt->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - case OMX_QcomIndexQueryNumberOfVideoDecInstance: - { - QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = - (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; - decoderinstances->nNumOfInstances = 16; - /*TODO: How to handle this case */ - break; - } - case OMX_QcomIndexConfigVideoFramePackingArrangement: - { - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = - (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; - h264_parser->get_frame_pack_data(configFmt); - } - else - { - DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); - } - break; - } - case OMX_IndexConfigCommonOutputCrop: - { - OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; - memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); - break; - } - default: - { - DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); - eRet = OMX_ErrorBadParameter; - } - - } - - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SetConfig - -DESCRIPTION - OMX Set Config method implementation - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_IN OMX_PTR configData) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_VIDEO_CONFIG_NALSIZE *pNal; - - DEBUG_PRINT_LOW("\n Set Config Called"); - - if (m_state == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n"); - return ret; - } - - if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) - { - OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; - DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called"); - if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) - { - DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC"); - OMX_U32 extra_size; - // Parsing done here for the AVC atom is definitely not generic - // Currently this piece of code is working, but certainly - // not tested with all .mp4 files. - // Incase of failure, we might need to revisit this - // for a generic piece of code. - - // Retrieve size of NAL length field - // byte #4 contains the size of NAL lenght field - nal_length = (config->pData[4] & 0x03) + 1; - - extra_size = 0; - if (nal_length > 2) - { - /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ - extra_size = (nal_length - 2) * 2; - } - - // SPS starts from byte #6 - OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); - OMX_U8 *pDestBuf; - m_vendor_config.nPortIndex = config->nPortIndex; - - // minus 6 --> SPS starts from byte #6 - // minus 1 --> picture param set byte to be ignored from avcatom - m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; - m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); - OMX_U32 len; - OMX_U8 index = 0; - // case where SPS+PPS is sent as part of set_config - pDestBuf = m_vendor_config.pData; - - DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n", - m_vendor_config.nPortIndex, - m_vendor_config.nDataSize, - m_vendor_config.pData); - while (index < 2) - { - uint8 *psize; - len = *pSrcBuf; - len = len << 8; - len |= *(pSrcBuf + 1); - psize = (uint8 *) & len; - memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); - for (unsigned int i = 0; i < nal_length; i++) - { - pDestBuf[i] = psize[nal_length - 1 - i]; - } - //memcpy(pDestBuf,pSrcBuf,(len+2)); - pDestBuf += len + nal_length; - pSrcBuf += len + 2; - index++; - pSrcBuf++; // skip picture param set - len = 0; - } - } - else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || - !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) - { - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); - memcpy(m_vendor_config.pData, config->pData,config->nDataSize); - } - else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) - { - if(m_vendor_config.pData) - { - free(m_vendor_config.pData); - m_vendor_config.pData = NULL; - m_vendor_config.nDataSize = 0; - } - - if (((*((OMX_U32 *) config->pData)) & - VC1_SP_MP_START_CODE_MASK) == - VC1_SP_MP_START_CODE) - { - DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = - (OMX_U8 *) malloc(config->nDataSize); - memcpy(m_vendor_config.pData, config->pData, - config->nDataSize); - m_vc1_profile = VC1_SP_MP_RCV; - } - else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) - { - DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = - (OMX_U8 *) malloc((config->nDataSize)); - memcpy(m_vendor_config.pData, config->pData, - config->nDataSize); - m_vc1_profile = VC1_AP; - } - else if ((config->nDataSize == VC1_STRUCT_C_LEN)) - { - DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); - memcpy(m_vendor_config.pData,config->pData,config->nDataSize); - m_vc1_profile = VC1_SP_MP_RCV; - } - else - { - DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); - } - } - return ret; - } - else if (configIndex == OMX_IndexConfigVideoNalSize) - { - - pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); - nal_length = pNal->nNaluBytes; - m_frame_parser.init_nal_length(nal_length); - DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d",nal_length); - return ret; - } - - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetExtensionIndex - -DESCRIPTION - OMX GetExtensionIndex method implementaion. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_STRING paramName, - OMX_OUT OMX_INDEXTYPE* indexType) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); - return OMX_ErrorInvalidState; - } - else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; - } - else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) - { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; - } -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; - } - else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; - } - else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { - DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName); - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; - } - else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; - } -#endif - else { - DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName); - return OMX_ErrorNotImplemented; - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetState - -DESCRIPTION - Returns the state information back to the caller. - -PARAMETERS - . - -RETURN VALUE - Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STATETYPE* state) -{ - *state = m_state; - DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentTunnelRequest - -DESCRIPTION - OMX Component Tunnel Request method implementation. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_HANDLETYPE peerComponent, - OMX_IN OMX_U32 peerPort, - OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) -{ - DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::UseOutputBuffer - -DESCRIPTION - Helper function for Use buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_extradata() -{ -#ifdef USE_ION - if (drv_ctx.extradata_info.buffer_size) { - if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { - munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); - close(drv_ctx.extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&drv_ctx.extradata_info.ion); - } - drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); - DEBUG_PRINT_HIGH("allocate extradata memory size %d\n", drv_ctx.extradata_info.size); - drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( - drv_ctx.extradata_info.size, 4096, - &drv_ctx.extradata_info.ion.ion_alloc_data, - &drv_ctx.extradata_info.ion.fd_ion_data, 0); - if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { - DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n"); - return OMX_ErrorInsufficientResources; - } - drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, - drv_ctx.extradata_info.size, - PROT_READ|PROT_WRITE, MAP_SHARED, - drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); - if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); - close(drv_ctx.extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&drv_ctx.extradata_info.ion); - return OMX_ErrorInsufficientResources; - } - memset(drv_ctx.extradata_info.uaddr, 0, drv_ctx.extradata_info.size); - } -#endif - return OMX_ErrorNone; -} - -void omx_vdec::free_extradata() { -#ifdef USE_ION - if (drv_ctx.extradata_info.uaddr) { - munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); - close(drv_ctx.extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&drv_ctx.extradata_info.ion); - } - memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); -#endif -} - -OMX_ERRORTYPE omx_vdec::use_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - struct vdec_setbuffer_cmd setbuffers; - OMX_PTR privateAppData = NULL; - private_handle_t *handle = NULL; - OMX_U8 *buff = buffer; - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - int extra_idx = 0; - - if (!m_out_mem_ptr) { - DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); - eRet = allocate_output_headers(); - if (eRet == OMX_ErrorNone) - eRet = allocate_extradata(); - } - - if (eRet == OMX_ErrorNone) { - for(i=0; i< drv_ctx.op_buf.actualcount; i++) { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - break; - } - } - } - - if(i >= drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount); - eRet = OMX_ErrorInsufficientResources; - } - - if (eRet == OMX_ErrorNone) { -#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) - if(m_enable_android_native_buffers) { - if (m_use_android_native_buffers) { - UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; - sp nBuf = params->nativeBuffer; - handle = (private_handle_t *)nBuf->handle; - privateAppData = params->pAppPrivate; - } else { - handle = (private_handle_t *)buff; - privateAppData = appData; - } - - if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { - DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," - " expected %u, got %lu", - drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); - return OMX_ErrorBadParameter; - } - - drv_ctx.op_buf.buffer_size = (OMX_U32)handle->size; - if (!m_use_android_native_buffers) { - if (!secure_mode) { - buff = (OMX_U8*)mmap(0, handle->size, - PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); - if (buff == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); - return OMX_ErrorInsufficientResources; - } - } - } -#if defined(_ANDROID_ICS_) - native_buffer[i].nativehandle = handle; - native_buffer[i].privatehandle = handle; -#endif - if(!handle) { - DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); - return OMX_ErrorBadParameter; - } - drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; - drv_ctx.ptr_outputbuffer[i].offset = 0; - drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; - drv_ctx.ptr_outputbuffer[i].mmaped_size = - drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; - } else -#endif - - if (!ouput_egl_buffers && !m_use_output_pmem) { -#ifdef USE_ION - DEBUG_PRINT_HIGH("allocate output buffer memory size %d\n", drv_ctx.op_buf.buffer_size); - drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( - drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, - &drv_ctx.op_buf_ion_info[i].ion_alloc_data, - &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); - if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd); - return OMX_ErrorInsufficientResources; - } - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; -#else - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - open (MEM_DEVICE,O_RDWR); - - if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { - DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); - return OMX_ErrorInsufficientResources; - } - - /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ - if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) - { - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - open (MEM_DEVICE,O_RDWR); - if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { - DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, - drv_ctx.op_buf.buffer_size, - drv_ctx.op_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(drv_ctx.ptr_outputbuffer[i].pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if(!secure_mode) { - drv_ctx.ptr_outputbuffer[i].bufferaddr = - (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, - PROT_READ|PROT_WRITE, MAP_SHARED, - drv_ctx.ptr_outputbuffer[i].pmem_fd,0); - if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { - close(drv_ctx.ptr_outputbuffer[i].pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[i]); -#endif - DEBUG_PRINT_ERROR("Unable to mmap output buffer\n"); - return OMX_ErrorInsufficientResources; - } - } - drv_ctx.ptr_outputbuffer[i].offset = 0; - privateAppData = appData; - } - else { - - DEBUG_PRINT_HIGH("Use_op_buf: out_pmem=%d",m_use_output_pmem); - if (!appData || !bytes ) { - if(!secure_mode && !buffer) { - DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case"); - return OMX_ErrorBadParameter; - } - } - - OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; - pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; - if (!pmem_list->entryList || !pmem_list->entryList->entry || - !pmem_list->nEntries || - pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { - DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer"); - return OMX_ErrorBadParameter; - } - pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - pmem_list->entryList->entry; - DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x", - pmem_info->pmem_fd); - drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; - drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; - drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; - drv_ctx.ptr_outputbuffer[i].mmaped_size = - drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; - privateAppData = appData; - } - m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; - m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; - - *bufferHdr = (m_out_mem_ptr + i ); - if(secure_mode) - drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; - //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], - sizeof (vdec_bufferpayload)); - - DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, - drv_ctx.ptr_outputbuffer[i].bufferaddr, - drv_ctx.ptr_outputbuffer[i].pmem_fd ); - - buf.index = i; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].length = drv_ctx.op_buf.buffer_size; - plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - - (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; - plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; - plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; - plane[0].data_offset = 0; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; - plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - buf.m.planes = plane; - buf.length = drv_ctx.num_planes; - - DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); - - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { - DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); - /*TODO: How to handle this case */ - return OMX_ErrorInsufficientResources; - } - - if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { - enum v4l2_buf_type buf_type; - buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { - return OMX_ErrorInsufficientResources; - } else { - streaming[CAPTURE_PORT] = true; - DEBUG_PRINT_LOW("\n STREAMON Successful \n "); - } - } - - (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; - if (m_enable_android_native_buffers) { - DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); - (*bufferHdr)->pBuffer = (OMX_U8 *)handle; - } else { - (*bufferHdr)->pBuffer = buff; - } - (*bufferHdr)->pAppPrivate = privateAppData; - BITMASK_SET(&m_out_bm_count,i); - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::use_input_heap_buffers - -DESCRIPTION - OMX Use Buffer Heap allocation method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer); - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!m_inp_heap_ptr) - m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), - drv_ctx.ip_buf.actualcount); - if(!m_phdr_pmem_ptr) - m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) - calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), - drv_ctx.ip_buf.actualcount); - if(!m_inp_heap_ptr || !m_phdr_pmem_ptr) - { - DEBUG_PRINT_ERROR("Insufficent memory"); - eRet = OMX_ErrorInsufficientResources; - } - else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) - { - input_use_buffer = true; - memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); - m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; - m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; - m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; - m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; - m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; - *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; - eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); - DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); - if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], - (unsigned)NULL, (unsigned)NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); - return OMX_ErrorInsufficientResources; - } - m_in_alloc_cnt++; - } - else - { - DEBUG_PRINT_ERROR("All i/p buffers have been set!"); - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::UseBuffer - -DESCRIPTION - OMX Use Buffer method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE error = OMX_ErrorNone; - struct vdec_setbuffer_cmd setbuffers; - - if (bufferHdr == NULL || bytes == 0) - { - if(!secure_mode && buffer == NULL) { - DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer); - return OMX_ErrorBadParameter; - } - } - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(port == OMX_CORE_INPUT_PORT_INDEX) - error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested - else - { - DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); - error = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error); - if(error == OMX_ErrorNone) - { - if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && - BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && - BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - return error; -} - -OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, - OMX_BUFFERHEADERTYPE *pmem_bufferHdr) -{ - if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) - { - if(m_inp_heap_ptr[bufferindex].pBuffer) - free(m_inp_heap_ptr[bufferindex].pBuffer); - m_inp_heap_ptr[bufferindex].pBuffer = NULL; - } - if (pmem_bufferHdr) - free_input_buffer(pmem_bufferHdr); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - if (bufferHdr == NULL || m_inp_mem_ptr == NULL) - { - return OMX_ErrorBadParameter; - } - - index = bufferHdr - m_inp_mem_ptr; - DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); - - if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) - { - DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); - if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) - { - struct vdec_setbuffer_cmd setbuffers; - setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], - sizeof (vdec_bufferpayload)); - DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d", - drv_ctx.ptr_inputbuffer[index].pmem_fd); - DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %d", - drv_ctx.ptr_inputbuffer[index].mmaped_size, - drv_ctx.ptr_inputbuffer[index].bufferaddr); - munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, - drv_ctx.ptr_inputbuffer[index].mmaped_size); - close (drv_ctx.ptr_inputbuffer[index].pmem_fd); - drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; - if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) - { - free(m_desc_buffer_ptr[index].buf_addr); - m_desc_buffer_ptr[index].buf_addr = NULL; - m_desc_buffer_ptr[index].desc_data_size = 0; - } -#ifdef USE_ION - free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); -#endif - } - } - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - - if (bufferHdr == NULL || m_out_mem_ptr == NULL) - { - return OMX_ErrorBadParameter; - } - - index = bufferHdr - m_out_mem_ptr; - DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index); - - if (index < drv_ctx.op_buf.actualcount - && drv_ctx.ptr_outputbuffer) - { - DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index, - drv_ctx.ptr_outputbuffer[index].bufferaddr); - - struct vdec_setbuffer_cmd setbuffers; - setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], - sizeof (vdec_bufferpayload)); -#ifdef _ANDROID_ - if(m_enable_android_native_buffers) { - if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { - munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, - drv_ctx.ptr_outputbuffer[index].mmaped_size); - } - drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; - } else { -#endif - if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) - { - DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", - drv_ctx.ptr_outputbuffer[0].pmem_fd); - DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %d", - drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, - drv_ctx.ptr_outputbuffer[0].bufferaddr); - munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, - drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); - close (drv_ctx.ptr_outputbuffer[0].pmem_fd); - drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[0]); -#endif - } -#ifdef _ANDROID_ - } -#endif - if (release_output_done()) { - free_extradata(); - } - } - - return OMX_ErrorNone; - -} - -OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes) -{ - OMX_BUFFERHEADERTYPE *input = NULL; - unsigned char *buf_addr = NULL; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned i = 0; - - /* Sanity Check*/ - if (bufferHdr == NULL) - { - return OMX_ErrorBadParameter; - } - - if (m_inp_heap_ptr == NULL) - { - m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), - drv_ctx.ip_buf.actualcount); - m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), - drv_ctx.ip_buf.actualcount); - - if (m_inp_heap_ptr == NULL) - { - DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - } - - /*Find a Free index*/ - for(i=0; i< drv_ctx.ip_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); - break; - } - } - - if (i < drv_ctx.ip_buf.actualcount) - { - buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); - - if (buf_addr == NULL) - { - return OMX_ErrorInsufficientResources; - } - - *bufferHdr = (m_inp_heap_ptr + i); - input = *bufferHdr; - BITMASK_SET(&m_heap_inp_bm_count,i); - - input->pBuffer = (OMX_U8 *)buf_addr; - input->nSize = sizeof(OMX_BUFFERHEADERTYPE); - input->nVersion.nVersion = OMX_SPEC_VERSION; - input->nAllocLen = drv_ctx.ip_buf.buffer_size; - input->pAppPrivate = appData; - input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; - DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr ); - eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); - DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); - /*Add the Buffers to freeq*/ - if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i], - (unsigned)NULL, (unsigned)NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); - return OMX_ErrorInsufficientResources; - } - } - else - { - return OMX_ErrorBadParameter; - } - - return eRet; - -} - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateInputBuffer - -DESCRIPTION - Helper function for allocate buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_input_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct vdec_setbuffer_cmd setbuffers; - OMX_BUFFERHEADERTYPE *input = NULL; - unsigned i = 0; - unsigned char *buf_addr = NULL; - int pmem_fd = -1; - - if(bytes != drv_ctx.ip_buf.buffer_size) - { - DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d", - bytes, drv_ctx.ip_buf.buffer_size); - return OMX_ErrorBadParameter; - } - - if(!m_inp_mem_ptr) - { - DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)", - drv_ctx.ip_buf.actualcount, - drv_ctx.ip_buf.buffer_size); - - m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); - - if (m_inp_mem_ptr == NULL) - { - return OMX_ErrorInsufficientResources; - } - - drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ - calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); - - if (drv_ctx.ptr_inputbuffer == NULL) - { - return OMX_ErrorInsufficientResources; - } -#ifdef USE_ION - drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ - calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); - - if (drv_ctx.ip_buf_ion_info == NULL) - { - return OMX_ErrorInsufficientResources; - } -#endif - - for (i=0; i < drv_ctx.ip_buf.actualcount; i++) - { - drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; -#ifdef USE_ION - drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; -#endif - } - } - - for(i=0; i< drv_ctx.ip_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_inp_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); - break; - } - } - - if(i < drv_ctx.ip_buf.actualcount) - { - struct v4l2_buffer buf; - struct v4l2_plane plane; - int rc; - -#ifdef USE_ION - DEBUG_PRINT_HIGH("\n Allocate input Buffer size %d\n", drv_ctx.ip_buf.buffer_size); - drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( - drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, - &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, - &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); - if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; -#else - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); - return OMX_ErrorInsufficientResources; - } - - if (pmem_fd == 0) - { - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, - drv_ctx.ip_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if (!secure_mode) { - buf_addr = (unsigned char *)mmap(NULL, - drv_ctx.ip_buf.buffer_size, - PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); - - if (buf_addr == MAP_FAILED) - { - close(pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); -#endif - DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); - return OMX_ErrorInsufficientResources; - } - } - *bufferHdr = (m_inp_mem_ptr + i); - if (secure_mode) - drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; - else - drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; - drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; - drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; - drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; - drv_ctx.ptr_inputbuffer [i].offset = 0; - - - buf.index = i; - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane.bytesused = 0; - plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; - plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; - plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; - plane.reserved[1] = 0; - plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; - buf.m.planes = &plane; - buf.length = 1; - - DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_inputbuffer[i]); - - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); - - if (rc) { - DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); - /*TODO: How to handle this case */ - return OMX_ErrorInsufficientResources; - } - - input = *bufferHdr; - BITMASK_SET(&m_inp_bm_count,i); - DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr); - if (secure_mode) - input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; - else - input->pBuffer = (OMX_U8 *)buf_addr; - input->nSize = sizeof(OMX_BUFFERHEADERTYPE); - input->nVersion.nVersion = OMX_SPEC_VERSION; - input->nAllocLen = drv_ctx.ip_buf.buffer_size; - input->pAppPrivate = appData; - input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; - input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; - - if (drv_ctx.disable_dmx) - { - eRet = allocate_desc_buffer(i); - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateOutputBuffer - -DESCRIPTION - Helper fn for AllocateBuffer in the output pin - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything went well. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - struct vdec_setbuffer_cmd setbuffers; - int extra_idx = 0; -#ifdef USE_ION - int ion_device_fd =-1; - struct ion_allocation_data ion_alloc_data; - struct ion_fd_data fd_ion_data; -#endif - if(!m_out_mem_ptr) - { - DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)", - drv_ctx.op_buf.actualcount, - drv_ctx.op_buf.buffer_size); - int nBufHdrSize = 0; - int nPlatformEntrySize = 0; - int nPlatformListSize = 0; - int nPMEMInfoSize = 0; - int pmem_fd = -1; - unsigned char *pmem_baseaddress = NULL; - - OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; - - DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n", - drv_ctx.op_buf.actualcount); - nBufHdrSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_BUFFERHEADERTYPE); - - nPMEMInfoSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); - nPlatformListSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); - nPlatformEntrySize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); - - DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, - sizeof(OMX_BUFFERHEADERTYPE), - nPMEMInfoSize, - nPlatformListSize); - DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize, - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - DEBUG_PRINT_HIGH("allocate outputBuffer size %d \n",drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount); - ion_device_fd = alloc_map_ion_memory( - drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount, - drv_ctx.op_buf.alignment, - &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0); - if (ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - pmem_fd = fd_ion_data.fd; -#else - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", - drv_ctx.op_buf.buffer_size); - return OMX_ErrorInsufficientResources; - } - - if(pmem_fd == 0) - { - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", - drv_ctx.op_buf.buffer_size); - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size * - drv_ctx.op_buf.actualcount, - drv_ctx.op_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if (!secure_mode) { - pmem_baseaddress = (unsigned char *)mmap(NULL, - (drv_ctx.op_buf.buffer_size * - drv_ctx.op_buf.actualcount), - PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); - if (pmem_baseaddress == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\n MMAP failed for Size %d", - drv_ctx.op_buf.buffer_size); - close(pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - // Alloc mem for platform specific info - char *pPtr=NULL; - pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + - nPMEMInfoSize,1); - drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ - calloc (sizeof(struct vdec_bufferpayload), - drv_ctx.op_buf.actualcount); - drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ - calloc (sizeof (struct vdec_output_frameinfo), - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ - calloc (sizeof(struct vdec_ion), - drv_ctx.op_buf.actualcount); -#endif - - if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer - && drv_ctx.ptr_respbuffer) - { - drv_ctx.ptr_outputbuffer[0].mmaped_size = - (drv_ctx.op_buf.buffer_size * - drv_ctx.op_buf.actualcount); - bufHdr = m_out_mem_ptr; - m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); - m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) - (((char *) m_platform_list) + nPlatformListSize); - m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - (((char *) m_platform_entry) + nPlatformEntrySize); - pPlatformList = m_platform_list; - pPlatformEntry = m_platform_entry; - pPMEMInfo = m_pmem_info; - - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); - - // Settting the entire storage nicely - DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry); - DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); - for(i=0; i < drv_ctx.op_buf.actualcount ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = bytes; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = appData; - bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - // Platform specific PMEM Information - // Initialize the Platform Entry - //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i); - pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pPlatformEntry->entry = pPMEMInfo; - // Initialize the Platform List - pPlatformList->nEntries = 1; - pPlatformList->entryList = pPlatformEntry; - // Keep pBuffer NULL till vdec is opened - bufHdr->pBuffer = NULL; - bufHdr->nOffset = 0; - - pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; - pPMEMInfo->pmem_fd = 0; - bufHdr->pPlatformPrivate = pPlatformList; - - drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd; - m_pmem_info[i].pmem_fd = pmem_fd; -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd; - drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data; - drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data; -#endif - - /*Create a mapping between buffers*/ - bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; - drv_ctx.ptr_respbuffer[i].client_data = (void *)\ - &drv_ctx.ptr_outputbuffer[i]; - drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; - drv_ctx.ptr_outputbuffer[i].bufferaddr = - pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); - - DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p", - pmem_fd, drv_ctx.ptr_outputbuffer[i].offset, - drv_ctx.ptr_outputbuffer[i].bufferaddr); - // Move the buffer and buffer header pointers - bufHdr++; - pPMEMInfo++; - pPlatformEntry++; - pPlatformList++; - } - } - else - { - DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ - m_out_mem_ptr, pPtr); - if(m_out_mem_ptr) - { - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(pPtr) - { - free(pPtr); - pPtr = NULL; - } - if(drv_ctx.ptr_outputbuffer) - { - free(drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } - if(drv_ctx.ptr_respbuffer) - { - free(drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif - eRet = OMX_ErrorInsufficientResources; - } - if (eRet == OMX_ErrorNone) - eRet = allocate_extradata(); - } - - for(i=0; i< drv_ctx.op_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); - break; - } - } - - if (eRet == OMX_ErrorNone) - { - if(i < drv_ctx.op_buf.actualcount) - { - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - int rc; - m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; - - drv_ctx.ptr_outputbuffer[i].buffer_len = - drv_ctx.op_buf.buffer_size; - - *bufferHdr = (m_out_mem_ptr + i ); - if (secure_mode) { - drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; - } - drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; - - buf.index = i; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].length = drv_ctx.op_buf.buffer_size; - plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - - (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; -#ifdef USE_ION - plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; -#endif - plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; - plane[0].data_offset = 0; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; - plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - buf.m.planes = plane; - buf.length = drv_ctx.num_planes; - DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]); - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); - if (rc) { - /*TODO: How to handle this case */ - return OMX_ErrorInsufficientResources; - } - - if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { - enum v4l2_buf_type buf_type; - buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); - if (rc) { - return OMX_ErrorInsufficientResources; - } else { - streaming[CAPTURE_PORT] = true; - DEBUG_PRINT_LOW("\n STREAMON Successful \n "); - } - } - - (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; - (*bufferHdr)->pAppPrivate = appData; - BITMASK_SET(&m_out_bm_count,i); - } - else - { - DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n"); - eRet = OMX_ErrorInsufficientResources; - } - } - - return eRet; -} - - -// AllocateBuffer -- API Call -/* ====================================================================== -FUNCTION - omx_vdec::AllocateBuffer - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - unsigned i = 0; - OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type - - DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if(port == OMX_CORE_INPUT_PORT_INDEX) - { - if (arbitrary_bytes) - { - eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); - } - else - { - eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); - } - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - { - eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, - appData,bytes); - } - else - { - DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); - if(eRet == OMX_ErrorNone) - { - if(allocate_done()){ - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - } - DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); - return eRet; -} - -// Free Buffer - API call -/* ====================================================================== -FUNCTION - omx_vdec::FreeBuffer - -DESCRIPTION - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int nPortIndex; - DEBUG_PRINT_LOW("In for decoder free_buffer \n"); - - if(m_state == OMX_StateIdle && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); - } - else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| - (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) - { - DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); - } - else if ((port == OMX_CORE_INPUT_PORT_INDEX && - BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || - (port == OMX_CORE_OUTPUT_PORT_INDEX && - BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) - { - DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port); - } - else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) - { - DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - - return OMX_ErrorIncorrectStateOperation; - } - else if (m_state != OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - } - - if(port == OMX_CORE_INPUT_PORT_INDEX) - { - /*Check if arbitrary bytes*/ - if(!arbitrary_bytes && !input_use_buffer) - nPortIndex = buffer - m_inp_mem_ptr; - else - nPortIndex = buffer - m_inp_heap_ptr; - - DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex); - if(nPortIndex < drv_ctx.ip_buf.actualcount) - { - // Clear the bit associated with it. - BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); - BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); - if (input_use_buffer == true) - { - - DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex); - if(m_phdr_pmem_ptr) - free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); - } - else - { - if (arbitrary_bytes) - { - if(m_phdr_pmem_ptr) - free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); - else - free_input_buffer(nPortIndex,NULL); - } - else - free_input_buffer(buffer); - } - m_inp_bPopulated = OMX_FALSE; - /*Free the Buffer Header*/ - if (release_input_done()) - { - DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released"); - free_input_buffer_header(); - } - } - else - { - DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) - && release_input_done()) - { - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); - post_event(OMX_CommandPortDisable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - { - // check if the buffer is valid - nPortIndex = buffer - client_buffers.get_il_buf_hdr(); - if(nPortIndex < drv_ctx.op_buf.actualcount) - { - DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex); - // Clear the bit associated with it. - BITMASK_CLEAR(&m_out_bm_count,nPortIndex); - m_out_bPopulated = OMX_FALSE; - client_buffers.free_output_buffer (buffer); - - if (release_output_done()) - { - free_output_buffer_header(); - } - } - else - { - DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) - && release_output_done()) - { - DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); - - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); - memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); - } -#endif - - post_event(OMX_CommandPortDisable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else - { - eRet = OMX_ErrorBadPortIndex; - } - if((eRet == OMX_ErrorNone) && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - if(release_done()) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); - post_event(OMX_CommandStateSet, OMX_StateLoaded, - OMX_COMPONENT_GENERATE_EVENT); - } - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::EmptyThisBuffer - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE ret1 = OMX_ErrorNone; - unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (buffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); - return OMX_ErrorBadParameter; - } - - if (!m_inp_bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled."); - return OMX_ErrorIncorrectStateOperation; - } - - if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) - { - DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex); - return OMX_ErrorBadPortIndex; - } - -#ifdef _ANDROID_ - if(iDivXDrmDecrypt) - { - OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer); - if(drmErr != OMX_ErrorNone) { - // this error can be ignored - DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr); - } - } -#endif //_ANDROID_ - if (perf_flag) - { - if (!latency) - { - dec_time.stop(); - latency = dec_time.processing_time_us(); - dec_time.start(); - } - } - - if (arbitrary_bytes) - { - nBufferIndex = buffer - m_inp_heap_ptr; - } - else - { - if (input_use_buffer == true) - { - nBufferIndex = buffer - m_inp_heap_ptr; - m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; - m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; - m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; - buffer = &m_inp_mem_ptr[nBufferIndex]; - DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d", - &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); - } - else{ - nBufferIndex = buffer - m_inp_mem_ptr; - } - } - - if (nBufferIndex > drv_ctx.ip_buf.actualcount ) - { - DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", - buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); - if (arbitrary_bytes) - { - post_event ((unsigned)hComp,(unsigned)buffer, - OMX_COMPONENT_GENERATE_ETB_ARBITRARY); - } - else - { - if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) - set_frame_rate(buffer->nTimeStamp); - post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::empty_this_buffer_proxy - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - int push_cnt = 0,i=0; - unsigned nPortIndex = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - struct vdec_input_frameinfo frameinfo; - struct vdec_bufferpayload *temp_buffer; - struct vdec_seqheader seq_header; - bool port_setting_changed = true; - bool not_coded_vop = false; - - /*Should we generate a Aync error event*/ - if (buffer == NULL || buffer->pInputPortPrivate == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); - return OMX_ErrorBadParameter; - } - - nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - - if (nPortIndex > drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", - nPortIndex); - return OMX_ErrorBadParameter; - } - - pending_input_buffers++; - - /* return zero length and not an EOS buffer */ - if (!arbitrary_bytes && (buffer->nFilledLen == 0) && - ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) - { - DEBUG_PRINT_HIGH("\n return zero legth buffer"); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorNone; - } - - - if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){ - mp4StreamType psBits; - psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); - psBits.numBytes = buffer->nFilledLen; - mp4_headerparser.parseHeader(&psBits); - not_coded_vop = mp4_headerparser.is_notcodec_vop( - (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); - if(not_coded_vop) { - DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u", - buffer->nFilledLen,frame_count); - if(buffer->nFlags & OMX_BUFFERFLAG_EOS){ - DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero"); - not_coded_vop = false; - buffer->nFilledLen = 0; - } - } - } - - if(input_flush_progress == true - - || not_coded_vop - - ) - { - DEBUG_PRINT_LOW("\n Flush in progress return buffer "); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorNone; - } - - temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; - - if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) - { - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - /*for use buffer we need to memcpy the data*/ - temp_buffer->buffer_len = buffer->nFilledLen; - - if (input_use_buffer) - { - if (buffer->nFilledLen <= temp_buffer->buffer_len) - { - if(arbitrary_bytes) - { - memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); - } - else - { - memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), - buffer->nFilledLen); - } - } - else - { - return OMX_ErrorBadParameter; - } - - } - - frameinfo.bufferaddr = temp_buffer->bufferaddr; - frameinfo.client_data = (void *) buffer; - frameinfo.datalen = temp_buffer->buffer_len; - frameinfo.flags = 0; - frameinfo.offset = buffer->nOffset; - frameinfo.pmem_fd = temp_buffer->pmem_fd; - frameinfo.pmem_offset = temp_buffer->offset; - frameinfo.timestamp = buffer->nTimeStamp; - if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) - { - DEBUG_PRINT_LOW("ETB: dmx enabled"); - if (m_demux_entries == 0) - { - extract_demux_addr_offsets(buffer); - } - - DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries); - handle_demux_data(buffer); - frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; - frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; - } - else - { - frameinfo.desc_addr = NULL; - frameinfo.desc_size = 0; - } - if(!arbitrary_bytes) - { - frameinfo.flags |= buffer->nFlags; - } - -#ifdef _ANDROID_ - if (m_debug_timestamp) - { - if(arbitrary_bytes) - { - DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); - m_timestamp_list.insert_ts(buffer->nTimeStamp); - } - else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) - { - DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); - m_timestamp_list.insert_ts(buffer->nTimeStamp); - } - } -#endif - -#ifdef INPUT_BUFFER_LOG - if (inputBufferFile1) - { - fwrite((const char *)temp_buffer->bufferaddr, - temp_buffer->buffer_len,1,inputBufferFile1); - } -#endif - - if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) - { - frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; - } - - if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) - { - DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached"); - frameinfo.flags |= VDEC_BUFFERFLAG_EOS; - h264_scratch.nFilledLen = 0; - nal_count = 0; - look_ahead_nal = false; - frame_count = 0; - if (m_frame_parser.mutils) - m_frame_parser.mutils->initialize_frame_checking_environment(); - m_frame_parser.flush(); - h264_last_au_ts = LLONG_MAX; - h264_last_au_flags = 0; - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - } - struct v4l2_buffer buf; - struct v4l2_plane plane; - memset( (void *)&buf, 0, sizeof(buf)); - memset( (void *)&plane, 0, sizeof(plane)); - int rc; - unsigned long print_count; - if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) - { buf.flags = V4L2_BUF_FLAG_EOS; - DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ; - } - OMX_ERRORTYPE eRet = OMX_ErrorNone; - buf.index = nPortIndex; - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane.bytesused = temp_buffer->buffer_len; - plane.length = drv_ctx.ip_buf.buffer_size; - plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - - (unsigned long)temp_buffer->offset; - plane.reserved[0] = temp_buffer->pmem_fd; - plane.reserved[1] = temp_buffer->offset; - plane.data_offset = 0; - buf.m.planes = &plane; - buf.length = 1; - if (frameinfo.timestamp >= LLONG_MAX) { - buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; - } - //assumption is that timestamp is in milliseconds - buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; - buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); - buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; - - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); - if(rc) - { - DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n"); - return OMX_ErrorHardware; - } - if(!streaming[OUTPUT_PORT]) - { - enum v4l2_buf_type buf_type; - int ret,r; - - buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); - ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); - if(!ret) { - DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n"); - streaming[OUTPUT_PORT] = true; - } else{ - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n"); - DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorBadParameter; - } -} - DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", - frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); - time_stamp_dts.insert_timestamp(buffer); - - return ret; -} - -/* ====================================================================== -FUNCTION - omx_vdec::FillThisBuffer - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("FTB in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (!m_out_bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled."); - return OMX_ErrorIncorrectStateOperation; - } - - if (buffer == NULL || - ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) - { - return OMX_ErrorBadParameter; - } - - if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) - { - DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex); - return OMX_ErrorBadPortIndex; - } - - DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg); - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_vdec::fill_this_buffer_proxy - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) -{ - OMX_ERRORTYPE nRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *buffer = bufferAdd; - unsigned nPortIndex = 0; - struct vdec_fillbuffer_cmd fillbuffer; - struct vdec_bufferpayload *ptr_outputbuffer = NULL; - struct vdec_output_frameinfo *ptr_respbuffer = NULL; - - nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); - - if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) - return OMX_ErrorBadParameter; - - DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", - bufferAdd, bufferAdd->pBuffer); - /*Return back the output buffer to client*/ - if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true) - { - DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - return OMX_ErrorNone; - } - pending_output_buffers++; - buffer = client_buffers.get_dr_buf_hdr(bufferAdd); - ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; - if (ptr_respbuffer) - { - ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; - } - - if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) - { - DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - pending_output_buffers--; - return OMX_ErrorBadParameter; - } - - /* memcpy (&fillbuffer.buffer,ptr_outputbuffer, - sizeof(struct vdec_bufferpayload)); - fillbuffer.client_data = bufferAdd;*/ - -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - // Acquire a write lock on this buffer. - if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle, - GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { - DEBUG_PRINT_ERROR("Failed to acquire genlock"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - pending_output_buffers--; - return OMX_ErrorInsufficientResources; - } else { - native_buffer[buffer - m_out_mem_ptr].inuse = true; - } - } -#endif - int rc = 0; - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - memset( (void *)&buf, 0, sizeof(buf)); - memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); - int extra_idx = 0; - - buf.index = nPortIndex; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].bytesused = buffer->nFilledLen; - plane[0].length = drv_ctx.op_buf.buffer_size; - plane[0].m.userptr = - (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - - (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; - plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; - plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; - plane[0].data_offset = 0; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].bytesused = 0; - plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; - plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - buf.m.planes = plane; - buf.length = drv_ctx.num_planes; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); - if (rc) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to qbuf to driver"); - } -//#ifdef _ANDROID_ICS_ - // if (m_enable_android_native_buffers) - // { - // Unlock the buffer - // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { - // DEBUG_PRINT_ERROR("Releasing genlock failed"); - // return OMX_ErrorInsufficientResources; - /// } else { - // native_buffer[buffer - m_out_mem_ptr].inuse = false; - // } - // } -//#endif - //m_cb.FillBufferDone (hComp,m_app_data,buffer); - // pending_output_buffers--; - // return OMX_ErrorBadParameter; - //} - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SetCallbacks - -DESCRIPTION - Set the callbacks. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_CALLBACKTYPE* callbacks, - OMX_IN OMX_PTR appData) -{ - - m_cb = *callbacks; - DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ - m_cb.EventHandler,m_cb.FillBufferDone); - m_app_data = appData; - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentDeInit - -DESCRIPTION - Destroys the component and release memory allocated to the heap. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) -{ -#ifdef _ANDROID_ - if(iDivXDrmDecrypt) - { - delete iDivXDrmDecrypt; - iDivXDrmDecrypt=NULL; - } -#endif //_ANDROID_ - - unsigned i = 0; - if (OMX_StateLoaded != m_state) - { - DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ - m_state); - DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); - } - else - { - DEBUG_PRINT_HIGH("\n Playback Ended - PASSED"); - } - - /*Check if the output buffers have to be cleaned up*/ - if(m_out_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing the Output Memory\n"); - for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) - { - free_output_buffer (&m_out_mem_ptr[i]); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - if (native_buffer[i].inuse) - { - if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) { - DEBUG_PRINT_ERROR("Unlocking genlock failed"); - } - native_buffer[i].inuse = false; - } - } -#endif - } -#ifdef _ANDROID_ICS_ - memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); -#endif - } - - /*Check if the input buffers have to be cleaned up*/ - if(m_inp_mem_ptr || m_inp_heap_ptr) - { - DEBUG_PRINT_LOW("Freeing the Input Memory\n"); - for (i = 0; i. - -PARAMETERS - . - -RETURN VALUE - Not Implemented error. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN void* eglImage) -{ - OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; - -#ifdef USE_EGL_IMAGE_GPU - PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; - EGLint fd = -1, offset = 0,pmemPtr = 0; -#else - int fd = -1, offset = 0; -#endif - DEBUG_PRINT_HIGH("\nuse EGL image support for decoder"); - if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { - DEBUG_PRINT_ERROR("\n "); - } -#ifdef USE_EGL_IMAGE_GPU - if(m_display_id == NULL) { - DEBUG_PRINT_ERROR("Display ID is not set by IL client \n"); - return OMX_ErrorInsufficientResources; - } - egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) - eglGetProcAddress("eglQueryImageKHR"); - egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); - egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); - egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); -#else //with OMX test app - struct temp_egl { - int pmem_fd; - int offset; - }; - struct temp_egl *temp_egl_id = NULL; - void * pmemPtr = (void *) eglImage; - temp_egl_id = (struct temp_egl *)eglImage; - if (temp_egl_id != NULL) - { - fd = temp_egl_id->pmem_fd; - offset = temp_egl_id->offset; - } -#endif - if (fd < 0) { - DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd); - return OMX_ErrorInsufficientResources; - } - pmem_info.pmem_fd = (OMX_U32) fd; - pmem_info.offset = (OMX_U32) offset; - pmem_entry.entry = (void *) &pmem_info; - pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pmem_list.entryList = &pmem_entry; - pmem_list.nEntries = 1; - ouput_egl_buffers = true; - if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, - (void *)&pmem_list, drv_ctx.op_buf.buffer_size, - (OMX_U8 *)pmemPtr)) { - DEBUG_PRINT_ERROR("use buffer call failed for egl image\n"); - return OMX_ErrorInsufficientResources; - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentRoleEnum - -DESCRIPTION - OMX Component Role Enum method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_U8* role, - OMX_IN OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) - ) - - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } - return eRet; -} - - - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateDone - -DESCRIPTION - Checks if entire buffer pool is allocated by IL Client or not. - Need this to move to IDLE state. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_vdec::allocate_done(void) -{ - bool bRet = false; - bool bRet_In = false; - bool bRet_Out = false; - - bRet_In = allocate_input_done(); - bRet_Out = allocate_output_done(); - - if(bRet_In && bRet_Out) - { - bRet = true; - } - - return bRet; -} -/* ====================================================================== -FUNCTION - omx_vdec::AllocateInputDone - -DESCRIPTION - Checks if I/P buffer pool is allocated by IL Client or not. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_vdec::allocate_input_done(void) -{ - bool bRet = false; - unsigned i=0; - - if (m_inp_mem_ptr == NULL) - { - return bRet; - } - if(m_inp_mem_ptr ) - { - for(;i= drv_ctx.op_buf.actualcount) - { - DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer); - return OMX_ErrorBadParameter; - } - else if (output_flush_progress) - { - DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); - buffer->nFilledLen = 0; - buffer->nTimeStamp = 0; - buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; - buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; - } - - DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", - buffer, buffer->pBuffer); - pending_output_buffers --; - - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) - { - DEBUG_PRINT_HIGH("\n Output EOS has been reached"); - if (!output_flush_progress) - post_event((unsigned)NULL, (unsigned)NULL, - OMX_COMPONENT_GENERATE_EOS_DONE); - - if (psource_frame) - { - m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); - psource_frame = NULL; - } - if (pdest_frame) - { - pdest_frame->nFilledLen = 0; - m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL, - (unsigned)NULL); - pdest_frame = NULL; - } - } - - DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer); -#ifdef OUTPUT_BUFFER_LOG - if (outputBufferFile1 && buffer->nFilledLen) - { - int buf_index = buffer - m_out_mem_ptr; - int stride = drv_ctx.video_resolution.stride; - int scanlines = drv_ctx.video_resolution.scan_lines; - char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; - int i; - int bytes_written = 0; - for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { - bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); - temp += stride; - } - temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; - int stride_c = stride; - for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { - bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); - temp += stride_c; - } - } -#endif - - /* For use buffer we need to copy the data */ - if (!output_flush_progress) - { - time_stamp_dts.get_next_timestamp(buffer, - (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - if (m_debug_timestamp) - { - { - OMX_TICKS expected_ts = 0; - m_timestamp_list.pop_min_ts(expected_ts); - DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", - buffer->nTimeStamp, expected_ts); - - if (buffer->nTimeStamp != expected_ts) - { - DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check"); - } - } - } - } - if (m_cb.FillBufferDone) - { - if (buffer->nFilledLen > 0) - { - handle_extradata(buffer); - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - // Keep min timestamp interval to handle corrupted bit stream scenario - set_frame_rate(buffer->nTimeStamp); - else if (arbitrary_bytes) - adjust_timestamp(buffer->nTimeStamp); - if (perf_flag) - { - if (!proc_frms) - { - dec_time.stop(); - latency = dec_time.processing_time_us() - latency; - DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); - dec_time.start(); - fps_metrics.start(); - } - proc_frms++; - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) - { - OMX_U64 proc_time = 0; - fps_metrics.stop(); - proc_time = fps_metrics.processing_time_us(); - DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", - proc_frms, (float)proc_time / 1e6, - (float)(1e6 * proc_frms) / proc_time); - proc_frms = 0; - } - } - -#ifdef OUTPUT_EXTRADATA_LOG - if (outputExtradataFile) - { - - OMX_OTHER_EXTRADATATYPE *p_extra = NULL; - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(buffer->pBuffer + buffer->nOffset + - buffer->nFilledLen + 3)&(~3)); - while(p_extra && - (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) - { - DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); - fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); - if (p_extra->eType == OMX_ExtraDataNone) - { - break; - } - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - } -#endif - } - if (buffer->nFlags & OMX_BUFFERFLAG_EOS){ - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } - - pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) - buffer->pPlatformPrivate)->entryList->entry; - DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - if (native_buffer[buffer - m_out_mem_ptr].inuse) { - if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { - DEBUG_PRINT_ERROR("Unlocking genlock failed"); - return OMX_ErrorInsufficientResources; - } - else { - native_buffer[buffer - m_out_mem_ptr].inuse = false; - } - } - } -#endif - OMX_BUFFERHEADERTYPE *il_buffer; - il_buffer = client_buffers.get_il_buf_hdr(buffer); - if (il_buffer) - m_cb.FillBufferDone (hComp,m_app_data,il_buffer); - else { - DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd); - } - else - { - return OMX_ErrorBadParameter; - } - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE* buffer) -{ - - if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) - { - DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer); - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", - buffer, buffer->pBuffer); - pending_input_buffers--; - - if (arbitrary_bytes) - { - if (pdest_frame == NULL && input_flush_progress == false) - { - DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer); - pdest_frame = buffer; - buffer->nFilledLen = 0; - buffer->nTimeStamp = LLONG_MAX; - push_input_buffer (hComp); - } - else - { - DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer); - buffer->nFilledLen = 0; - if (!m_input_free_q.insert_entry((unsigned)buffer, - (unsigned)NULL, (unsigned)NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); - } - } - } - else if(m_cb.EmptyBufferDone) - { - buffer->nFilledLen = 0; - if (input_use_buffer == true){ - buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; - } - m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); - } - return OMX_ErrorNone; -} - -int omx_vdec::async_message_process (void *context, void* message) -{ - omx_vdec* omx = NULL; - struct vdec_msginfo *vdec_msg = NULL; - OMX_BUFFERHEADERTYPE* omxhdr = NULL; - struct v4l2_buffer *v4l2_buf_ptr = NULL; - struct vdec_output_frameinfo *output_respbuf = NULL; - int rc=1; - if (context == NULL || message == NULL) - { - DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); - return -1; - } - vdec_msg = (struct vdec_msginfo *)message; - - omx = reinterpret_cast(context); - - switch (vdec_msg->msgcode) - { - - case VDEC_MSG_EVT_HW_ERROR: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_HARDWARE_ERROR); - break; - - case VDEC_MSG_RESP_START_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_START_DONE); - break; - - case VDEC_MSG_RESP_STOP_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - break; - - case VDEC_MSG_RESP_RESUME_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_RESUME_DONE); - break; - - case VDEC_MSG_RESP_PAUSE_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_PAUSE_DONE); - break; - - case VDEC_MSG_RESP_FLUSH_INPUT_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); - break; - case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); - break; - case VDEC_MSG_RESP_INPUT_FLUSHED: - case VDEC_MSG_RESP_INPUT_BUFFER_DONE: - - /* omxhdr = (OMX_BUFFERHEADERTYPE* ) - vdec_msg->msgdata.input_frame_clientdata; */ - - v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; - omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index; - if (omxhdr == NULL || - ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) - { - omxhdr = NULL; - vdec_msg->status_code = VDEC_S_EFATAL; - } - - omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, - OMX_COMPONENT_GENERATE_EBD); - break; - case VDEC_MSG_EVT_INFO_FIELD_DROPPED: - int64_t *timestamp; - timestamp = (int64_t *) malloc(sizeof(int64_t)); - if (timestamp) { - *timestamp = vdec_msg->msgdata.output_frame.time_stamp; - omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); - DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld", - vdec_msg->msgdata.output_frame.time_stamp); - } - break; - case VDEC_MSG_RESP_OUTPUT_FLUSHED: - case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: - - v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; - omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index; - DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", - omxhdr, vdec_msg->msgdata.output_frame.time_stamp, - vdec_msg->msgdata.output_frame.pic_type); - - if (omxhdr && omxhdr->pOutputPortPrivate && - ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && - (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate - - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) - { - if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) - { - omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; - omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; - omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; - omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags; - - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) - { - omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; - //rc = -1; - } - if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) - { - omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - } - vdec_msg->msgdata.output_frame.bufferaddr = - omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; - if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft != - vdec_msg->msgdata.output_frame.framesize.left) - || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) - || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) - || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) { - omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; - omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; - omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; - omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; - DEBUG_PRINT_HIGH("\n Crop information has changed\n"); - omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, - OMX_COMPONENT_GENERATE_PORT_RECONFIG); - } - output_respbuf = (struct vdec_output_frameinfo *)\ - omxhdr->pOutputPortPrivate; - output_respbuf->len = vdec_msg->msgdata.output_frame.len; - output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) - { - output_respbuf->pic_type = PICTURE_TYPE_I; - } - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) - { - output_respbuf->pic_type = PICTURE_TYPE_P; - } - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { - output_respbuf->pic_type = PICTURE_TYPE_B; - } - - if (omx->output_use_buffer) - memcpy ( omxhdr->pBuffer, (void *) - ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + - (unsigned long)vdec_msg->msgdata.output_frame.offset), - vdec_msg->msgdata.output_frame.len); - } - else - omxhdr->nFilledLen = 0; - omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_FBD); - } - else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) - omx->post_event ((unsigned int)NULL, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_EOS_DONE); - else - omx->post_event ((unsigned int)NULL, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_HARDWARE_ERROR); - break; - case VDEC_MSG_EVT_CONFIG_CHANGED: - DEBUG_PRINT_HIGH("\n Port settings changed"); - omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, - OMX_COMPONENT_GENERATE_PORT_RECONFIG); - break; - case VDEC_MSG_EVT_INFO_CONFIG_CHANGED: - { - DEBUG_PRINT_HIGH("\n Port settings changed info"); - // get_buffer_req and populate port defn structure - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_format fmt; - int ret; - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ret = ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); - omx->update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); - omx->drv_ctx.video_resolution.stride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline; - omx->drv_ctx.video_resolution.scan_lines = fmt.fmt.pix_mp.plane_fmt[0].reserved[0]; - omx->m_port_def.nPortIndex = 1; - eRet = omx->update_portdef(&(omx->m_port_def)); - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG); - break; - } - default: - break; - } - return rc; -} - -OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ) -{ - unsigned address,p2,id; - DEBUG_PRINT_LOW("\n Empty this arbitrary"); - - if (buffer == NULL) - { - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u", - buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp); - - /* return zero length and not an EOS buffer */ - /* return buffer if input flush in progress */ - if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && - ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) - { - DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress"); - m_cb.EmptyBufferDone (hComp,m_app_data,buffer); - return OMX_ErrorNone; - } - - if (psource_frame == NULL) - { - DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp); - psource_frame = buffer; - DEBUG_PRINT_LOW("\n Try to Push One Input Buffer "); - push_input_buffer (hComp); - } - else - { - DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer); - if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL, - (unsigned)NULL)) - { - return OMX_ErrorBadParameter; - } - } - - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) -{ - unsigned address,p2,id; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (pdest_frame == NULL || psource_frame == NULL) - { - /*Check if we have a destination buffer*/ - if (pdest_frame == NULL) - { - DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue"); - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *)address; - pdest_frame->nFilledLen = 0; - pdest_frame->nTimeStamp = LLONG_MAX; - DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame); - } - } - - /*Check if we have a destination buffer*/ - if (psource_frame == NULL) - { - DEBUG_PRINT_LOW("\n Get a source buffer from the queue"); - if (m_input_pending_q.m_size) - { - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *)address; - DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, - psource_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", - psource_frame->nFlags,psource_frame->nFilledLen); - - } - } - - } - - while ((pdest_frame != NULL) && (psource_frame != NULL)) - { - switch (codec_type_parse) - { - case CODEC_TYPE_MPEG4: - case CODEC_TYPE_H263: - case CODEC_TYPE_MPEG2: - ret = push_input_sc_codec(hComp); - break; - case CODEC_TYPE_H264: - ret = push_input_h264(hComp); - break; - case CODEC_TYPE_HEVC: - ret = push_input_hevc(hComp); - break; - case CODEC_TYPE_VC1: - ret = push_input_vc1(hComp); - break; - default: - break; - } - if (ret != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); - omx_report_error (); - break; - } - } - - return ret; -} - -OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) -{ - OMX_U32 partial_frame = 1; - OMX_BOOL generate_ebd = OMX_TRUE; - unsigned address,p2,id; - - DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d", - psource_frame,psource_frame->nTimeStamp); - if (m_frame_parser.parse_sc_frame(psource_frame, - pdest_frame,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); - return OMX_ErrorBadParameter; - } - - if (partial_frame == 0) - { - DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d", - pdest_frame->nFilledLen,psource_frame,frame_count); - - - DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp); - /*First Parsed buffer will have only header Hence skip*/ - if (frame_count == 0) - { - DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame "); - - if(codec_type_parse == CODEC_TYPE_MPEG4 || - codec_type_parse == CODEC_TYPE_DIVX) { - mp4StreamType psBits; - psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; - psBits.numBytes = pdest_frame->nFilledLen; - mp4_headerparser.parseHeader(&psBits); - } - - frame_count++; - } - else - { - pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; - if(pdest_frame->nFilledLen) - { - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *) address; - pdest_frame->nFilledLen = 0; - } - } - else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) - { - DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL"); - m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL, - (unsigned)NULL); - pdest_frame = NULL; - } - } - } - else - { - DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen); - /*Check if Destination Buffer is full*/ - if (pdest_frame->nAllocLen == - pdest_frame->nFilledLen + pdest_frame->nOffset) - { - DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); - return OMX_ErrorStreamCorrupt; - } - } - - if (psource_frame->nFilledLen == 0) - { - if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) - { - if (pdest_frame) - { - pdest_frame->nFlags |= psource_frame->nFlags; - DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", - pdest_frame->nFilledLen,frame_count++); - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - } - else - { - DEBUG_PRINT_LOW("\n Last frame in else dest addr") ; - generate_ebd = OMX_FALSE; - } - } - if(generate_ebd) - { - DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame); - m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); - psource_frame = NULL; - - if (m_input_pending_q.m_size) - { - DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame, - psource_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d", - psource_frame->nFlags,psource_frame->nFilledLen); - } - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) -{ - OMX_U32 partial_frame = 1; - unsigned address,p2,id; - OMX_BOOL isNewFrame = OMX_FALSE; - OMX_BOOL generate_ebd = OMX_TRUE; - - if (h264_scratch.pBuffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %d " - "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); - DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); - if (h264_scratch.nFilledLen && look_ahead_nal) - { - look_ahead_nal = false; - if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame"); - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - if (nal_length == 0) - { - DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code"); - if (m_frame_parser.parse_sc_frame(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); - return OMX_ErrorBadParameter; - } - } - else - { - DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); - if (m_frame_parser.parse_h264_nallength(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); - return OMX_ErrorBadParameter; - } - } - - if (partial_frame == 0) - { - if (nal_count == 0 && h264_scratch.nFilledLen == 0) - { - DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip"); - nal_count++; - h264_scratch.nTimeStamp = psource_frame->nTimeStamp; - h264_scratch.nFlags = psource_frame->nFlags; - } - else - { - DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen); - if(h264_scratch.nFilledLen) - { - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, - NALU_TYPE_SPS); -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, - h264_scratch.nFilledLen, NALU_TYPE_SEI); - else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - // If timeinfo is present frame info from SEI is already processed - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, - h264_scratch.nFilledLen, NALU_TYPE_SEI); -#endif - m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); - nal_count++; - if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { - pdest_frame->nTimeStamp = h264_last_au_ts; - pdest_frame->nFlags = h264_last_au_flags; -#ifdef PANSCAN_HDLR - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - h264_parser->update_panscan_data(h264_last_au_ts); -#endif - } - if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || - m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { - h264_last_au_ts = h264_scratch.nTimeStamp; - h264_last_au_flags = h264_scratch.nFlags; -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); - if (!VALID_TS(h264_last_au_ts)) - h264_last_au_ts = ts_in_sei; - } -#endif - } else - h264_last_au_ts = LLONG_MAX; - } - - if (!isNewFrame) - { - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d", - h264_scratch.nFilledLen); - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) - pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - else - { - look_ahead_nal = true; - DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d", - pdest_frame->nFilledLen,frame_count++); - - if (pdest_frame->nFilledLen == 0) - { - DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it"); - look_ahead_nal = false; - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - else - { - if(psource_frame->nFilledLen || h264_scratch.nFilledLen) - { - DEBUG_PRINT_LOW("\n Reset the EOS Flag"); - pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; - } - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - //frame_count++; - pdest_frame = NULL; - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame); - pdest_frame->nFilledLen = 0; - pdest_frame->nFlags = 0; - pdest_frame->nTimeStamp = LLONG_MAX; - } - } - } - } - } - else - { - DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen); - /*Check if Destination Buffer is full*/ - if (h264_scratch.nAllocLen == - h264_scratch.nFilledLen + h264_scratch.nOffset) - { - DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); - return OMX_ErrorStreamCorrupt; - } - } - - if (!psource_frame->nFilledLen) - { - DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame); - - if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) - { - if (pdest_frame) - { - DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer"); - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; - pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; - - DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%d TimeStamp = %x", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++); -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); - if (!VALID_TS(pdest_frame->nTimeStamp)) - pdest_frame->nTimeStamp = ts_in_sei; - } -#endif - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - } - else - { - DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d", - pdest_frame,h264_scratch.nFilledLen); - generate_ebd = OMX_FALSE; - } - } - } - if(generate_ebd && !psource_frame->nFilledLen) - { - m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); - psource_frame = NULL; - if (m_input_pending_q.m_size) - { - DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("\nNext source Buffer flag %d src length %d", - psource_frame->nFlags,psource_frame->nFilledLen); - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc) -{ - OMX_ERRORTYPE rc = OMX_ErrorNone; - if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) - { - memcpy ((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen); - if (pDst->nTimeStamp == LLONG_MAX || pDst->nTimeStamp == 0) - { - pDst->nTimeStamp = pSrc->nTimeStamp; - DEBUG_PRINT_LOW("Assign Dst nTimeStamp=%lld", pDst->nTimeStamp); - } - pDst->nFilledLen += pSrc->nFilledLen; - pSrc->nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("Error: Destination buffer overflow\n"); - rc = OMX_ErrorBadParameter; - } - return rc; -} - -OMX_ERRORTYPE omx_vdec::push_input_hevc (OMX_HANDLETYPE hComp) -{ - OMX_U32 partial_frame = 1; - unsigned address,p2,id; - OMX_BOOL isNewFrame = OMX_FALSE; - OMX_BOOL generate_ebd = OMX_TRUE; - OMX_ERRORTYPE rc = OMX_ErrorNone; - - if (h264_scratch.pBuffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:Hevc Scratch Buffer not allocated"); - return OMX_ErrorBadParameter; - } - - - DEBUG_PRINT_LOW("h264_scratch.nFilledLen %d has look_ahead_nal %d pdest_frame nFilledLen %d nTimeStamp %lld\n", - h264_scratch.nFilledLen, look_ahead_nal, pdest_frame->nFilledLen, pdest_frame->nTimeStamp); - - if (h264_scratch.nFilledLen && look_ahead_nal) - { - look_ahead_nal = false; - - // copy the lookahead buffer in the scratch - rc = copy_buffer(pdest_frame, &h264_scratch); - if (rc != OMX_ErrorNone) - { - return rc; - } - } - if (nal_length == 0) - { - if (m_frame_parser.parse_sc_frame(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); - return OMX_ErrorBadParameter; - } - } - else - { - DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d\n",nal_length); - if (m_frame_parser.parse_h264_nallength(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); - return OMX_ErrorBadParameter; - } - } - - if (partial_frame == 0) - { - if (nal_count == 0 && h264_scratch.nFilledLen == 0) - { - DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip"); - nal_count++; - h264_scratch.nTimeStamp = psource_frame->nTimeStamp; - h264_scratch.nFlags = psource_frame->nFlags; - } - else - { - DEBUG_PRINT_LOW("\n Parsed New NAL Length = %d",h264_scratch.nFilledLen); - if(h264_scratch.nFilledLen) - { - mHEVCutils.isNewFrame(&h264_scratch, 0, isNewFrame); - nal_count++; - } - - if (!isNewFrame) - { - DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %d nTimestamp %lld, pdest_frame nFilledLen %d nTimestamp %lld\n", - h264_scratch.nFilledLen, h264_scratch.nTimeStamp, pdest_frame->nFilledLen, pdest_frame->nTimeStamp); - rc = copy_buffer(pdest_frame, &h264_scratch); - if ( rc != OMX_ErrorNone) - { - return rc; - } - } - else - { - look_ahead_nal = true; - if (pdest_frame->nFilledLen == 0) - { - look_ahead_nal = false; - DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer\n"); - rc = copy_buffer(pdest_frame, &h264_scratch); - if ( rc != OMX_ErrorNone ) - { - return OMX_ErrorBadParameter; - } - } - else - { - if(psource_frame->nFilledLen || h264_scratch.nFilledLen) - { - pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; - } - - DEBUG_PRINT_LOW("FrameDetecetd # %d pdest_frame nFilledLen %d nTimeStamp %lld, look_ahead_nal in h264_scratch nFilledLen %d nTimeStamp %lld \n", - frame_count++, pdest_frame->nFilledLen, pdest_frame->nTimeStamp, h264_scratch.nFilledLen, h264_scratch.nTimeStamp); - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - pdest_frame = NULL; - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("pop the next pdest_buffer %p\n",pdest_frame); - pdest_frame->nFilledLen = 0; - pdest_frame->nFlags = 0; - pdest_frame->nTimeStamp = LLONG_MAX; - } - } - } - } - } - else - { - DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %d nTimeStamp %lld, pdest_frame nFilledLen %d nTimeStamp %lld, h264_scratch nFilledLen %d nTimeStamp %lld \n", - psource_frame->nFilledLen, psource_frame->nTimeStamp, pdest_frame->nFilledLen, pdest_frame->nTimeStamp, h264_scratch.nFilledLen, h264_scratch.nTimeStamp); - - /*Check if Destination Buffer is full*/ - if (h264_scratch.nAllocLen == - h264_scratch.nFilledLen + h264_scratch.nOffset) - { - DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); - return OMX_ErrorStreamCorrupt; - } - } - - if (!psource_frame->nFilledLen) - { - DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client\n",psource_frame); - - if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) - { - if (pdest_frame) - { - DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer\n"); - rc = copy_buffer(pdest_frame, &h264_scratch); - if ( rc != OMX_ErrorNone ) - { - return rc; - } - pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; - pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; - - DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%d TimeStamp = %lld\n", - frame_count, pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - } - else - { - DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d", - pdest_frame,h264_scratch.nFilledLen); - generate_ebd = OMX_FALSE; - } - } - } - if(generate_ebd && !psource_frame->nFilledLen) - { - m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); - psource_frame = NULL; - if (m_input_pending_q.m_size) - { - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("Next source Buffer flag %d nFilledLen %d, nTimeStamp %lld\n", - psource_frame->nFlags,psource_frame->nFilledLen, psource_frame->nTimeStamp); - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) -{ - OMX_U8 *buf, *pdest; - OMX_U32 partial_frame = 1; - OMX_U32 buf_len, dest_len; - - if(first_frame == 0) - { - first_frame = 1; - DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n"); - if(!m_vendor_config.pData) - { - DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n"); - buf = psource_frame->pBuffer; - buf_len = psource_frame->nFilledLen; - - if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == - VC1_SP_MP_START_CODE) - { - m_vc1_profile = VC1_SP_MP_RCV; - } - else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) - { - m_vc1_profile = VC1_AP; - } - else - { - DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n"); - return OMX_ErrorStreamCorrupt; - } - } - else - { - pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + - pdest_frame->nOffset; - dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + - pdest_frame->nOffset); - - if(dest_len < m_vendor_config.nDataSize) - { - DEBUG_PRINT_ERROR("\nDestination buffer full\n"); - return OMX_ErrorBadParameter; - } - else - { - memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); - pdest_frame->nFilledLen += m_vendor_config.nDataSize; - } - } - } - - switch(m_vc1_profile) - { - case VC1_AP: - DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code"); - if (push_input_sc_codec(hComp) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); - return OMX_ErrorBadParameter; - } - break; - - case VC1_SP_MP_RCV: - default: - DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n"); - return OMX_ErrorBadParameter; - } - return OMX_ErrorNone; -} - -bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, - OMX_U32 alignment) -{ - struct pmem_allocation allocation; - allocation.size = buffer_size; - allocation.align = clip2(alignment); - if (allocation.align < 4096) - { - allocation.align = 4096; - } - if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) - { - DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", - allocation.align, allocation.size); - return false; - } - return true; -} -#ifdef USE_ION -int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, - OMX_U32 alignment, struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data, int flag) -{ - int fd = -EINVAL; - int rc = -EINVAL; - int ion_dev_flag; - struct vdec_ion ion_buf_info; - if (!alloc_data || buffer_size <= 0 || !fd_data) { - DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n"); - return -EINVAL; - } - ion_dev_flag = O_RDONLY; - fd = open (MEM_DEVICE, ion_dev_flag); - if (fd < 0) { - DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd); - return fd; - } - alloc_data->flags = 0; - if(!secure_mode && (flag & ION_FLAG_CACHED)) - { - alloc_data->flags |= ION_FLAG_CACHED; - } - alloc_data->len = buffer_size; - alloc_data->align = clip2(alignment); - if (alloc_data->align < 4096) - { - alloc_data->align = 4096; - } - if ((secure_mode) && (flag & ION_SECURE)) - alloc_data->flags |= ION_SECURE; - -#ifdef _HEVC_USE_ADSP_HEAP_ - alloc_data->heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); -#else - alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); -#endif - if (secure_mode) { - alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); - } - rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); - if (rc || !alloc_data->handle) { - DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); - alloc_data->handle = NULL; - close(fd); - fd = -ENOMEM; - return fd; - } - fd_data->handle = alloc_data->handle; - rc = ioctl(fd,ION_IOC_MAP,fd_data); - if (rc) { - DEBUG_PRINT_ERROR("\n ION MAP failed "); - ion_buf_info.ion_alloc_data = *alloc_data; - ion_buf_info.ion_device_fd = fd; - ion_buf_info.fd_ion_data = *fd_data; - free_ion_memory(&ion_buf_info); - fd_data->fd =-1; - close(fd); - fd = -ENOMEM; - } - - return fd; -} - -void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) { - - if(!buf_ion_info) { - DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata"); - return; - } - if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, - &buf_ion_info->ion_alloc_data.handle)) { - DEBUG_PRINT_ERROR("\n ION: free failed" ); - } - close(buf_ion_info->ion_device_fd); - buf_ion_info->ion_device_fd = -1; - buf_ion_info->ion_alloc_data.handle = NULL; - buf_ion_info->fd_ion_data.fd = -1; -} -#endif -void omx_vdec::free_output_buffer_header() -{ - DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released"); - output_use_buffer = false; - ouput_egl_buffers = false; - - if (m_out_mem_ptr) - { - free (m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - - if(m_platform_list) - { - free(m_platform_list); - m_platform_list = NULL; - } - - if (drv_ctx.ptr_respbuffer) - { - free (drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } - if (drv_ctx.ptr_outputbuffer) - { - free (drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif -} - -void omx_vdec::free_input_buffer_header() -{ - input_use_buffer = false; - if (arbitrary_bytes) - { - if (m_frame_parser.mutils) - { - DEBUG_PRINT_LOW("\n Free utils parser"); - delete (m_frame_parser.mutils); - m_frame_parser.mutils = NULL; - } - - if (m_inp_heap_ptr) - { - DEBUG_PRINT_LOW("\n Free input Heap Pointer"); - free (m_inp_heap_ptr); - m_inp_heap_ptr = NULL; - } - - if (m_phdr_pmem_ptr) - { - DEBUG_PRINT_LOW("\n Free input pmem header Pointer"); - free (m_phdr_pmem_ptr); - m_phdr_pmem_ptr = NULL; - } - } - if (m_inp_mem_ptr) - { - DEBUG_PRINT_LOW("\n Free input pmem Pointer area"); - free (m_inp_mem_ptr); - m_inp_mem_ptr = NULL; - } - if (drv_ctx.ptr_inputbuffer) - { - DEBUG_PRINT_LOW("\n Free Driver Context pointer"); - free (drv_ctx.ptr_inputbuffer); - drv_ctx.ptr_inputbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.ip_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free ion context"); - free(drv_ctx.ip_buf_ion_info); - drv_ctx.ip_buf_ion_info = NULL; - } -#endif -} - -int omx_vdec::stream_off(OMX_U32 port) -{ - enum v4l2_buf_type btype; - int rc = 0; - enum v4l2_ports v4l2_port = OUTPUT_PORT; - - if (port == OMX_CORE_INPUT_PORT_INDEX) { - btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - v4l2_port = OUTPUT_PORT; - } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { - btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - v4l2_port = CAPTURE_PORT; - } else if (port == OMX_ALL) { - int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); - int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); - - if (!rc_input) - return rc_input; - else - return rc_output; - } - - if (!streaming[v4l2_port]) { - // already streamed off, warn and move on - DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," - " which is already streamed off", v4l2_port); - return 0; - } - - DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); - - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); - if (rc) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port); - } else { - streaming[v4l2_port] = false; - } - - return rc; -} - -OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_requestbuffers bufreq; - unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; - struct v4l2_format fmt; - int ret = 0; - - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = 1; - if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ - bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.pixelformat = output_capability; - }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.pixelformat = capture_capability; - }else {eRet = OMX_ErrorBadParameter;} - if(eRet==OMX_ErrorNone){ - ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); - } - if(ret) - { - DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); - /*TODO: How to handle this case */ - eRet = OMX_ErrorInsufficientResources; - return eRet; - } - else - { - buffer_prop->actualcount = bufreq.count; - buffer_prop->mincount = bufreq.count; - DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count); - } - DEBUG_PRINT_HIGH("GetBufReq: ActCnt(%d) Size(%d), BufType(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type); - - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); - - update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height); - if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; - DEBUG_PRINT_HIGH("Buffer Size (plane[0].sizeimage) = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); - - if(ret) - { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - int extra_idx = 0; - buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - buf_size = buffer_prop->buffer_size; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - { - DEBUG_PRINT_HIGH("Frame info extra data enabled!"); - client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; - } - if (client_extradata & OMX_INTERLACE_EXTRADATA) - { - client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; - } - if (client_extradata & OMX_PORTDEF_EXTRADATA) - { - client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; - DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n", - client_extra_data_size); - } - if (client_extra_data_size) - { - client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator - buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit - } - drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size; - drv_ctx.extradata_info.count = buffer_prop->actualcount; - drv_ctx.extradata_info.buffer_size = extra_data_size; - buf_size += client_extra_data_size; - buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); - DEBUG_PRINT_HIGH("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d) BufType(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size, buf_size, buffer_prop->buffer_type); - if (in_reconfig) // BufReq will be set to driver when port is disabled - buffer_prop->buffer_size = buf_size; - else if (buf_size != buffer_prop->buffer_size) - { - buffer_prop->buffer_size = buf_size; - eRet = set_buffer_req(buffer_prop); - } - } - DEBUG_PRINT_HIGH("GetBufReq OUT: ActCnt(%d) Size(%d), BufType(%d)\n", - buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type); - return eRet; -} - -OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned buf_size = 0; - struct v4l2_format fmt; - struct v4l2_requestbuffers bufreq; - int ret; - DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); - if (buf_size != buffer_prop->buffer_size) - { - DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", - buffer_prop->buffer_size, buf_size); - eRet = OMX_ErrorBadParameter; - } - else - { - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - - if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ - fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.pixelformat = output_capability; - } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { - fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.pixelformat = capture_capability; - } else {eRet = OMX_ErrorBadParameter;} - - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) - { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); - eRet = OMX_ErrorInsufficientResources; - } - - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = buffer_prop->actualcount; - if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { - bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - } else {eRet = OMX_ErrorBadParameter;} - - if (eRet==OMX_ErrorNone) { - ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); - } - - if (ret) - { - DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); - /*TODO: How to handle this case */ - eRet = OMX_ErrorInsufficientResources; - } else if (bufreq.count < buffer_prop->actualcount) { - DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" - " on v4l2 port %d to %d (prefers %d)", bufreq.type, - buffer_prop->actualcount, bufreq.count); - eRet = OMX_ErrorInsufficientResources; - } else { - if (!client_buffers.update_buffer_req()) { - DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); - eRet = OMX_ErrorInsufficientResources; - } - } - } - if (!eRet && buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) - { - // need to update extradata buffers also - drv_ctx.extradata_info.size = buffer_prop->actualcount * drv_ctx.extradata_info.buffer_size; - drv_ctx.extradata_info.count = buffer_prop->actualcount; - } - return eRet; -} - -OMX_ERRORTYPE omx_vdec::update_picture_resolution() -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - return eRet; -} - -OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (!portDefn) - { - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("omx_vdec::update_portdef\n"); - portDefn->nVersion.nVersion = OMX_SPEC_VERSION; - portDefn->nSize = sizeof(portDefn); - portDefn->eDomain = OMX_PortDomainVideo; - if (drv_ctx.frame_rate.fps_denominator > 0) - portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / - drv_ctx.frame_rate.fps_denominator; - else { - DEBUG_PRINT_ERROR("Error: Divide by zero \n"); - return OMX_ErrorBadParameter; - } - if (0 == portDefn->nPortIndex) - { - portDefn->eDir = OMX_DirInput; - portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; - portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; - portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; - portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; - portDefn->format.video.eCompressionFormat = eCompressionFormat; - portDefn->bEnabled = m_inp_bEnabled; - portDefn->bPopulated = m_inp_bPopulated; - } - else if (1 == portDefn->nPortIndex) - { - unsigned int buf_size = 0; - if (!client_buffers.update_buffer_req()) { - DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed"); - return OMX_ErrorHardware; - } - if (!client_buffers.get_buffer_req(buf_size)) { - DEBUG_PRINT_ERROR("\n update buffer requirements"); - return OMX_ErrorHardware; - } - portDefn->nBufferSize = buf_size; - portDefn->eDir = OMX_DirOutput; - portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; - portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; - portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - portDefn->bEnabled = m_out_bEnabled; - portDefn->bPopulated = m_out_bPopulated; - if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { - DEBUG_PRINT_ERROR("\n Error in getting color format"); - return OMX_ErrorHardware; - } - } - else - { - portDefn->eDir = OMX_DirMax; - DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; - portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; - portDefn->format.video.nStride = drv_ctx.video_resolution.stride; - portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; - DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld" - " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight, - portDefn->format.video.nStride, - portDefn->format.video.nSliceHeight); - return eRet; - -} - -OMX_ERRORTYPE omx_vdec::allocate_output_headers() -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr = NULL; - unsigned i= 0; - - if(!m_out_mem_ptr) { - DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation"); - int nBufHdrSize = 0; - int nPlatformEntrySize = 0; - int nPlatformListSize = 0; - int nPMEMInfoSize = 0; - OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; - - DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n", - drv_ctx.op_buf.actualcount); - nBufHdrSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_BUFFERHEADERTYPE); - - nPMEMInfoSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); - nPlatformListSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); - nPlatformEntrySize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); - - DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, - sizeof(OMX_BUFFERHEADERTYPE), - nPMEMInfoSize, - nPlatformListSize); - DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize, - m_out_bm_count); - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - // Alloc mem for platform specific info - char *pPtr=NULL; - pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + - nPMEMInfoSize,1); - drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ - calloc (sizeof(struct vdec_bufferpayload), - drv_ctx.op_buf.actualcount); - drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ - calloc (sizeof (struct vdec_output_frameinfo), - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ - calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); -#endif - - if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer - && drv_ctx.ptr_respbuffer) - { - bufHdr = m_out_mem_ptr; - m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); - m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) - (((char *) m_platform_list) + nPlatformListSize); - m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - (((char *) m_platform_entry) + nPlatformEntrySize); - pPlatformList = m_platform_list; - pPlatformEntry = m_platform_entry; - pPMEMInfo = m_pmem_info; - - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); - - // Settting the entire storage nicely - DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, - m_out_mem_ptr,pPlatformEntry); - DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); - for(i=0; i < drv_ctx.op_buf.actualcount ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = 0; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = NULL; - bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pPlatformEntry->entry = pPMEMInfo; - // Initialize the Platform List - pPlatformList->nEntries = 1; - pPlatformList->entryList = pPlatformEntry; - // Keep pBuffer NULL till vdec is opened - bufHdr->pBuffer = NULL; - pPMEMInfo->offset = 0; - pPMEMInfo->pmem_fd = 0; - bufHdr->pPlatformPrivate = pPlatformList; - drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; -#endif - /*Create a mapping between buffers*/ - bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; - drv_ctx.ptr_respbuffer[i].client_data = (void *) \ - &drv_ctx.ptr_outputbuffer[i]; - // Move the buffer and buffer header pointers - bufHdr++; - pPMEMInfo++; - pPlatformEntry++; - pPlatformList++; - } - } - else - { - DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ - m_out_mem_ptr, pPtr); - if(m_out_mem_ptr) - { - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(pPtr) - { - free(pPtr); - pPtr = NULL; - } - if(drv_ctx.ptr_outputbuffer) - { - free(drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } - if(drv_ctx.ptr_respbuffer) - { - free(drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif - eRet = OMX_ErrorInsufficientResources; - } - } else { - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - -void omx_vdec::complete_pending_buffer_done_cbs() -{ - unsigned p1; - unsigned p2; - unsigned ident; - omx_cmd_queue tmp_q, pending_bd_q; - pthread_mutex_lock(&m_lock); - // pop all pending GENERATE FDB from ftb queue - while (m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_FBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to ftb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_ftb_q.insert_entry(p1,p2,ident); - } - // pop all pending GENERATE EDB from etb queue - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_EBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to etb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_etb_q.insert_entry(p1,p2,ident); - } - pthread_mutex_unlock(&m_lock); - // process all pending buffer dones - while(pending_bd_q.m_size) - { - pending_bd_q.pop_entry(&p1,&p2,&ident); - switch(ident) - { - case OMX_COMPONENT_GENERATE_EBD: - if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); - omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FBD: - if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); - omx_report_error (); - } - break; - } - } -} - -void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) -{ - OMX_U32 new_frame_interval = 0; - if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts - && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000)) - { - new_frame_interval = (act_timestamp > prev_ts)? - act_timestamp - prev_ts : - prev_ts - act_timestamp; - if (new_frame_interval < frm_int || frm_int == 0) - { - frm_int = new_frame_interval; - if(frm_int) - { - drv_ctx.frame_rate.fps_numerator = 1e6; - drv_ctx.frame_rate.fps_denominator = frm_int; - DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)", - frm_int, drv_ctx.frame_rate.fps_numerator / - (float)drv_ctx.frame_rate.fps_denominator); - } - } - } - prev_ts = act_timestamp; -} - -void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) -{ - if (rst_prev_ts && VALID_TS(act_timestamp)) - { - prev_ts = act_timestamp; - rst_prev_ts = false; - } - else if (VALID_TS(prev_ts)) - { - bool codec_cond = (drv_ctx.timestamp_adjust)? - (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? - (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): - (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); - if(frm_int > 0 && codec_cond) - { - DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); - act_timestamp = prev_ts + frm_int; - DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); - prev_ts = act_timestamp; - } - else - set_frame_rate(act_timestamp); - } - else if (frm_int > 0) // In this case the frame rate was set along - { // with the port definition, start ts with 0 - act_timestamp = prev_ts = 0; // and correct if a valid ts is received. - rst_prev_ts = true; - } -} - -void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) -{ - OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; - OMX_U32 num_conceal_MB = 0; - OMX_U32 frame_rate = 0; - int consumed_len = 0; - OMX_U32 num_MB_in_frame; - OMX_U32 recovery_sei_flags = 1; - int buf_index = p_buf_hdr - m_out_mem_ptr; - struct msm_vidc_panscan_window_payload *panscan_payload = NULL; - OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) + - p_buf_hdr->nOffset; - if (!drv_ctx.extradata_info.uaddr) { - return; - } - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); - char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) - p_extra = NULL; - OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; - if (data) { - while((consumed_len < drv_ctx.extradata_info.buffer_size) - && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) { - if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) { - DEBUG_PRINT_LOW("Invalid extra data size"); - break; - } - switch((unsigned long)data->eType) { - case EXTRADATA_INTERLACE_VIDEO: - struct msm_vidc_interlace_payload *payload; - payload = (struct msm_vidc_interlace_payload *)data->data; - if (payload->format != INTERLACE_FRAME_PROGRESSIVE) { - int enable = 1; - OMX_U32 mbaff = 0; - mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; - if ((payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; - else - drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; - if(m_enable_android_native_buffers) - setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, - PP_PARAM_INTERLACED, (void*)&enable); - } - if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) { - append_interlace_extradata(p_extra, payload->format); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - break; - case EXTRADATA_FRAME_RATE: - struct msm_vidc_framerate_payload *frame_rate_payload; - frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data; - frame_rate = frame_rate_payload->frame_rate; - break; - case EXTRADATA_TIMESTAMP: - struct msm_vidc_ts_payload *time_stamp_payload; - time_stamp_payload = (struct msm_vidc_ts_payload *)data->data; - p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo; - p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); - break; - case EXTRADATA_NUM_CONCEALED_MB: - struct msm_vidc_concealmb_payload *conceal_mb_payload; - conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data; - num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * - (drv_ctx.video_resolution.frame_height + 15)) >> 8; - num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); - break; - case EXTRADATA_ASPECT_RATIO: - struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; - aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)data->data; - ((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; - ((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; - break; - case EXTRADATA_RECOVERY_POINT_SEI: - struct msm_vidc_recoverysei_payload *recovery_sei_payload; - recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data; - recovery_sei_flags = recovery_sei_payload->flags; - if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; - DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received\n"); - } - break; - case EXTRADATA_PANSCAN_WINDOW: - panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data; - break; - default: - goto unrecognized_extradata; - } - consumed_len += data->nSize; - data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); - } - if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - append_frame_info_extradata(p_extra, - num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, - panscan_payload,&((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);} - } -unrecognized_extradata: - if(!secure_mode && client_extradata) - append_terminator_extradata(p_extra); - return; -} - -OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, - bool is_internal, bool enable) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - struct v4l2_control control; - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); - return OMX_ErrorIncorrectStateOperation; - } - DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n", - client_extradata, requested_extradata, enable, is_internal); - - if (!is_internal) { - if (enable) - client_extradata |= requested_extradata; - else - client_extradata = client_extradata & ~requested_extradata; - } - - if (enable) { - if (requested_extradata & OMX_INTERLACE_EXTRADATA) { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set interlaced extradata." - " Quality of interlaced clips might be impacted.\n"); - } - } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) - { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set framerate extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); - } - } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) - { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n"); - } - } - } - ret = get_buffer_req(&drv_ctx.op_buf); - return ret; -} - -OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; - OMX_U8 *data_ptr = extra->data, data = 0; - while (byte_count < extra->nDataSize) - { - data = *data_ptr; - while (data) - { - num_MB += (data&0x01); - data >>= 1; - } - data_ptr++; - byte_count++; - } - num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * - (drv_ctx.video_resolution.frame_height + 15)) >> 8; - return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); -} - -void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - if (!m_debug_extradata) - return; - - DEBUG_PRINT_HIGH( - "============== Extra Data ==============\n" - " Size: %lu \n" - " Version: %lu \n" - " PortIndex: %lu \n" - " Type: %x \n" - " DataSize: %lu \n", - extra->nSize, extra->nVersion.nVersion, - extra->nPortIndex, extra->eType, extra->nDataSize); - - if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) - { - OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; - DEBUG_PRINT_HIGH( - "------ Interlace Format ------\n" - " Size: %lu \n" - " Version: %lu \n" - " PortIndex: %lu \n" - " Is Interlace Format: %d \n" - " Interlace Formats: %lu \n" - "=========== End of Interlace ===========\n", - intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, - intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); - } - else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) - { - OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; - - DEBUG_PRINT_HIGH( - "-------- Frame Format --------\n" - " Picture Type: %d \n" - " Interlace Type: %d \n" - " Pan Scan Total Frame Num: %lu \n" - " Concealed Macro Blocks: %lu \n" - " frame rate: %lu \n" - " Aspect Ratio X: %lu \n" - " Aspect Ratio Y: %lu \n", - fminfo->ePicType, - fminfo->interlaceType, - fminfo->panScan.numWindows, - fminfo->nConcealedMacroblocks, - fminfo->nFrameRate, - fminfo->aspectRatio.aspectRatioX, - fminfo->aspectRatio.aspectRatioY); - - for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) - { - DEBUG_PRINT_HIGH( - "------------------------------\n" - " Pan Scan Frame Num: %lu \n" - " Rectangle x: %ld \n" - " Rectangle y: %ld \n" - " Rectangle dx: %ld \n" - " Rectangle dy: %ld \n", - i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, - fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); - } - - DEBUG_PRINT_HIGH("========= End of Frame Format =========="); - } - else if (extra->eType == OMX_ExtraDataNone) - { - DEBUG_PRINT_HIGH("========== End of Terminator ==========="); - } - else - { - DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); - } -} - -void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 interlaced_format_type) -{ - OMX_STREAMINTERLACEFORMAT *interlace_format; - OMX_U32 mbaff = 0; - if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { - return; - } - extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; - extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); - interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; - interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); - interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; - interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; - if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) - { - interlace_format->bInterlaceFormat = OMX_FALSE; - interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; - } - else - { - interlace_format->bInterlaceFormat = OMX_TRUE; - interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; - drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; - } - print_debug_extradata(extra); -} - -void omx_vdec::fill_aspect_ratio_info( - struct vdec_aspectratioinfo *aspect_ratio_info, - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) -{ - m_extradata = frame_info; - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; - DEBUG_PRINT_LOW("aspectRatioX %d aspectRatioX %d", m_extradata->aspectRatio.aspectRatioX, - m_extradata->aspectRatio.aspectRatioY); -} - -void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate, - struct msm_vidc_panscan_window_payload *panscan_payload, - struct vdec_aspectratioinfo *aspect_ratio_info) -{ - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; - struct msm_vidc_panscan_window *panscan_window; - if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { - return; - } - extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; - extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); - frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; - switch (picture_type) - { - case PICTURE_TYPE_I: - frame_info->ePicType = OMX_VIDEO_PictureTypeI; - break; - case PICTURE_TYPE_P: - frame_info->ePicType = OMX_VIDEO_PictureTypeP; - break; - case PICTURE_TYPE_B: - frame_info->ePicType = OMX_VIDEO_PictureTypeB; - break; - default: - frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; - } - if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) - frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; - else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) - frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; - else - frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; - memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); - frame_info->nConcealedMacroblocks = num_conceal_mb; - frame_info->nFrameRate = frame_rate; - frame_info->panScan.numWindows = 0; - if(panscan_payload) { - frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; - panscan_window = &panscan_payload->wnd[0]; - for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) - { - frame_info->panScan.window[i].x = panscan_window->panscan_window_width; - frame_info->panScan.window[i].y = panscan_window->panscan_window_height; - frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; - frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; - panscan_window++; - } - } - fill_aspect_ratio_info(aspect_ratio_info, frame_info); - print_debug_extradata(extra); -} - -void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; - extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; - extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; - *portDefn = m_port_def; - DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u" - "sliceheight = %u \n",portDefn->format.video.nFrameHeight, - portDefn->format.video.nFrameWidth, - portDefn->format.video.nStride, - portDefn->format.video.nSliceHeight); -} - -void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - if (!client_extradata) { - return; - } - extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->eType = OMX_ExtraDataNone; - extra->nDataSize = 0; - extra->data[0] = 0; - - print_debug_extradata(extra); -} - -OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (index >= drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found"); - return OMX_ErrorInsufficientResources; - } - if (m_desc_buffer_ptr == NULL) - { - m_desc_buffer_ptr = (desc_buffer_hdr*) \ - calloc( (sizeof(desc_buffer_hdr)), - drv_ctx.ip_buf.actualcount); - if (m_desc_buffer_ptr == NULL) - { - DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - } - - m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); - if (m_desc_buffer_ptr[index].buf_addr == NULL) - { - DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed "); - return OMX_ErrorInsufficientResources; - } - - return eRet; -} - -void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) -{ - DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries); - if (m_demux_entries < 8192) - { - m_demux_offsets[m_demux_entries++] = address_offset; - } - return; -} - -void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) -{ - OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; - OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; - OMX_U32 index = 0; - - m_demux_entries = 0; - - while (index < bytes_to_parse) - { - if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && - (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || - ((buf[index] == 0x00) && (buf[index+1] == 0x00) && - (buf[index+2] == 0x01)) ) - { - //Found start code, insert address offset - insert_demux_addr_offset(index); - if (buf[index+2] == 0x01) // 3 byte start code - index += 3; - else //4 byte start code - index += 4; - } - else - index++; - } - DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries); - return; -} - -OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) -{ - //fix this, handle 3 byte start code, vc1 terminator entry - OMX_U8 *p_demux_data = NULL; - OMX_U32 desc_data = 0; - OMX_U32 start_addr = 0; - OMX_U32 nal_size = 0; - OMX_U32 suffix_byte = 0; - OMX_U32 demux_index = 0; - OMX_U32 buffer_index = 0; - - if (m_desc_buffer_ptr == NULL) - { - DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); - return OMX_ErrorBadParameter; - } - - buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - if (buffer_index > drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index); - return OMX_ErrorBadParameter; - } - - p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; - - if ( ((OMX_U8*)p_demux_data == NULL) || - ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) - { - DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); - return OMX_ErrorBadParameter; - } - else - { - for (; demux_index < m_demux_entries; demux_index++) - { - desc_data = 0; - start_addr = m_demux_offsets[demux_index]; - if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) - { - suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; - } - else - { - suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; - } - if (demux_index < (m_demux_entries - 1)) - { - nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; - } - else - { - nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; - } - DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)", - start_addr, - suffix_byte, - nal_size, - demux_index); - desc_data = (start_addr >> 3) << 1; - desc_data |= (start_addr & 7) << 21; - desc_data |= suffix_byte << 24; - - memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); - memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); - memset(p_demux_data + 8, 0, sizeof(OMX_U32)); - memset(p_demux_data + 12, 0, sizeof(OMX_U32)); - - p_demux_data += 16; - } - if (codec_type_parse == CODEC_TYPE_VC1) - { - DEBUG_PRINT_LOW("VC1 terminator entry"); - desc_data = 0; - desc_data = 0x82 << 24; - memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); - memset(p_demux_data + 4, 0, sizeof(OMX_U32)); - memset(p_demux_data + 8, 0, sizeof(OMX_U32)); - memset(p_demux_data + 12, 0, sizeof(OMX_U32)); - p_demux_data += 16; - m_demux_entries++; - } - //Add zero word to indicate end of descriptors - memset(p_demux_data, 0, sizeof(OMX_U32)); - - m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); - DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size); - } - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - DEBUG_PRINT_LOW("Demux table complete!"); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::createDivxDrmContext() -{ - OMX_ERRORTYPE err = OMX_ErrorNone; - iDivXDrmDecrypt = DivXDrmDecrypt::Create(); - if (iDivXDrmDecrypt) { - OMX_ERRORTYPE err = iDivXDrmDecrypt->Init(); - if(err!=OMX_ErrorNone) { - DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err); - delete iDivXDrmDecrypt; - iDivXDrmDecrypt = NULL; - } - } - else { - DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM"); - err = OMX_ErrorUndefined; - } - return err; -} - -omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() -{ - enabled = false; - omx = NULL; - init_members(); - ColorFormat = OMX_COLOR_FormatMax; -} - -void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) -{ - omx = reinterpret_cast(client); -} - -void omx_vdec::allocate_color_convert_buf::init_members() { - allocated_count = 0; - buffer_size_req = 0; - buffer_alignment_req = 0; - memset(m_platform_list_client,0,sizeof(m_platform_list_client)); - memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); - memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); - memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); -#ifdef USE_ION - memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); -#endif - for (int i = 0; i < MAX_COUNT;i++) - pmem_fd[i] = -1; -} - -omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() { - c2d.destroy(); -} - -bool omx_vdec::allocate_color_convert_buf::update_buffer_req() -{ - bool status = true; - unsigned int src_size = 0, destination_size = 0; - OMX_COLOR_FORMATTYPE drv_color_format; - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid client in color convert"); - return false; - } - if (!enabled){ - DEBUG_PRINT_ERROR("\n No color conversion required"); - return status; - } - pthread_mutex_lock(&omx->c_lock); - if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && - ColorFormat != OMX_COLOR_FormatYUV420Planar) { - DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion"); - status = false; - goto fail_update_buf_req; - } - c2d.close(); - status = c2d.open(omx->drv_ctx.video_resolution.frame_height, - omx->drv_ctx.video_resolution.frame_width, - NV12_128m,YCbCr420P); - if (status) { - status = c2d.get_buffer_size(C2D_INPUT,src_size); - if (status) - status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); - } - if (status) { - if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || - !destination_size) { - DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d" - "driver size %d destination size %d", - src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); - status = false; - c2d.close(); - buffer_size_req = 0; - } else { - buffer_size_req = destination_size; - if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) - buffer_size_req = omx->drv_ctx.op_buf.buffer_size; - if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) - buffer_alignment_req = omx->drv_ctx.op_buf.alignment; - } - } -fail_update_buf_req: - pthread_mutex_unlock(&omx->c_lock); - return status; -} - -bool omx_vdec::allocate_color_convert_buf::set_color_format( - OMX_COLOR_FORMATTYPE dest_color_format) -{ - bool status = true; - OMX_COLOR_FORMATTYPE drv_color_format; - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid client in color convert"); - return false; - } - pthread_mutex_lock(&omx->c_lock); - if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) - drv_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - else { - DEBUG_PRINT_ERROR("\n Incorrect color format"); - status = false; - } - if (status && (drv_color_format != dest_color_format)) { - DEBUG_PRINT_LOW("Enabling C2D\n"); - if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { - DEBUG_PRINT_ERROR("\n Unsupported color format for c2d"); - status = false; - } else { - ColorFormat = OMX_COLOR_FormatYUV420Planar; - if (enabled) - c2d.destroy(); - enabled = false; - if (!c2d.init()) { - DEBUG_PRINT_ERROR("\n open failed for c2d"); - status = false; - } else - enabled = true; - } - } else { - if (enabled) - c2d.destroy(); - enabled = false; - } - pthread_mutex_unlock(&omx->c_lock); - return status; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return omx->m_out_mem_ptr; - return m_out_mem_ptr_client; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr - (OMX_BUFFERHEADERTYPE *bufadd) -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return bufadd; - - unsigned index = 0; - index = bufadd - omx->m_out_mem_ptr; - if (index < omx->drv_ctx.op_buf.actualcount) { - m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); - m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; - bool status; - if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { - pthread_mutex_lock(&omx->c_lock); - status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, - omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer,pmem_fd[index], - pmem_baseaddress[index], pmem_baseaddress[index]); - pthread_mutex_unlock(&omx->c_lock); - m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; - if (!status){ - DEBUG_PRINT_ERROR("\n Failed color conversion %d", status); - m_out_mem_ptr_client[index].nFilledLen = 0; - return &m_out_mem_ptr_client[index]; - } - } else - m_out_mem_ptr_client[index].nFilledLen = 0; - return &m_out_mem_ptr_client[index]; - } - DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr"); - return NULL; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr - (OMX_BUFFERHEADERTYPE *bufadd) -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return bufadd; - unsigned index = 0; - index = bufadd - m_out_mem_ptr_client; - if (index < omx->drv_ctx.op_buf.actualcount) { - return &omx->m_out_mem_ptr[index]; - } - DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr"); - return NULL; -} -bool omx_vdec::allocate_color_convert_buf::get_buffer_req - (unsigned int &buffer_size) -{ - bool status = true; - pthread_mutex_lock(&omx->c_lock); - if (!enabled) - buffer_size = omx->drv_ctx.op_buf.buffer_size; - else { - if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { - DEBUG_PRINT_ERROR("\n Get buffer size failed"); - status = false; - goto fail_get_buffer_size; - } - } - if (buffer_size < omx->drv_ctx.op_buf.buffer_size) - buffer_size = omx->drv_ctx.op_buf.buffer_size; - if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) - buffer_alignment_req = omx->drv_ctx.op_buf.alignment; -fail_get_buffer_size: - pthread_mutex_unlock(&omx->c_lock); - return status; -} -OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( - OMX_BUFFERHEADERTYPE *bufhdr) { - unsigned int index = 0; - - if (!enabled) - return omx->free_output_buffer(bufhdr); - if (enabled && omx->is_component_secure()) - return OMX_ErrorNone; - if (!allocated_count || !bufhdr) { - DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr); - return OMX_ErrorBadParameter; - } - index = bufhdr - m_out_mem_ptr_client; - if (index >= omx->drv_ctx.op_buf.actualcount){ - DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer"); - return OMX_ErrorBadParameter; - } - if (pmem_fd[index] > 0) { - munmap(pmem_baseaddress[index], buffer_size_req); - close(pmem_fd[index]); - } - pmem_fd[index] = -1; -#ifdef USE_ION - omx->free_ion_memory(&op_buf_ion_info[index]); -#endif - m_heap_ptr[index].video_heap_ptr = NULL; - if (allocated_count > 0) - allocated_count--; - else - allocated_count = 0; - if (!allocated_count) { - pthread_mutex_lock(&omx->c_lock); - c2d.close(); - init_members(); - pthread_mutex_unlock(&omx->c_lock); - } - return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); -} - -OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (!enabled){ - eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); - return eRet; - } - if (enabled && omx->is_component_secure()) { - DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d", - omx->is_component_secure()); - return OMX_ErrorUnsupportedSetting; - } - if (!bufferHdr || bytes > buffer_size_req) { - DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr); - DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu", - buffer_size_req,bytes); - return OMX_ErrorBadParameter; - } - if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert"); - return OMX_ErrorInsufficientResources; - } - OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; - eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, - port,appData,omx->drv_ctx.op_buf.buffer_size); - if (eRet != OMX_ErrorNone || !temp_bufferHdr){ - DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert"); - return eRet; - } - if ((temp_bufferHdr - omx->m_out_mem_ptr) >= - omx->drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("\n Invalid header index %d", - (temp_bufferHdr - omx->m_out_mem_ptr)); - return OMX_ErrorUndefined; - } - unsigned int i = allocated_count; -#ifdef USE_ION - op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( - buffer_size_req,buffer_alignment_req, - &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, - 0); - pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; - if (op_buf_ion_info[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert"); - return OMX_ErrorInsufficientResources; - } - pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, - PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); - - if (pmem_baseaddress[i] == MAP_FAILED) { - DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req); - close(pmem_fd[i]); - omx->free_ion_memory(&op_buf_ion_info[i]); - return OMX_ErrorInsufficientResources; - } - m_heap_ptr[i].video_heap_ptr = new VideoHeap ( - op_buf_ion_info[i].ion_device_fd,buffer_size_req, - pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); -#endif - m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); - m_pmem_info_client[i].offset = 0; - m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; - m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - m_platform_list_client[i].nEntries = 1; - m_platform_list_client[i].entryList = &m_platform_entry_client[i]; - m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; - m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; - m_out_mem_ptr_client[i].nFilledLen = 0; - m_out_mem_ptr_client[i].nFlags = 0; - m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); - m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; - m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; - m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; - m_out_mem_ptr_client[i].pAppPrivate = appData; - *bufferHdr = &m_out_mem_ptr_client[i]; - DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr); - allocated_count++; - return eRet; -} - -bool omx_vdec::is_component_secure() -{ - return secure_mode; -} - -bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) -{ - bool status = true; - if (!enabled) { - if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) - dest_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - else - status = false; - } else { - if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { - status = false; - } else - dest_color_format = OMX_COLOR_FormatYUV420Planar; - } - return status; -} diff --git a/mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp deleted file mode 100644 index 44810df4..00000000 --- a/mm-video/vidc/vdec/src/omx_vdec_msm8974.cpp +++ /dev/null @@ -1,9668 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -/*============================================================================ - O p e n M A X w r a p p e r s - O p e n M A X C o r e - -*//** @file omx_vdec.cpp - This module contains the implementation of the OpenMAX core & component. - -*//*========================================================================*/ - -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include "omx_vdec.h" -#include -#include -#include -#include - -#ifndef _ANDROID_ -#include -#include -#endif //_ANDROID_ - -#ifdef _ANDROID_ -#include -#undef USE_EGL_IMAGE_GPU -#endif - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -#include -#endif - -#if defined (_ANDROID_ICS_) -#include -#include -#endif - -#ifdef _ANDROID_ -#include "DivXDrmDecrypt.h" -#endif //_ANDROID_ - -#ifdef USE_EGL_IMAGE_GPU -#include -#include -#define EGL_BUFFER_HANDLE_QCOM 0x4F00 -#define EGL_BUFFER_OFFSET_QCOM 0x4F01 -#endif -#ifdef INPUT_BUFFER_LOG -#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0" -#define INPUT_BUFFER_FILE_NAME_LEN 30 -FILE *inputBufferFile1; -char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0"; -#endif -#ifdef OUTPUT_BUFFER_LOG -FILE *outputBufferFile1; -char outputfilename [] = "/data/output.yuv"; - -#endif -#ifdef OUTPUT_EXTRADATA_LOG -FILE *outputExtradataFile; -char ouputextradatafilename [] = "/data/extradata"; -#endif - -#define DEFAULT_FPS 30 -#define MAX_INPUT_ERROR DEFAULT_FPS -#define MAX_SUPPORTED_FPS 120 - -#define VC1_SP_MP_START_CODE 0xC5000000 -#define VC1_SP_MP_START_CODE_MASK 0xFF000000 -#define VC1_AP_SEQ_START_CODE 0x0F010000 -#define VC1_STRUCT_C_PROFILE_MASK 0xF0 -#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 -#define VC1_SIMPLE_PROFILE 0 -#define VC1_MAIN_PROFILE 1 -#define VC1_ADVANCE_PROFILE 3 -#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 -#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 -#define VC1_STRUCT_C_LEN 4 -#define VC1_STRUCT_C_POS 8 -#define VC1_STRUCT_A_POS 12 -#define VC1_STRUCT_B_POS 24 -#define VC1_SEQ_LAYER_SIZE 36 -#define POLL_TIMEOUT 0x7fffffff - -#define MEM_DEVICE "/dev/ion" -#define MEM_HEAP_ID ION_CP_MM_HEAP_ID - -#ifdef _ANDROID_ - extern "C"{ - #include - } -#endif//_ANDROID_ - -#define SZ_4K 0x1000 -#define SZ_1M 0x100000 - -#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } -#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } -#define EXTRADATA_IDX(__num_planes) (__num_planes - 1) - -#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA) -void* async_message_thread (void *input) -{ - OMX_BUFFERHEADERTYPE *buffer; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - struct pollfd pfd; - struct v4l2_buffer v4l2_buf; - memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); - struct v4l2_event dqevent; - omx_vdec *omx = reinterpret_cast(input); - pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; - pfd.fd = omx->drv_ctx.video_driver_fd; - int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0; - DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n"); - prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0); - while (1) - { - rc = poll(&pfd, 1, POLL_TIMEOUT); - if (!rc) { - DEBUG_PRINT_ERROR("Poll timedout\n"); - break; - } else if (rc < 0) { - DEBUG_PRINT_ERROR("Error while polling: %d\n", rc); - break; - } - if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { - struct vdec_msginfo vdec_msg; - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - v4l2_buf.memory = V4L2_MEMORY_USERPTR; - v4l2_buf.length = omx->drv_ctx.num_planes; - v4l2_buf.m.planes = plane; - while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { - vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf; - vdec_msg.msgdata.output_frame.len=plane[0].bytesused; - vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr; - vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) + - (uint64_t)v4l2_buf.timestamp.tv_usec; - if (vdec_msg.msgdata.output_frame.len) { - vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2]; - vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3]; - vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4]; - vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5]; - } - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } - } - if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { - struct vdec_msginfo vdec_msg; - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - v4l2_buf.memory = V4L2_MEMORY_USERPTR; - v4l2_buf.length = 1; - v4l2_buf.m.planes = plane; - while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { - vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf; - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } - } - if (pfd.revents & POLLPRI){ - rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); - if(dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) { - struct vdec_msginfo vdec_msg; - vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { - struct vdec_msginfo vdec_msg; - vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { - DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n"); - break; - } else if(dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) { - struct vdec_msginfo vdec_msg; - vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR; - vdec_msg.status_code=VDEC_S_SUCCESS; - DEBUG_PRINT_HIGH("\n SYS Error Recieved \n"); - if (omx->async_message_process(input,&vdec_msg) < 0) { - DEBUG_PRINT_HIGH("\n async_message_thread Exited \n"); - break; - } - } else { - DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n"); - continue; - } - } - } - DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n"); - return NULL; -} - -void* message_thread(void *input) -{ - omx_vdec* omx = reinterpret_cast(input); - unsigned char id; - int n; - - DEBUG_PRINT_HIGH("omx_vdec: message thread start\n"); - prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0); - while (1) - { - - n = read(omx->m_pipe_in, &id, 1); - - if(0 == n) - { - break; - } - - if (1 == n) - { - omx->process_event_cb(omx, id); - } - if ((n < 0) && (errno != EINTR)) - { - DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno); - break; - } - } - DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n"); - return 0; -} - -void post_message(omx_vdec *omx, unsigned char id) -{ - int ret_value; - DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out); - ret_value = write(omx->m_pipe_out, &id, 1); - DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value); -} - -// omx_cmd_queue destructor -omx_vdec::omx_cmd_queue::~omx_cmd_queue() -{ - // Nothing to do -} - -// omx cmd queue constructor -omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) -{ - memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); -} - -// omx cmd queue insert -bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) -{ - bool ret = true; - if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_q[m_write].id = id; - m_q[m_write].param1 = p1; - m_q[m_write].param2 = p2; - m_write++; - m_size ++; - if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_write = 0; - } - } - else - { - ret = false; - DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__); - } - return ret; -} - -// omx cmd queue pop -bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) -{ - bool ret = true; - if (m_size > 0) - { - *id = m_q[m_read].id; - *p1 = m_q[m_read].param1; - *p2 = m_q[m_read].param2; - // Move the read pointer ahead - ++m_read; - --m_size; - if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_read = 0; - } - } - else - { - ret = false; - } - return ret; -} - -// Retrieve the first mesg type in the queue -unsigned omx_vdec::omx_cmd_queue::get_q_msg_type() -{ - return m_q[m_read].id; -} - -#ifdef _ANDROID_ -omx_vdec::ts_arr_list::ts_arr_list() -{ - //initialize timestamps array - memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) ); -} -omx_vdec::ts_arr_list::~ts_arr_list() -{ - //free m_ts_arr_list? -} - -bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts) -{ - bool ret = true; - bool duplicate_ts = false; - int idx = 0; - - //insert at the first available empty location - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - if (!m_ts_arr_list[idx].valid) - { - //found invalid or empty entry, save timestamp - m_ts_arr_list[idx].valid = true; - m_ts_arr_list[idx].timestamp = ts; - DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)", - ts, idx); - break; - } - } - - if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) - { - DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert"); - ret = false; - } - return ret; -} - -bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts) -{ - bool ret = true; - int min_idx = -1; - OMX_TICKS min_ts = 0; - int idx = 0; - - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - - if (m_ts_arr_list[idx].valid) - { - //found valid entry, save index - if (min_idx < 0) - { - //first valid entry - min_ts = m_ts_arr_list[idx].timestamp; - min_idx = idx; - } - else if (m_ts_arr_list[idx].timestamp < min_ts) - { - min_ts = m_ts_arr_list[idx].timestamp; - min_idx = idx; - } - } - - } - - if (min_idx < 0) - { - //no valid entries found - DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop"); - ts = 0; - ret = false; - } - else - { - ts = m_ts_arr_list[min_idx].timestamp; - m_ts_arr_list[min_idx].valid = false; - DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)", - ts, min_idx); - } - - return ret; - -} - - -bool omx_vdec::ts_arr_list::reset_ts_list() -{ - bool ret = true; - int idx = 0; - - DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list"); - for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) - { - m_ts_arr_list[idx].valid = false; - } - return ret; -} -#endif - -// factory function executed by the core to create instances -void *get_omx_component_factory_fn(void) -{ - return (new omx_vdec); -} - -#ifdef _ANDROID_ -#ifdef USE_ION -VideoHeap::VideoHeap(int devicefd, size_t size, void* base, - struct ion_handle *handle, int ionMapfd) -{ -// ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd); -} -#else -VideoHeap::VideoHeap(int fd, size_t size, void* base) -{ - // dup file descriptor, map once, use pmem - init(dup(fd), base, size, 0 , MEM_DEVICE); -} -#endif -#endif // _ANDROID_ -/* ====================================================================== -FUNCTION - omx_vdec::omx_vdec - -DESCRIPTION - Constructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_vdec::omx_vdec(): m_error_propogated(false), - m_state(OMX_StateInvalid), - m_app_data(NULL), - m_inp_mem_ptr(NULL), - m_out_mem_ptr(NULL), - m_inp_err_count(0), - input_flush_progress (false), - output_flush_progress (false), - input_use_buffer (false), - output_use_buffer (false), - ouput_egl_buffers(false), - m_use_output_pmem(OMX_FALSE), - m_out_mem_region_smi(OMX_FALSE), - m_out_pvt_entry_pmem(OMX_FALSE), - pending_input_buffers(0), - pending_output_buffers(0), - m_out_bm_count(0), - m_inp_bm_count(0), - m_inp_bPopulated(OMX_FALSE), - m_out_bPopulated(OMX_FALSE), - m_flags(0), -#ifdef _ANDROID_ - m_heap_ptr(NULL), -#endif - m_inp_bEnabled(OMX_TRUE), - m_out_bEnabled(OMX_TRUE), - m_in_alloc_cnt(0), - m_platform_list(NULL), - m_platform_entry(NULL), - m_pmem_info(NULL), - arbitrary_bytes (true), - psource_frame (NULL), - pdest_frame (NULL), - m_inp_heap_ptr (NULL), - m_phdr_pmem_ptr(NULL), - m_heap_inp_bm_count (0), - codec_type_parse ((codec_type)0), - first_frame_meta (true), - frame_count (0), - nal_count (0), - nal_length(0), - look_ahead_nal (false), - first_frame(0), - first_buffer(NULL), - first_frame_size (0), - m_device_file_ptr(NULL), - m_vc1_profile((vc1_profile_type)0), - h264_last_au_ts(LLONG_MAX), - h264_last_au_flags(0), - prev_ts(LLONG_MAX), - rst_prev_ts(true), - frm_int(0), - m_disp_hor_size(0), - m_disp_vert_size(0), - in_reconfig(false), - m_display_id(NULL), - h264_parser(NULL), - client_extradata(0), -#ifdef _ANDROID_ - m_enable_android_native_buffers(OMX_FALSE), - m_use_android_native_buffers(OMX_FALSE), - iDivXDrmDecrypt(NULL), -#endif - m_desc_buffer_ptr(NULL), - secure_mode(false), - client_set_fps(false) -{ - /* Assumption is that , to begin with , we have all the frames with decoder */ - DEBUG_PRINT_HIGH("In OMX vdec Constructor"); -#ifdef _ANDROID_ - char property_value[PROPERTY_VALUE_MAX] = {0}; - property_get("vidc.dec.debug.perf", property_value, "0"); - perf_flag = atoi(property_value); - if (perf_flag) - { - DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag); - dec_time.start(); - proc_frms = latency = 0; - } - prev_n_filled_len = 0; - property_value[0] = '\0'; - property_get("vidc.dec.debug.ts", property_value, "0"); - m_debug_timestamp = atoi(property_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp); - if (m_debug_timestamp) - { - time_stamp_dts.set_timestamp_reorder_mode(true); - time_stamp_dts.enable_debug_print(true); - } - - property_value[0] = '\0'; - property_get("vidc.dec.debug.concealedmb", property_value, "0"); - m_debug_concealedmb = atoi(property_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb); - -#endif - memset(&m_cmp,0,sizeof(m_cmp)); - memset(&m_cb,0,sizeof(m_cb)); - memset (&drv_ctx,0,sizeof(drv_ctx)); - memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE)); - memset (m_hwdevice_name,0,sizeof(m_hwdevice_name)); - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - msg_thread_id = 0; - async_thread_id = 0; - msg_thread_created = false; - async_thread_created = false; -#ifdef _ANDROID_ICS_ - memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); -#endif - memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); - drv_ctx.timestamp_adjust = false; - drv_ctx.video_driver_fd = -1; - m_vendor_config.pData = NULL; - pthread_mutex_init(&m_lock, NULL); - pthread_mutex_init(&c_lock, NULL); - sem_init(&m_cmd_lock,0,0); - streaming[CAPTURE_PORT] = - streaming[OUTPUT_PORT] = false; -#ifdef _ANDROID_ - char extradata_value[PROPERTY_VALUE_MAX] = {0}; - property_get("vidc.dec.debug.extradata", extradata_value, "0"); - m_debug_extradata = atoi(extradata_value); - DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata); -#endif - m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB; - client_buffers.set_vdec_client(this); -} - -static const int event_type[] = { - V4L2_EVENT_MSM_VIDC_FLUSH_DONE, - V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT, - V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT, - V4L2_EVENT_MSM_VIDC_CLOSE_DONE, - V4L2_EVENT_MSM_VIDC_SYS_ERROR -}; - -static OMX_ERRORTYPE subscribe_to_events(int fd) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_event_subscription sub; - int array_sz = sizeof(event_type)/sizeof(int); - int i,rc; - if (fd < 0) { - printf("Invalid input: %d\n", fd); - return OMX_ErrorBadParameter; - } - - for (i = 0; i < array_sz; ++i) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); - if (rc) { - printf("Failed to subscribe event: 0x%x\n", sub.type); - break; - } - } - if (i < array_sz) { - for (--i; i >=0 ; i--) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); - if (rc) - printf("Failed to unsubscribe event: 0x%x\n", sub.type); - } - eRet = OMX_ErrorNotImplemented; - } - return eRet; -} - - -static OMX_ERRORTYPE unsubscribe_to_events(int fd) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_event_subscription sub; - int array_sz = sizeof(event_type)/sizeof(int); - int i,rc; - if (fd < 0) { - printf("Invalid input: %d\n", fd); - return OMX_ErrorBadParameter; - } - - for (i = 0; i < array_sz; ++i) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); - if (rc) { - printf("Failed to unsubscribe event: 0x%x\n", sub.type); - break; - } - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::~omx_vdec - -DESCRIPTION - Destructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_vdec::~omx_vdec() -{ - m_pmem_info = NULL; - struct v4l2_decoder_cmd dec; - DEBUG_PRINT_HIGH("In OMX vdec Destructor"); - if(m_pipe_in) close(m_pipe_in); - if(m_pipe_out) close(m_pipe_out); - m_pipe_in = -1; - m_pipe_out = -1; - DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit"); - if (msg_thread_created) - pthread_join(msg_thread_id,NULL); - DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit"); - dec.cmd = V4L2_DEC_CMD_STOP; - if (drv_ctx.video_driver_fd >=0 ) { - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) - DEBUG_PRINT_ERROR("\n STOP Command failed\n"); - } - if (async_thread_created) - pthread_join(async_thread_id,NULL); - unsubscribe_to_events(drv_ctx.video_driver_fd); - close(drv_ctx.video_driver_fd); - pthread_mutex_destroy(&m_lock); - pthread_mutex_destroy(&c_lock); - sem_destroy(&m_cmd_lock); - if (perf_flag) - { - DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME"); - dec_time.end(); - } - DEBUG_PRINT_HIGH("Exit OMX vdec Destructor"); -} - -int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type) { - struct v4l2_requestbuffers bufreq; - int rc = 0; - if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = 0; - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); - } - return rc; -} - -/* ====================================================================== -FUNCTION - omx_vdec::OMXCntrlProcessMsgCb - -DESCRIPTION - IL Client callbacks are generated through this routine. The decoder - provides the thread context for this routine. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -void omx_vdec::process_event_cb(void *ctxt, unsigned char id) -{ - signed p1; // Parameter - 1 - signed p2; // Parameter - 2 - unsigned ident; - unsigned qsize=0; // qsize - omx_vdec *pThis = (omx_vdec *) ctxt; - - if(!pThis) - { - DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n", - __func__); - return; - } - - // Protect the shared queue data structure - do - { - /*Read the message id's from the queue*/ - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if(qsize) - { - pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); - } - - if (qsize == 0 && pThis->m_state != OMX_StatePause) - { - qsize = pThis->m_ftb_q.m_size; - if (qsize) - { - pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); - } - } - - if (qsize == 0 && pThis->m_state != OMX_StatePause) - { - qsize = pThis->m_etb_q.m_size; - if (qsize) - { - pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident); - } - } - pthread_mutex_unlock(&pThis->m_lock); - - /*process message if we have one*/ - if(qsize > 0) - { - id = ident; - switch (id) - { - case OMX_COMPONENT_GENERATE_EVENT: - if (pThis->m_cb.EventHandler) - { - switch (p1) - { - case OMX_CommandStateSet: - pThis->m_state = (OMX_STATETYPE) p2; - DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d", - pThis->m_state); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL); - break; - - case OMX_EventError: - if(p2 == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid"); - pThis->m_state = (OMX_STATETYPE) p2; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError, OMX_ErrorInvalidState, p2, NULL); - } - else if (p2 == OMX_ErrorHardware) - { - pThis->omx_report_error(); - } - else - { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError, p2, (OMX_U32)NULL, NULL ); - } - break; - - case OMX_CommandPortDisable: - DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2); - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) - { - BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); - break; - } - if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) - { - OMX_ERRORTYPE eRet = OMX_ErrorNone; - pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX); - if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT)) - DEBUG_PRINT_HIGH("Failed to release output buffers\n"); - OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf); - pThis->in_reconfig = false; - if(eRet != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet); - pThis->omx_report_error(); - break; - } - } - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - case OMX_CommandPortEnable: - DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - default: - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__); - } - break; - case OMX_COMPONENT_GENERATE_ETB_ARBITRARY: - if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure"); - pThis->omx_report_error (); - } - break; - case OMX_COMPONENT_GENERATE_ETB: - if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FTB: - if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_COMMAND: - pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ - (OMX_U32)p2,(OMX_PTR)NULL); - break; - - case OMX_COMPONENT_GENERATE_EBD: - - if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure"); - pThis->omx_report_error (); - } - else - { - if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) - { - pThis->m_inp_err_count++; - pThis->time_stamp_dts.remove_time_stamp( - ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp, - (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - } - else - { - pThis->m_inp_err_count = 0; - } - if ( pThis->empty_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n empty_buffer_done failure"); - pThis->omx_report_error (); - } - if(pThis->m_inp_err_count >= MAX_INPUT_ERROR) - { - DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR); - pThis->omx_report_error (); - } - } - break; - case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: - { - int64_t *timestamp = (int64_t *)p1; - if (p1) - { - pThis->time_stamp_dts.remove_time_stamp(*timestamp, - (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - ?true:false); - free(timestamp); - } - } - break; - case OMX_COMPONENT_GENERATE_FBD: - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure"); - pThis->omx_report_error (); - } - else if ( pThis->fill_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\n fill_buffer_done failure"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: - DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete"); - if (!pThis->input_flush_progress) - { - DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); - } - else - { - pThis->execute_input_flush(); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure"); - pThis->omx_report_error (); - } - else - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_INPUT_FLUSH_PENDING)) - { - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); - DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client"); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - OMX_CORE_INPUT_PORT_INDEX,NULL ); - } - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_IDLE_PENDING)) - { - if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) { - DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n"); - pThis->omx_report_error (); - } else { - pThis->streaming[OUTPUT_PORT] = false; - } - if (!pThis->output_flush_progress) - { - DEBUG_PRINT_LOW("\n Input flush done hence issue stop"); - pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - } - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: - DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete"); - if (!pThis->output_flush_progress) - { - DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver"); - } - else - { - pThis->execute_output_flush(); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed"); - pThis->omx_report_error (); - } - else - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) - { - DEBUG_PRINT_LOW("\n Notify Output Flush done"); - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - OMX_CORE_OUTPUT_PORT_INDEX,NULL ); - } - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) - { - DEBUG_PRINT_LOW("\n Internal flush complete"); - BITMASK_CLEAR (&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); - if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) - { - pThis->post_event(OMX_CommandPortDisable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - BITMASK_CLEAR (&pThis->m_flags, - OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED); - - } - } - - if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) - { - if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) { - DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n"); - pThis->omx_report_error (); - break; - } - pThis->streaming[CAPTURE_PORT] = false; - if (!pThis->input_flush_progress) - { - DEBUG_PRINT_LOW("\n Output flush done hence issue stop"); - pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - } - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_START_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE"); - - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure"); - pThis->omx_report_error (); - } - else - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("\n Move to executing"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting, NULL); - } - else if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_PAUSE_PENDING)) - { - if (/*ioctl (pThis->drv_ctx.video_driver_fd, - VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed"); - pThis->omx_report_error (); - } - } - } - } - else - { - DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); - } - break; - - case OMX_COMPONENT_GENERATE_PAUSE_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed"); - pThis->omx_report_error (); - } - else - { - pThis->complete_pending_buffer_done_cbs(); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity"); - //Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); - pThis->m_state = OMX_StatePause; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StatePause, NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_RESUME_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed"); - pThis->omx_report_error (); - } - else - { - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("\n Moving the decoder to execute state"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting,NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_STOP_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE"); - if (pThis->m_cb.EventHandler) - { - if (p2 != VDEC_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed"); - pThis->omx_report_error (); - } - else - { - pThis->complete_pending_buffer_done_cbs(); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); - pThis->m_state = OMX_StateIdle; - DEBUG_PRINT_LOW("\n Move to Idle State"); - pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateIdle,NULL); - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - break; - - case OMX_COMPONENT_GENERATE_PORT_RECONFIG: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG"); - - if (p2 == OMX_IndexParamPortDefinition) { - pThis->in_reconfig = true; - } - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventPortSettingsChanged, p1, p2, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - - if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) - { - OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1; - OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged; - if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) - format = OMX_InterlaceInterleaveFrameTopFieldFirst; - else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) - format = OMX_InterlaceInterleaveFrameBottomFieldFirst; - else //unsupported interlace format; raise a error - event = OMX_EventError; - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - event, format, 0, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - break; - - case OMX_COMPONENT_GENERATE_EOS_DONE: - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE"); - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag, - OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - pThis->prev_ts = LLONG_MAX; - pThis->rst_prev_ts = true; - break; - - case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR"); - pThis->omx_report_error (); - break; - - case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING: - DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n"); - pThis->omx_report_unsupported_setting(); - break; - - case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: - { - DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG"); - if (pThis->m_cb.EventHandler) { - pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, - (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL ); - } else { - DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__); - } - } - default: - break; - } - } - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if (pThis->m_state != OMX_StatePause) - qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size); - pthread_mutex_unlock(&pThis->m_lock); - } - while(qsize>0); - -} - -int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines) -{ - int format_changed = 0; - if ((height != drv_ctx.video_resolution.frame_height) || - (width != drv_ctx.video_resolution.frame_width)) { - DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n", - width, drv_ctx.video_resolution.frame_width, - height,drv_ctx.video_resolution.frame_height); - format_changed = 1; - } - drv_ctx.video_resolution.frame_height = height; - drv_ctx.video_resolution.frame_width = width; - drv_ctx.video_resolution.scan_lines = scan_lines; - drv_ctx.video_resolution.stride = stride; - rectangle.nLeft = 0; - rectangle.nTop = 0; - rectangle.nWidth = drv_ctx.video_resolution.frame_width; - rectangle.nHeight = drv_ctx.video_resolution.frame_height; - return format_changed; -} - -OMX_ERRORTYPE omx_vdec::is_video_session_supported() -{ -#ifdef H264_PROFILE_LEVEL_CHECK - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", - OMX_MAX_STRINGNAME_SIZE) && - m_profile_lvl.eProfile == OMX_VIDEO_AVCProfileHigh) { - if (m_profile_lvl.eLevel > OMX_VIDEO_AVCLevel3) { - DEBUG_PRINT_ERROR("Unsupported level for H264 High profile"); - return OMX_ErrorUnsupportedSetting; - } - m_decoder_capability.max_width = 864; - m_decoder_capability.max_height = 480; - DEBUG_PRINT_LOW(" set max_width x max_height to 864x480 for H264 high profile"); - } -#endif - - if ((drv_ctx.video_resolution.frame_width * - drv_ctx.video_resolution.frame_height > - m_decoder_capability.max_width * - m_decoder_capability.max_height) || - (drv_ctx.video_resolution.frame_width* - drv_ctx.video_resolution.frame_height < - m_decoder_capability.min_width * - m_decoder_capability.min_height)) - { - DEBUG_PRINT_ERROR( - "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)", - drv_ctx.video_resolution.frame_width, - drv_ctx.video_resolution.frame_height, - m_decoder_capability.min_width, - m_decoder_capability.min_height, - m_decoder_capability.max_width, - m_decoder_capability.max_height); - return OMX_ErrorUnsupportedSetting; - } - DEBUG_PRINT_HIGH("\n video session supported\n"); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentInit - -DESCRIPTION - Initialize the component. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_fmtdesc fdesc; - struct v4l2_format fmt; - struct v4l2_requestbuffers bufreq; - struct v4l2_control control; - struct v4l2_frmsizeenum frmsize; - unsigned int alignment = 0,buffer_size = 0; - int fds[2]; - int r,ret=0; - bool codec_ambiguous = false; - OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec"; - -#ifdef _ANDROID_ - char platform_name[64]; - property_get("ro.board.platform", platform_name, "0"); - if (!strncmp(platform_name, "msm8610", 7)) { - device_name = (OMX_STRING)"/dev/video/q6_dec"; - } -#endif - - if(!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)){ - struct v4l2_control control; - secure_mode = true; - arbitrary_bytes = false; - role = (OMX_STRING)"OMX.qcom.video.decoder.avc"; - } - - drv_ctx.video_driver_fd = open(device_name, O_RDWR); - - DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d", - drv_ctx.video_driver_fd, errno); - - if(drv_ctx.video_driver_fd == 0){ - DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n"); - drv_ctx.video_driver_fd = open(device_name, O_RDWR); - close(0); - } - - if(drv_ctx.video_driver_fd < 0) - { - DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno); - return OMX_ErrorInsufficientResources; - } - drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS; - drv_ctx.frame_rate.fps_denominator = 1; - - ret = subscribe_to_events(drv_ctx.video_driver_fd); - if (!ret) { - async_thread_created = true; - ret = pthread_create(&async_thread_id,0,async_message_thread,this); - } - if(ret) { - DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n"); - async_thread_created = false; - return OMX_ErrorInsufficientResources; - } - -#ifdef INPUT_BUFFER_LOG - strcpy(inputfilename, INPUT_BUFFER_FILE_NAME); -#endif -#ifdef OUTPUT_BUFFER_LOG - outputBufferFile1 = fopen (outputfilename, "ab"); -#endif -#ifdef OUTPUT_EXTRADATA_LOG - outputExtradataFile = fopen (ouputextradatafilename, "ab"); -#endif - - // Copy the role information which provides the decoder kind - strlcpy(drv_ctx.kind,role,128); - - if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE); - drv_ctx.timestamp_adjust = true; - drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4; - eCompressionFormat = OMX_VIDEO_CodingMPEG4; - output_capability=V4L2_PIX_FMT_MPEG4; - /*Initialize Start Code for MPEG4*/ - codec_type_parse = CODEC_TYPE_MPEG4; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "m4v"); -#endif - } - else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.mpeg2",\ - OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2; - output_capability = V4L2_PIX_FMT_MPEG2; - eCompressionFormat = OMX_VIDEO_CodingMPEG2; - /*Initialize Start Code for MPEG2*/ - codec_type_parse = CODEC_TYPE_MPEG2; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "mpg"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("\n H263 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_H263; - eCompressionFormat = OMX_VIDEO_CodingH263; - output_capability = V4L2_PIX_FMT_H263; - codec_type_parse = CODEC_TYPE_H263; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "263"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3; - output_capability = V4L2_PIX_FMT_DIVX_311; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - m_frame_parser.init_start_codes (codec_type_parse); - - eRet = createDivxDrmContext(); - if (eRet != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - return eRet; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4; - output_capability = V4L2_PIX_FMT_DIVX; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - codec_ambiguous = true; - m_frame_parser.init_start_codes (codec_type_parse); - - eRet = createDivxDrmContext(); - if (eRet != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - return eRet; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected"); - drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6; - output_capability = V4L2_PIX_FMT_DIVX; - eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - codec_type_parse = CODEC_TYPE_DIVX; - codec_ambiguous = true; - m_frame_parser.init_start_codes (codec_type_parse); - - eRet = createDivxDrmContext(); - if (eRet != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("createDivxDrmContext Failed"); - return eRet; - } - - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_H264; - output_capability=V4L2_PIX_FMT_H264; - eCompressionFormat = OMX_VIDEO_CodingAVC; - codec_type_parse = CODEC_TYPE_H264; - m_frame_parser.init_start_codes (codec_type_parse); - m_frame_parser.init_nal_length(nal_length); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "264"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_VC1; - eCompressionFormat = OMX_VIDEO_CodingWMV; - codec_type_parse = CODEC_TYPE_VC1; - output_capability = V4L2_PIX_FMT_VC1_ANNEX_G; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "vc1"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV; - eCompressionFormat = OMX_VIDEO_CodingWMV; - codec_type_parse = CODEC_TYPE_VC1; - output_capability = V4L2_PIX_FMT_VC1_ANNEX_L; - m_frame_parser.init_start_codes (codec_type_parse); -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "vc1"); -#endif - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", \ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); - output_capability=V4L2_PIX_FMT_VP8; - eCompressionFormat = OMX_VIDEO_CodingVPX; - codec_type_parse = CODEC_TYPE_VP8; - arbitrary_bytes = false; -#ifdef INPUT_BUFFER_LOG - strcat(inputfilename, "ivf"); -#endif - - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } -#ifdef INPUT_BUFFER_LOG - inputBufferFile1 = fopen (inputfilename, "ab"); - if (output_capability == V4L2_PIX_FMT_VP8) { - struct ivf_file_header - { - OMX_U8 signature[4]; //='DKIF'; - OMX_U8 version ; //= 0; - OMX_U8 headersize ; //= 32; - OMX_U32 FourCC; - OMX_U8 width; - OMX_U8 height; - OMX_U32 rate; - OMX_U32 scale; - OMX_U32 length; - OMX_U8 unused[4]; - } file_header; - memset((void *)&file_header,0,sizeof(file_header)); - file_header.signature[0] = 'D'; - file_header.signature[1] = 'K'; - file_header.signature[2] = 'I'; - file_header.signature[3] = 'F'; - file_header.version = 0; - file_header.headersize = 32; - file_header.FourCC = 0x30385056; - if (inputBufferFile1) - { - fwrite((const char *)&file_header, - sizeof(file_header),1,inputBufferFile1); - } - } -#endif - if (eRet == OMX_ErrorNone) - { - - drv_ctx.output_format = VDEC_YUV_FORMAT_NV12; - OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - if (!client_buffers.set_color_format(dest_color_format)) { - DEBUG_PRINT_ERROR("\n Setting color format failed"); - eRet = OMX_ErrorInsufficientResources; - } - - capture_capability= V4L2_PIX_FMT_NV12; - - struct v4l2_capability cap; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap); - if (ret) { - DEBUG_PRINT_ERROR("Failed to query capabilities\n"); - /*TODO: How to handle this case */ - } else { - DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s," - " version = %d, capabilities = %x\n", cap.driver, cap.card, - cap.bus_info, cap.version, cap.capabilities); - } - ret=0; - fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fdesc.index=0; - while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { - DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, - fdesc.pixelformat, fdesc.flags); - fdesc.index++; - } - fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fdesc.index=0; - while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { - - DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, - fdesc.pixelformat, fdesc.flags); - fdesc.index++; - } - update_resolution(320, 240, 320, 240); - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = output_capability; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to set format on output port\n"); - return OMX_ErrorInsufficientResources; - } - DEBUG_PRINT_HIGH("\n Set Format was successful \n "); - if (codec_ambiguous) { - if (output_capability == V4L2_PIX_FMT_DIVX) { - struct v4l2_control divx_ctrl; - - if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) { - divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4; - } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) { - divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5; - } else { - divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6; - } - - divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl); - if (ret) { - DEBUG_PRINT_ERROR("Failed to set divx version\n"); - } - } else { - DEBUG_PRINT_ERROR("Codec should not be ambiguous"); - } - } - - //Get the hardware capabilities - memset((void *)&frmsize,0,sizeof(frmsize)); - frmsize.index = 0; - frmsize.pixel_format = output_capability; - ret = ioctl(drv_ctx.video_driver_fd, - VIDIOC_ENUM_FRAMESIZES, &frmsize); - if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { - DEBUG_PRINT_ERROR("Failed to get framesizes\n"); - return OMX_ErrorHardware; - } - - if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { - m_decoder_capability.min_width = frmsize.stepwise.min_width; - m_decoder_capability.max_width = frmsize.stepwise.max_width; - m_decoder_capability.min_height = frmsize.stepwise.min_height; - m_decoder_capability.max_height = frmsize.stepwise.max_height; - } - - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = capture_capability; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to set format on capture port\n"); - } - DEBUG_PRINT_HIGH("\n Set Format was successful \n "); - if(secure_mode){ - control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE; - control.value = 1; - DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret); - ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); - if (ret) { - DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret); - return OMX_ErrorInsufficientResources; - } - } - - /*Get the Buffer requirements for input and output ports*/ - drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT; - drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - if (secure_mode) { - drv_ctx.op_buf.alignment=SZ_1M; - drv_ctx.ip_buf.alignment=SZ_1M; - } else { - drv_ctx.op_buf.alignment=SZ_4K; - drv_ctx.ip_buf.alignment=SZ_4K; - } - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; - drv_ctx.extradata = 0; - drv_ctx.picture_order = VDEC_ORDER_DISPLAY; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; - control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - drv_ctx.idr_only_decoding = 0; - - m_state = OMX_StateLoaded; -#ifdef DEFAULT_EXTRADATA - if (eRet == OMX_ErrorNone && !secure_mode) - enable_extradata(DEFAULT_EXTRADATA, true, true); -#endif - eRet=get_buffer_req(&drv_ctx.ip_buf); - DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size); - get_buffer_req(&drv_ctx.op_buf); - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - if (m_frame_parser.mutils == NULL) - { - m_frame_parser.mutils = new H264_Utils(); - - if (m_frame_parser.mutils == NULL) - { - DEBUG_PRINT_ERROR("\n parser utils Allocation failed "); - eRet = OMX_ErrorInsufficientResources; - } - else - { - h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size; - h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size); - h264_scratch.nFilledLen = 0; - h264_scratch.nOffset = 0; - - if (h264_scratch.pBuffer == NULL) - { - DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed "); - return OMX_ErrorInsufficientResources; - } - m_frame_parser.mutils->initialize_frame_checking_environment(); - m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size); - } - } - - h264_parser = new h264_stream_parser(); - if (!h264_parser) - { - DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!"); - eRet = OMX_ErrorInsufficientResources; - } - } - - if(pipe(fds)) - { - DEBUG_PRINT_ERROR("pipe creation failed\n"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - int temp1[2]; - if(fds[0] == 0 || fds[1] == 0) - { - if (pipe (temp1)) - { - DEBUG_PRINT_ERROR("pipe creation failed\n"); - return OMX_ErrorInsufficientResources; - } - //close (fds[0]); - //close (fds[1]); - fds[0] = temp1 [0]; - fds[1] = temp1 [1]; - } - m_pipe_in = fds[0]; - m_pipe_out = fds[1]; - msg_thread_created = true; - r = pthread_create(&msg_thread_id,0,message_thread,this); - - if(r < 0) - { - DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed"); - msg_thread_created = false; - eRet = OMX_ErrorInsufficientResources; - } - } - } - - if (eRet != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Component Init Failed"); - } - else - { - DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success"); - } - //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer)); - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetComponentVersion - -DESCRIPTION - Returns the component version. - -PARAMETERS - TBD. - -RETURN VALUE - OMX_ErrorNone. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_component_version - ( - OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STRING componentName, - OMX_OUT OMX_VERSIONTYPE* componentVersion, - OMX_OUT OMX_VERSIONTYPE* specVersion, - OMX_OUT OMX_UUIDTYPE* componentUUID - ) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n"); - return OMX_ErrorInvalidState; - } - /* TBD -- Return the proper version */ - if (specVersion) - { - specVersion->nVersion = OMX_SPEC_VERSION; - } - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_vdec::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX - && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) - { - DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush " - "to invalid port: %lu", param1); - return OMX_ErrorBadPortIndex; - } - post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); - sem_wait(&m_cmd_lock); - DEBUG_PRINT_LOW("\n send_command: Command Processed\n"); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_STATETYPE eState = (OMX_STATETYPE) param1; - int bFlag = 1,sem_posted = 0,ret=0; - - DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd); - DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d", - m_state, eState); - - if(cmd == OMX_CommandStateSet) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued"); - DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState); - /***************************/ - /* Current State is Loaded */ - /***************************/ - if(m_state == OMX_StateLoaded) - { - if(eState == OMX_StateIdle) - { - //if all buffers are allocated or all ports disabled - if(allocate_done() || - (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) - { - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n"); - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Loaded to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Loaded to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n"); - } - /* Requesting transition from Loaded to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\ - eState); - eRet = OMX_ErrorBadParameter; - } - } - - /***************************/ - /* Current State is IDLE */ - /***************************/ - else if(m_state == OMX_StateIdle) - { - if(eState == OMX_StateLoaded) - { - if(release_done()) - { - /* - Since error is None , we will post an event at the end - of this function definition - */ - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n"); - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Idle to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); - //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING); - bFlag = 1; - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); - m_state=OMX_StateExecuting; - DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n"); - } - /* Requesting transition from Idle to Idle */ - else if(eState == OMX_StateIdle) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Idle to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Idle to Pause */ - else if(eState == OMX_StatePause) - { - /*To pause the Video core we need to start the driver*/ - if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START, - NULL) < */0) - { - DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n"); - bFlag = 0; - } - } - /* Requesting transition from Idle to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - - /******************************/ - /* Current State is Executing */ - /******************************/ - else if(m_state == OMX_StateExecuting) - { - DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting"); - /* Requesting transition from Executing to Idle */ - if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition - */ - DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n"); - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - execute_omx_flush(OMX_ALL); - } - bFlag = 0; - } - /* Requesting transition from Executing to Paused */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_LOW("\n PAUSE Command Issued"); - m_state = OMX_StatePause; - bFlag = 1; - } - /* Requesting transition from Executing to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Executing to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is Pause */ - /***************************/ - else if(m_state == OMX_StatePause) - { - /* Requesting transition from Pause to Executing */ - if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_LOW("\n Pause --> Executing \n"); - m_state = OMX_StateExecuting; - bFlag = 1; - } - /* Requesting transition from Pause to Idle */ - else if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("\n Pause --> Idle \n"); - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - execute_omx_flush(OMX_ALL); - } - bFlag = 0; - } - /* Requesting transition from Pause to loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\n Pause --> loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("\n Pause --> Pause \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Pause to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\n Pause --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is WaitForResources */ - /***************************/ - else if(m_state == OMX_StateWaitForResources) - { - /* Requesting transition from WaitForResources to Loaded */ - if(eState == OMX_StateLoaded) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n"); - } - /* Requesting transition from WaitForResources to WaitForResources */ - else if (eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorSameState, - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from WaitForResources to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - /* Requesting transition from WaitForResources to Loaded - - is NOT tested by Khronos TS */ - - } - else - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState); - eRet = OMX_ErrorBadParameter; - } - } - /********************************/ - /* Current State is Invalid */ - /*******************************/ - else if(m_state == OMX_StateInvalid) - { - /* State Transition from Inavlid to any state */ - if(eState == (OMX_StateLoaded || OMX_StateWaitForResources - || OMX_StateIdle || OMX_StateExecuting - || OMX_StatePause || OMX_StateInvalid)) - { - DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n"); - post_event(OMX_EventError,OMX_ErrorInvalidState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - } - else if (cmd == OMX_CommandFlush) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued" - "with param1: %lu", param1); - if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); - } - if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) - { - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - } - if (!sem_posted){ - sem_posted = 1; - DEBUG_PRINT_LOW("\n Set the Semaphore"); - sem_post (&m_cmd_lock); - execute_omx_flush(param1); - } - bFlag = 0; - } - else if ( cmd == OMX_CommandPortEnable) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued" - "with param1: %lu", param1); - if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_inp_bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || allocate_input_done()) - { - post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) - { - DEBUG_PRINT_LOW("\n Enable output Port command recieved"); - m_out_bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || (allocate_output_done())) - { - post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - - } - else - { - DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - } - else if (cmd == OMX_CommandPortDisable) - { - DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued" - "with param1: %lu", param1); - if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_inp_bEnabled = OMX_FALSE; - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_input_done()) - { - post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - if(!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - } - execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX); - } - - // Skip the event notification - bFlag = 0; - } - } - if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) - { - m_out_bEnabled = OMX_FALSE; - DEBUG_PRINT_LOW("\n Disable output Port command recieved"); - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_output_done()) - { - post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\ - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - if (!sem_posted) - { - sem_posted = 1; - sem_post (&m_cmd_lock); - } - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING); - execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX); - } - // Skip the event notification - bFlag = 0; - - } - } - } - else - { - DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd); - eRet = OMX_ErrorNotImplemented; - } - if(eRet == OMX_ErrorNone && bFlag) - { - post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); - } - if(!sem_posted) - { - sem_post(&m_cmd_lock); - } - - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ExecuteOmxFlush - -DESCRIPTION - Executes the OMX flush. - -PARAMETERS - flushtype - input flush(1)/output flush(0)/ both. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_vdec::execute_omx_flush(OMX_U32 flushType) -{ - bool bRet = false; - struct v4l2_plane plane; - struct v4l2_buffer v4l2_buf; - struct v4l2_decoder_cmd dec; - DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType); - memset((void *)&v4l2_buf,0,sizeof(v4l2_buf)); - dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH; - - DEBUG_PRINT_ERROR("in %s: reconfig? %d", __func__, in_reconfig); - - if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) - { - output_flush_progress = true; - dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; - } - else - { - /* XXX: The driver/hardware does not support flushing of individual ports - * in all states. So we pretty much need to flush both ports internally, - * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it - * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, - * we automatically omit sending the FLUSH done for the "opposite" port. */ - input_flush_progress = true; - output_flush_progress = true; - dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE; - } - - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) - { - DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType); - bRet = false; - } - - return bRet; -} -/*========================================================================= -FUNCTION : execute_output_flush - -DESCRIPTION - Executes the OMX flush at OUTPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_vdec::execute_output_flush() -{ - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate FBD for all Buffers in the FTBq*/ - pthread_mutex_lock(&m_lock); - DEBUG_PRINT_LOW("\n Initiate Output Flush"); - while (m_ftb_q.m_size) - { - DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d", - m_ftb_q.m_size,pending_output_buffers); - m_ftb_q.pop_entry(&p1,&p2,&ident); - DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2); - if(ident == m_fill_output_msg ) - { - m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2); - } - else if (ident == OMX_COMPONENT_GENERATE_FBD) - { - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - pthread_mutex_unlock(&m_lock); - output_flush_progress = false; - - if (arbitrary_bytes) - { - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } - DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers); - return bRet; -} -/*========================================================================= -FUNCTION : execute_input_flush - -DESCRIPTION - Executes the OMX flush at INPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_vdec::execute_input_flush() -{ - unsigned i =0; - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate EBD for all Buffers in the ETBq*/ - DEBUG_PRINT_LOW("\n Initiate Input Flush \n"); - - pthread_mutex_lock(&m_lock); - DEBUG_PRINT_LOW("\n Check if the Queue is empty \n"); - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - - if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) - { - DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2); - m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_ETB) - { - pending_input_buffers++; - DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d", - (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers); - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if (ident == OMX_COMPONENT_GENERATE_EBD) - { - DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p", - (OMX_BUFFERHEADERTYPE *)p1); - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - time_stamp_dts.flush_timestamp(); - /*Check if Heap Buffers are to be flushed*/ - if (arbitrary_bytes && !(codec_config_flag)) - { - DEBUG_PRINT_LOW("\n Reset all the variables before flusing"); - h264_scratch.nFilledLen = 0; - nal_count = 0; - look_ahead_nal = false; - frame_count = 0; - h264_last_au_ts = LLONG_MAX; - h264_last_au_flags = 0; - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - DEBUG_PRINT_LOW("\n Initialize parser"); - if (m_frame_parser.mutils) - { - m_frame_parser.mutils->initialize_frame_checking_environment(); - } - - while (m_input_pending_q.m_size) - { - m_input_pending_q.pop_entry(&p1,&p2,&ident); - m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1); - } - - if (psource_frame) - { - m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame); - psource_frame = NULL; - } - - if (pdest_frame) - { - pdest_frame->nFilledLen = 0; - m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL, - (unsigned int)NULL); - pdest_frame = NULL; - } - m_frame_parser.flush(); - } - else if (codec_config_flag) - { - DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer " - "is not sent to the driver yet"); - } - pthread_mutex_unlock(&m_lock); - input_flush_progress = false; - if (!arbitrary_bytes) - { - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } -#ifdef _ANDROID_ - if (m_debug_timestamp) - { - m_timestamp_list.reset_ts_list(); - } -#endif - DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers); - return bRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::SendCommandEvent - -DESCRIPTION - Send the event to decoder pipe. This is needed to generate the callbacks - in decoder thread context. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_vdec::post_event(unsigned int p1, - unsigned int p2, - unsigned int id) -{ - bool bRet = false; - - - pthread_mutex_lock(&m_lock); - - if (id == m_fill_output_msg || - id == OMX_COMPONENT_GENERATE_FBD) - { - m_ftb_q.insert_entry(p1,p2,id); - } - else if (id == OMX_COMPONENT_GENERATE_ETB || - id == OMX_COMPONENT_GENERATE_EBD || - id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) - { - m_etb_q.insert_entry(p1,p2,id); - } - else - { - m_cmd_q.insert_entry(p1,p2,id); - } - - bRet = true; - DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); - post_message(this, id); - - pthread_mutex_unlock(&m_lock); - - return bRet; -} - -OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 0) { - if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - eRet = OMX_ErrorNoMore; - } - else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain; - profileLevelType->eLevel = OMX_VIDEO_MPEG2LevelHL; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetParameter - -DESCRIPTION - OMX Get Parameter method implementation - -PARAMETERS - . - -RETURN VALUE - Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_INOUT OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - DEBUG_PRINT_LOW("get_parameter: \n"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_LOW("Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - switch((unsigned long)paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn = - (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); - eRet = update_portdef(portDefn); - if (eRet == OMX_ErrorNone) - m_port_def = *portDefn; - break; - } - case OMX_IndexParamVideoInit: - { - OMX_PORT_PARAM_TYPE *portParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); - - portParamType->nVersion.nVersion = OMX_SPEC_VERSION; - portParamType->nSize = sizeof(portParamType); - portParamType->nPorts = 2; - portParamType->nStartPortNumber = 0; - break; - } - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); - - portFmt->nVersion.nVersion = OMX_SPEC_VERSION; - portFmt->nSize = sizeof(portFmt); - - if (0 == portFmt->nPortIndex) - { - if (0 == portFmt->nIndex) - { - portFmt->eColorFormat = OMX_COLOR_FormatUnused; - portFmt->eCompressionFormat = eCompressionFormat; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\ - " NoMore compression formats\n"); - eRet = OMX_ErrorNoMore; - } - } - else if (1 == portFmt->nPortIndex) - { - portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused; - - if(0 == portFmt->nIndex) - portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - else if (1 == portFmt->nIndex) - portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar; - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\ - " NoMore Color formats\n"); - eRet = OMX_ErrorNoMore; - } - ALOGE("returning %d\n", portFmt->eColorFormat); - } - else - { - DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", - (int)portFmt->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamAudioInit: - { - OMX_PORT_PARAM_TYPE *audioPortParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); - audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION; - audioPortParamType->nSize = sizeof(audioPortParamType); - audioPortParamType->nPorts = 0; - audioPortParamType->nStartPortNumber = 0; - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamImageInit: - { - OMX_PORT_PARAM_TYPE *imagePortParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); - imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION; - imagePortParamType->nSize = sizeof(imagePortParamType); - imagePortParamType->nPorts = 0; - imagePortParamType->nStartPortNumber = 0; - break; - - } - /*Component should support this port definition*/ - case OMX_IndexParamOtherInit: - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n", - paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - break; - } - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - comp_role->nVersion.nVersion = OMX_SPEC_VERSION; - comp_role->nSize = sizeof(*comp_role); - - DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n", - paramIndex); - strlcpy((char*)comp_role->cRole,(const char*)m_cRole, - OMX_MAX_STRINGNAME_SIZE); - break; - } - /* Added for parameter test */ - case OMX_IndexParamPriorityMgmt: - { - - OMX_PRIORITYMGMTTYPE *priorityMgmType = - (OMX_PRIORITYMGMTTYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); - priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION; - priorityMgmType->nSize = sizeof(priorityMgmType); - - break; - } - /* Added for parameter test */ - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = - (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); - - bufferSupplierType->nSize = sizeof(bufferSupplierType); - bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; - if(0 == bufferSupplierType->nPortIndex) - bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; - else if (1 == bufferSupplierType->nPortIndex) - bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified; - else - eRet = OMX_ErrorBadPortIndex; - - - break; - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoH263: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg4: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg2: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n", - paramIndex); - break; - } - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex); - OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType = - (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; - eRet = get_supported_profile_level_for_1080p(profileLevelType); - break; - } -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: - { - DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n"); - GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData; - if(nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) { - - if(secure_mode) { - nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED | - GRALLOC_USAGE_PRIVATE_UNCACHED); - } else { - nativeBuffersUsage->nUsage = - (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP | - GRALLOC_USAGE_PRIVATE_UNCACHED); - } - } else { - DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n"); - eRet = OMX_ErrorBadParameter; - } - } - break; -#endif - - default: - { - DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - } - - } - - DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n", - drv_ctx.video_resolution.frame_width, - drv_ctx.video_resolution.frame_height, - drv_ctx.video_resolution.stride, - drv_ctx.video_resolution.scan_lines); - - return eRet; -} - -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) -OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data) -{ - DEBUG_PRINT_LOW("Inside use_android_native_buffer"); - OMX_ERRORTYPE eRet = OMX_ErrorNone; - UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data; - - if((params == NULL) || - (params->nativeBuffer == NULL) || - (params->nativeBuffer->handle == NULL) || - !m_enable_android_native_buffers) - return OMX_ErrorBadParameter; - m_use_android_native_buffers = OMX_TRUE; - sp nBuf = params->nativeBuffer; - private_handle_t *handle = (private_handle_t *)nBuf->handle; - if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port - OMX_U8 *buffer = NULL; - if(!secure_mode) { - buffer = (OMX_U8*)mmap(0, handle->size, - PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); - if(buffer == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); - return OMX_ErrorInsufficientResources; - } - } - eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer); - } else { - eRet = OMX_ErrorBadParameter; - } - return eRet; -} -#endif -/* ====================================================================== -FUNCTION - omx_vdec::Setparameter - -DESCRIPTION - OMX Set Parameter method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_IN OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - int ret=0; - struct v4l2_format fmt; - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Set Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - if((m_state != OMX_StateLoaded) && - BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) && - (m_out_bEnabled == OMX_TRUE) && - BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) && - (m_inp_bEnabled == OMX_TRUE)) { - DEBUG_PRINT_ERROR("Set Param in Invalid State \n"); - return OMX_ErrorIncorrectStateOperation; - } - switch((unsigned long)paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has - //been called. - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", - (int)portDefn->format.video.nFrameHeight, - (int)portDefn->format.video.nFrameWidth); - if(OMX_DirOutput == portDefn->eDir) - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n"); - m_display_id = portDefn->format.video.pNativeWindow; - unsigned int buffer_size; - if (!client_buffers.get_buffer_req(buffer_size)) { - DEBUG_PRINT_ERROR("\n Error in getting buffer requirements"); - eRet = OMX_ErrorBadParameter; - } else { - if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount && - portDefn->nBufferSize >= drv_ctx.op_buf.buffer_size ) - { - drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual; - drv_ctx.op_buf.buffer_size = portDefn->nBufferSize; - drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount; - drv_ctx.extradata_info.size = drv_ctx.extradata_info.count * - drv_ctx.extradata_info.buffer_size; - eRet = set_buffer_req(&drv_ctx.op_buf); - if (eRet == OMX_ErrorNone) - m_port_def = *portDefn; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n", - drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size, - portDefn->nBufferCountActual, portDefn->nBufferSize); - eRet = OMX_ErrorBadParameter; - } - } - } - else if(OMX_DirInput == portDefn->eDir) - { - if((portDefn->format.video.xFramerate >> 16) > 0 && - (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) - { - // Frame rate only should be set if this is a "known value" or to - // activate ts prediction logic (arbitrary mode only) sending input - // timestamps with max value (LLONG_MAX). - DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu", - portDefn->format.video.xFramerate >> 16); - Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator, - drv_ctx.frame_rate.fps_denominator); - if(!drv_ctx.frame_rate.fps_numerator) - { - DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); - drv_ctx.frame_rate.fps_numerator = 30; - } - if(drv_ctx.frame_rate.fps_denominator) - drv_ctx.frame_rate.fps_numerator = (int) - drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; - drv_ctx.frame_rate.fps_denominator = 1; - frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / - drv_ctx.frame_rate.fps_numerator; - DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)", - frm_int, drv_ctx.frame_rate.fps_numerator / - (float)drv_ctx.frame_rate.fps_denominator); - } - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n"); - if(drv_ctx.video_resolution.frame_height != - portDefn->format.video.nFrameHeight || - drv_ctx.video_resolution.frame_width != - portDefn->format.video.nFrameWidth) - { - DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n", - portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight); - if (portDefn->format.video.nFrameHeight != 0x0 && - portDefn->format.video.nFrameWidth != 0x0) - { - update_resolution(portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight, - portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight); - eRet = is_video_session_supported(); - if (eRet) - break; - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = output_capability; - DEBUG_PRINT_LOW("\n fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d \n",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width); - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) - { - DEBUG_PRINT_ERROR("\n Set Resolution failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - else - eRet = get_buffer_req(&drv_ctx.op_buf); - } - } - else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount - || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) - { - vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf; - drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual; - drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) & - (~(buffer_prop->alignment - 1)); - eRet = set_buffer_req(buffer_prop); - } - else - { - DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n", - drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size, - portDefn->nBufferCountActual, portDefn->nBufferSize); - eRet = OMX_ErrorBadParameter; - } - } - else if (portDefn->eDir == OMX_DirMax) - { - DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - } - break; - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - int ret=0; - struct v4l2_format fmt; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", - portFmt->eColorFormat); - - if(1 == portFmt->nPortIndex) - { - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - fmt.fmt.pix_mp.pixelformat = capture_capability; - enum vdec_output_fromat op_format; - if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) || - (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar)) - op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12; - else if(portFmt->eColorFormat == - (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) - op_format = VDEC_YUV_FORMAT_TILE_4x2; - else - eRet = OMX_ErrorBadParameter; - - if(eRet == OMX_ErrorNone) - { - drv_ctx.output_format = op_format; - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if(ret) - { - DEBUG_PRINT_ERROR("\n Set output format failed"); - eRet = OMX_ErrorUnsupportedSetting; - /*TODO: How to handle this case */ - } - else - { - eRet = get_buffer_req(&drv_ctx.op_buf); - } - } - if (eRet == OMX_ErrorNone){ - if (!client_buffers.set_color_format(portFmt->eColorFormat)) { - DEBUG_PRINT_ERROR("\n Set color format failed"); - eRet = OMX_ErrorBadParameter; - } - } - } - } - break; - - case OMX_QcomIndexPortDefn: - { - OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt = - (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n", - portFmt->nFramePackingFormat); - - /* Input port */ - if (portFmt->nPortIndex == 0) - { - if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) - { - if(secure_mode) { - arbitrary_bytes = false; - DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session"); - eRet = OMX_ErrorUnsupportedSetting; - } else { - arbitrary_bytes = true; - } - } - else if (portFmt->nFramePackingFormat == - OMX_QCOM_FramePacking_OnlyOneCompleteFrame) - { - arbitrary_bytes = false; - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n", - portFmt->nFramePackingFormat); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n"); - if( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid && - portFmt->nMemRegion < OMX_QCOM_MemRegionMax) && - portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) - { - m_out_mem_region_smi = OMX_TRUE; - if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n"); - m_use_output_pmem = OMX_TRUE; - } - } - } - } - break; - - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", - comp_role->cRole); - - if((m_state == OMX_StateLoaded)&& - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("Set Parameter called in valid state"); - } - else - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) || - (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) - { - strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind); - eRet = OMX_ErrorInvalidComponentName; - } - break; - } - - case OMX_IndexParamPriorityMgmt: - { - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n", - priorityMgmtype->nGroupID); - - DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n", - priorityMgmtype->nGroupPriority); - - m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; - m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; - - break; - } - - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", - bufferSupplierType->eBufferSupplier); - if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) - m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; - - else - - eRet = OMX_ErrorBadPortIndex; - - break; - - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoH263: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg4: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n", - paramIndex); - break; - } - case OMX_IndexParamVideoMpeg2: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n", - paramIndex); - break; - } - case OMX_QcomIndexParamVideoDecoderPictureOrder: - { - QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder = - (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData; - struct v4l2_control control; - int pic_order,rc=0; - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n", - pictureOrder->eOutputPictureOrder); - if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) { - pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY; - } - else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER){ - pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; - time_stamp_dts.set_timestamp_reorder_mode(false); - } - else - eRet = OMX_ErrorBadParameter; - if (eRet == OMX_ErrorNone) - { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; - control.value = pic_order; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - if(rc) - { - DEBUG_PRINT_ERROR("\n Set picture order failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - } - break; - } - case OMX_QcomIndexParamConcealMBMapExtraData: - if(!secure_mode) - eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - case OMX_QcomIndexParamFrameInfoExtraData: - { - if(!secure_mode) - eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - } - case OMX_QcomIndexParamInterlaceExtraData: - if(!secure_mode) - eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - case OMX_QcomIndexParamH264TimeInfo: - if(!secure_mode) - eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false, - ((QOMX_ENABLETYPE *)paramData)->bEnable); - else { - DEBUG_PRINT_ERROR("\n secure mode setting not supported"); - eRet = OMX_ErrorUnsupportedSetting; - } - break; - case OMX_QcomIndexParamVideoDivx: - { - QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData; - } - break; - case OMX_QcomIndexPlatformPvt: - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n"); - OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData; - if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) - { - DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type); - eRet = OMX_ErrorUnsupportedSetting; - } - else - { - m_out_pvt_entry_pmem = OMX_TRUE; - if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n"); - m_use_output_pmem = OMX_TRUE; - } - } - - } - break; - case OMX_QcomIndexParamVideoSyncFrameDecodingMode: - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode"); - DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode"); - struct v4l2_control control; - int rc; - drv_ctx.idr_only_decoding = 1; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER; - control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - if(rc) - { - DEBUG_PRINT_ERROR("\n Set picture order failed"); - eRet = OMX_ErrorUnsupportedSetting; - } else { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE; - control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control); - if(rc) - { - DEBUG_PRINT_ERROR("\n Sync frame setting failed"); - eRet = OMX_ErrorUnsupportedSetting; - } - /*Setting sync frame decoding on driver might change buffer - * requirements so update them here*/ - if (get_buffer_req(&drv_ctx.ip_buf)) { - DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer requirements"); - eRet = OMX_ErrorUnsupportedSetting; - } - } - } - break; - - case OMX_QcomIndexParamIndexExtraDataType: - { - if(!secure_mode) { - QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData; - if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) && - (extradataIndexType->bEnabled == OMX_TRUE) && - (extradataIndexType->nPortIndex == 1)) - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n"); - eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled); - - } - } - } - break; - case OMX_QcomIndexParamEnableSmoothStreaming: - { -#ifndef SMOOTH_STREAMING_DISABLED - struct v4l2_control control; - struct v4l2_format fmt; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER; - control.value = 1; - int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control); - if(rc < 0) { - DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver."); - eRet = OMX_ErrorHardware; - } -#else - eRet = OMX_ErrorUnsupportedSetting; -#endif - } - break; -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - /* Need to allow following two set_parameters even in Idle - * state. This is ANDROID architecture which is not in sync - * with openmax standard. */ - case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: - { - EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData; - if(enableNativeBuffers) { - m_enable_android_native_buffers = enableNativeBuffers->enable; - } - } - break; - case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: - { - eRet = use_android_native_buffer(hComp, paramData); - } - break; -#endif - case OMX_QcomIndexParamEnableTimeStampReorder: - { - QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData; - if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) { - if (reorder->bEnable == OMX_TRUE) { - frm_int =0; - time_stamp_dts.set_timestamp_reorder_mode(true); - } - else - time_stamp_dts.set_timestamp_reorder_mode(false); - } else { - time_stamp_dts.set_timestamp_reorder_mode(false); - if (reorder->bEnable == OMX_TRUE) - { - eRet = OMX_ErrorUnsupportedSetting; - } - } - } - break; - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = - (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; - if (pParam) { - m_profile_lvl.eProfile = pParam->eProfile; - m_profile_lvl.eLevel = pParam->eLevel; - } - break; - - } - default: - { - DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex); - eRet = OMX_ErrorUnsupportedIndex; - } - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetConfig - -DESCRIPTION - OMX Get Config Method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_INOUT OMX_PTR configData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - if (m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - switch ((unsigned long)configIndex) - { - case OMX_QcomIndexConfigInterlaced: - { - OMX_QCOM_CONFIG_INTERLACETYPE *configFmt = - (OMX_QCOM_CONFIG_INTERLACETYPE *) configData; - if (configFmt->nPortIndex == 1) - { - if (configFmt->nIndex == 0) - { - configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive; - } - else if (configFmt->nIndex == 1) - { - configFmt->eInterlaceType = - OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; - } - else if (configFmt->nIndex == 2) - { - configFmt->eInterlaceType = - OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; - } - else - { - DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:" - " NoMore Interlaced formats\n"); - eRet = OMX_ErrorNoMore; - } - - } - else - { - DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n", - (int)configFmt->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - case OMX_QcomIndexQueryNumberOfVideoDecInstance: - { - QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances = - (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData; - decoderinstances->nNumOfInstances = 16; - /*TODO: How to handle this case */ - break; - } - case OMX_QcomIndexConfigVideoFramePackingArrangement: - { - if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) - { - OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = - (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; - h264_parser->get_frame_pack_data(configFmt); - } - else - { - DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs"); - } - break; - } - case OMX_IndexConfigCommonOutputCrop: - { - OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData; - memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE)); - break; - } - default: - { - DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex); - eRet = OMX_ErrorBadParameter; - } - - } - - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SetConfig - -DESCRIPTION - OMX Set Config method implementation - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_IN OMX_PTR configData) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_VIDEO_CONFIG_NALSIZE *pNal; - - DEBUG_PRINT_LOW("\n Set Config Called"); - - if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) - { - OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData; - DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called"); - if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) - { - DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC"); - OMX_U32 extra_size; - // Parsing done here for the AVC atom is definitely not generic - // Currently this piece of code is working, but certainly - // not tested with all .mp4 files. - // Incase of failure, we might need to revisit this - // for a generic piece of code. - - // Retrieve size of NAL length field - // byte #4 contains the size of NAL lenght field - nal_length = (config->pData[4] & 0x03) + 1; - - extra_size = 0; - if (nal_length > 2) - { - /* Presently we assume that only one SPS and one PPS in AvC1 Atom */ - extra_size = (nal_length - 2) * 2; - } - - // SPS starts from byte #6 - OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]); - OMX_U8 *pDestBuf; - m_vendor_config.nPortIndex = config->nPortIndex; - - // minus 6 --> SPS starts from byte #6 - // minus 1 --> picture param set byte to be ignored from avcatom - m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size; - m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize); - OMX_U32 len; - OMX_U8 index = 0; - // case where SPS+PPS is sent as part of set_config - pDestBuf = m_vendor_config.pData; - - DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n", - m_vendor_config.nPortIndex, - m_vendor_config.nDataSize, - m_vendor_config.pData); - while (index < 2) - { - uint8 *psize; - len = *pSrcBuf; - len = len << 8; - len |= *(pSrcBuf + 1); - psize = (uint8 *) & len; - memcpy(pDestBuf + nal_length, pSrcBuf + 2,len); - for (unsigned int i = 0; i < nal_length; i++) - { - pDestBuf[i] = psize[nal_length - 1 - i]; - } - //memcpy(pDestBuf,pSrcBuf,(len+2)); - pDestBuf += len + nal_length; - pSrcBuf += len + 2; - index++; - pSrcBuf++; // skip picture param set - len = 0; - } - } - else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") || - !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) - { - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize)); - memcpy(m_vendor_config.pData, config->pData,config->nDataSize); - } - else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) - { - if(m_vendor_config.pData) - { - free(m_vendor_config.pData); - m_vendor_config.pData = NULL; - m_vendor_config.nDataSize = 0; - } - - if (((*((OMX_U32 *) config->pData)) & - VC1_SP_MP_START_CODE_MASK) == - VC1_SP_MP_START_CODE) - { - DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = - (OMX_U8 *) malloc(config->nDataSize); - memcpy(m_vendor_config.pData, config->pData, - config->nDataSize); - m_vc1_profile = VC1_SP_MP_RCV; - } - else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) - { - DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = - (OMX_U8 *) malloc((config->nDataSize)); - memcpy(m_vendor_config.pData, config->pData, - config->nDataSize); - m_vc1_profile = VC1_AP; - } - else if ((config->nDataSize == VC1_STRUCT_C_LEN)) - { - DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n"); - m_vendor_config.nPortIndex = config->nPortIndex; - m_vendor_config.nDataSize = config->nDataSize; - m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize); - memcpy(m_vendor_config.pData,config->pData,config->nDataSize); - m_vc1_profile = VC1_SP_MP_RCV; - } - else - { - DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n"); - } - } - return ret; - } - else if (configIndex == OMX_IndexConfigVideoNalSize) - { - struct v4l2_control temp; - temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT; - - pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData); - switch (pNal->nNaluBytes) { - case 0: - temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES; - break; - case 2: - temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH; - break; - case 4: - temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH; - break; - default: - return OMX_ErrorUnsupportedSetting; - } - - if (!arbitrary_bytes) { - /* In arbitrary bytes mode, the assembler strips out nal size and replaces - * with start code, so only need to notify driver in frame by frame mode */ - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) - { - DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT"); - return OMX_ErrorHardware; - } - } - - nal_length = pNal->nNaluBytes; - m_frame_parser.init_nal_length(nal_length); - - DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length); - return ret; - } - else if (configIndex == OMX_IndexVendorVideoFrameRate) - { - OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData; - DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps); - - if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) - { - if (config->bEnabled) - { - if ((config->nFps >> 16) > 0) - { - DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d", - config->nFps >> 16); - Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator, - drv_ctx.frame_rate.fps_denominator); - - if (!drv_ctx.frame_rate.fps_numerator) - { - DEBUG_PRINT_ERROR("Numerator is zero setting to 30"); - drv_ctx.frame_rate.fps_numerator = 30; - } - - if (drv_ctx.frame_rate.fps_denominator) - { - drv_ctx.frame_rate.fps_numerator = (int) - drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator; - } - - drv_ctx.frame_rate.fps_denominator = 1; - frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 / - drv_ctx.frame_rate.fps_numerator; - - struct v4l2_outputparm oparm; - /*XXX: we're providing timing info as seconds per frame rather than frames - * per second.*/ - oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; - oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; - - struct v4l2_streamparm sparm; - sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - sparm.parm.output = oparm; - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) - { - DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ - performance might be affected"); - ret = OMX_ErrorHardware; - } - client_set_fps = true; - } - else - { - DEBUG_PRINT_ERROR("Frame rate not supported."); - ret = OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate"); - client_set_fps = false; - } - } - else - { - DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d", - (int)config->nPortIndex); - ret = OMX_ErrorBadPortIndex; - } - - return ret; - } - - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetExtensionIndex - -DESCRIPTION - OMX GetExtensionIndex method implementaion. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_STRING paramName, - OMX_OUT OMX_INDEXTYPE* indexType) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); - return OMX_ErrorInvalidState; - } - else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode; - } - else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) - { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType; - } -#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_) - else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers; - } - else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2; - } - else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) { - DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName); - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer; - } - else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage; - } -#endif - else { - DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName); - return OMX_ErrorNotImplemented; - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::GetState - -DESCRIPTION - Returns the state information back to the caller. - -PARAMETERS - . - -RETURN VALUE - Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STATETYPE* state) -{ - *state = m_state; - DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentTunnelRequest - -DESCRIPTION - OMX Component Tunnel Request method implementation. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_HANDLETYPE peerComponent, - OMX_IN OMX_U32 peerPort, - OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) -{ - DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::UseOutputBuffer - -DESCRIPTION - Helper function for Use buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_extradata() -{ -#ifdef USE_ION - if (drv_ctx.extradata_info.buffer_size) { - if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) { - munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); - close(drv_ctx.extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&drv_ctx.extradata_info.ion); - } - drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095); - drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory( - drv_ctx.extradata_info.size, 4096, - &drv_ctx.extradata_info.ion.ion_alloc_data, - &drv_ctx.extradata_info.ion.fd_ion_data, 0); - if (drv_ctx.extradata_info.ion.ion_device_fd < 0) { - DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n"); - return OMX_ErrorInsufficientResources; - } - drv_ctx.extradata_info.uaddr = (char *)mmap(NULL, - drv_ctx.extradata_info.size, - PROT_READ|PROT_WRITE, MAP_SHARED, - drv_ctx.extradata_info.ion.fd_ion_data.fd , 0); - if (drv_ctx.extradata_info.uaddr == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); - close(drv_ctx.extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&drv_ctx.extradata_info.ion); - return OMX_ErrorInsufficientResources; - } - } -#endif - return OMX_ErrorNone; -} - -void omx_vdec::free_extradata() { -#ifdef USE_ION - if (drv_ctx.extradata_info.uaddr) { - munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size); - close(drv_ctx.extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&drv_ctx.extradata_info.ion); - } - memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info)); -#endif -} - -OMX_ERRORTYPE omx_vdec::use_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - struct vdec_setbuffer_cmd setbuffers; - OMX_PTR privateAppData = NULL; - private_handle_t *handle = NULL; - OMX_U8 *buff = buffer; - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - int extra_idx = 0; - - if (!m_out_mem_ptr) { - DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers"); - eRet = allocate_output_headers(); - if (eRet == OMX_ErrorNone) - eRet = allocate_extradata(); - } - - if (eRet == OMX_ErrorNone) { - for(i=0; i< drv_ctx.op_buf.actualcount; i++) { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - break; - } - } - } - - if(i >= drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount); - eRet = OMX_ErrorInsufficientResources; - } - - if (eRet == OMX_ErrorNone) { -#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_) - if(m_enable_android_native_buffers) { - if (m_use_android_native_buffers) { - UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData; - sp nBuf = params->nativeBuffer; - handle = (private_handle_t *)nBuf->handle; - privateAppData = params->pAppPrivate; - } else { - handle = (private_handle_t *)buff; - privateAppData = appData; - } - - if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) { - DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback," - " expected %u, got %lu", - drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size); - return OMX_ErrorBadParameter; - } - - if (!m_use_android_native_buffers) { - if (!secure_mode) { - buff = (OMX_U8*)mmap(0, handle->size, - PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0); - if (buff == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size); - return OMX_ErrorInsufficientResources; - } - } - } -#if defined(_ANDROID_ICS_) - native_buffer[i].nativehandle = handle; - native_buffer[i].privatehandle = handle; -#endif - if(!handle) { - DEBUG_PRINT_ERROR("Native Buffer handle is NULL"); - return OMX_ErrorBadParameter; - } - drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd; - drv_ctx.ptr_outputbuffer[i].offset = 0; - drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; - drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; - drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size; - } else -#endif - - if (!ouput_egl_buffers && !m_use_output_pmem) { -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( - drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment, - &drv_ctx.op_buf_ion_info[i].ion_alloc_data, - &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); - if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd); - return OMX_ErrorInsufficientResources; - } - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; -#else - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - open (MEM_DEVICE,O_RDWR); - - if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { - DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); - return OMX_ErrorInsufficientResources; - } - - /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */ - if(drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) - { - drv_ctx.ptr_outputbuffer[i].pmem_fd = \ - open (MEM_DEVICE,O_RDWR); - if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) { - DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd); - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd, - drv_ctx.op_buf.buffer_size, - drv_ctx.op_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(drv_ctx.ptr_outputbuffer[i].pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if(!secure_mode) { - drv_ctx.ptr_outputbuffer[i].bufferaddr = - (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size, - PROT_READ|PROT_WRITE, MAP_SHARED, - drv_ctx.ptr_outputbuffer[i].pmem_fd,0); - if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) { - close(drv_ctx.ptr_outputbuffer[i].pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[i]); -#endif - DEBUG_PRINT_ERROR("Unable to mmap output buffer\n"); - return OMX_ErrorInsufficientResources; - } - } - drv_ctx.ptr_outputbuffer[i].offset = 0; - privateAppData = appData; - } - else { - - DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem); - if (!appData || !bytes ) { - if(!secure_mode && !buffer) { - DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case"); - return OMX_ErrorBadParameter; - } - } - - OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info; - pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData; - if (!pmem_list->entryList || !pmem_list->entryList->entry || - !pmem_list->nEntries || - pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) { - DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer"); - return OMX_ErrorBadParameter; - } - pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - pmem_list->entryList->entry; - DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx", - pmem_info->pmem_fd); - drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd; - drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset; - drv_ctx.ptr_outputbuffer[i].bufferaddr = buff; - drv_ctx.ptr_outputbuffer[i].mmaped_size = - drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size; - privateAppData = appData; - } - m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; - m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd; - - *bufferHdr = (m_out_mem_ptr + i ); - if(secure_mode) - drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; - //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i], - sizeof (vdec_bufferpayload)); - - DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i, - drv_ctx.ptr_outputbuffer[i].bufferaddr, - drv_ctx.ptr_outputbuffer[i].pmem_fd ); - - buf.index = i; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].length = drv_ctx.op_buf.buffer_size; - plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - - (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; - plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd; - plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; - plane[0].data_offset = 0; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; - plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - buf.m.planes = plane; - buf.length = drv_ctx.num_planes; - - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) { - DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); - /*TODO: How to handle this case */ - return OMX_ErrorInsufficientResources; - } - - if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) { - enum v4l2_buf_type buf_type; - buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) { - return OMX_ErrorInsufficientResources; - } else { - streaming[CAPTURE_PORT] = true; - DEBUG_PRINT_LOW("\n STREAMON Successful \n "); - } - } - - (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size; - if (m_enable_android_native_buffers) { - DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle); - (*bufferHdr)->pBuffer = (OMX_U8 *)handle; - } else { - (*bufferHdr)->pBuffer = buff; - } - (*bufferHdr)->pAppPrivate = privateAppData; - BITMASK_SET(&m_out_bm_count,i); - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::use_input_heap_buffers - -DESCRIPTION - OMX Use Buffer Heap allocation method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_input_heap_buffers( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer); - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!m_inp_heap_ptr) - m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), - drv_ctx.ip_buf.actualcount); - if(!m_phdr_pmem_ptr) - m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) - calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), - drv_ctx.ip_buf.actualcount); - if(!m_inp_heap_ptr || !m_phdr_pmem_ptr) - { - DEBUG_PRINT_ERROR("Insufficent memory"); - eRet = OMX_ErrorInsufficientResources; - } - else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) - { - input_use_buffer = true; - memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE)); - m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer; - m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes; - m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData; - m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput; - m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax; - *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt]; - eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes); - DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]); - if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], - (unsigned)NULL, (unsigned)NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); - return OMX_ErrorInsufficientResources; - } - m_in_alloc_cnt++; - } - else - { - DEBUG_PRINT_ERROR("All i/p buffers have been set!"); - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_vdec::UseBuffer - -DESCRIPTION - OMX Use Buffer method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE error = OMX_ErrorNone; - struct vdec_setbuffer_cmd setbuffers; - - if (bufferHdr == NULL || bytes == 0) - { - if(!secure_mode && buffer == NULL) { - DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer); - return OMX_ErrorBadParameter; - } - } - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(port == OMX_CORE_INPUT_PORT_INDEX) - error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer); - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested - else - { - DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); - error = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error); - if(error == OMX_ErrorNone) - { - if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated && - BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated && - BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - return error; -} - -OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex, - OMX_BUFFERHEADERTYPE *pmem_bufferHdr) -{ - if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) - { - if(m_inp_heap_ptr[bufferindex].pBuffer) - free(m_inp_heap_ptr[bufferindex].pBuffer); - m_inp_heap_ptr[bufferindex].pBuffer = NULL; - } - if (pmem_bufferHdr) - free_input_buffer(pmem_bufferHdr); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - if (bufferHdr == NULL || m_inp_mem_ptr == NULL) - { - return OMX_ErrorBadParameter; - } - - index = bufferHdr - m_inp_mem_ptr; - DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); - - if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) - { - DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index); - if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) - { - struct vdec_setbuffer_cmd setbuffers; - setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index], - sizeof (vdec_bufferpayload)); - if(!secure_mode) { - DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d", - drv_ctx.ptr_inputbuffer[index].pmem_fd); - DEBUG_PRINT_LOW("\n unmap the input buffer size=%d address = %p", - drv_ctx.ptr_inputbuffer[index].mmaped_size, - drv_ctx.ptr_inputbuffer[index].bufferaddr); - munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr, - drv_ctx.ptr_inputbuffer[index].mmaped_size); - } - close (drv_ctx.ptr_inputbuffer[index].pmem_fd); - drv_ctx.ptr_inputbuffer[index].pmem_fd = -1; - if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) - { - free(m_desc_buffer_ptr[index].buf_addr); - m_desc_buffer_ptr[index].buf_addr = NULL; - m_desc_buffer_ptr[index].desc_data_size = 0; - } -#ifdef USE_ION - free_ion_memory(&drv_ctx.ip_buf_ion_info[index]); -#endif - } - } - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - - if (bufferHdr == NULL || m_out_mem_ptr == NULL) - { - return OMX_ErrorBadParameter; - } - - index = bufferHdr - m_out_mem_ptr; - DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index); - - if (index < drv_ctx.op_buf.actualcount - && drv_ctx.ptr_outputbuffer) - { - DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index, - drv_ctx.ptr_outputbuffer[index].bufferaddr); - - struct vdec_setbuffer_cmd setbuffers; - setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index], - sizeof (vdec_bufferpayload)); -#ifdef _ANDROID_ - if(m_enable_android_native_buffers) { - if (!secure_mode) { - if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) { - munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr, - drv_ctx.ptr_outputbuffer[index].mmaped_size); - } - } - drv_ctx.ptr_outputbuffer[index].pmem_fd = -1; - } else { -#endif - if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) - { - if (!secure_mode) { - DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d", - drv_ctx.ptr_outputbuffer[0].pmem_fd); - DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d address = %p", - drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount, - drv_ctx.ptr_outputbuffer[0].bufferaddr); - munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr, - drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount); - } - close (drv_ctx.ptr_outputbuffer[0].pmem_fd); - drv_ctx.ptr_outputbuffer[0].pmem_fd = -1; -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[0]); -#endif - } -#ifdef _ANDROID_ - } -#endif - if (release_output_done()) { - free_extradata(); - } - } - - return OMX_ErrorNone; - -} - -OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes) -{ - OMX_BUFFERHEADERTYPE *input = NULL; - unsigned char *buf_addr = NULL; - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned i = 0; - - /* Sanity Check*/ - if (bufferHdr == NULL) - { - return OMX_ErrorBadParameter; - } - - if (m_inp_heap_ptr == NULL) - { - m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), - drv_ctx.ip_buf.actualcount); - m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), - drv_ctx.ip_buf.actualcount); - - if (m_inp_heap_ptr == NULL) - { - DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - } - - /*Find a Free index*/ - for(i=0; i< drv_ctx.ip_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_heap_inp_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); - break; - } - } - - if (i < drv_ctx.ip_buf.actualcount) - { - buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size); - - if (buf_addr == NULL) - { - return OMX_ErrorInsufficientResources; - } - - *bufferHdr = (m_inp_heap_ptr + i); - input = *bufferHdr; - BITMASK_SET(&m_heap_inp_bm_count,i); - - input->pBuffer = (OMX_U8 *)buf_addr; - input->nSize = sizeof(OMX_BUFFERHEADERTYPE); - input->nVersion.nVersion = OMX_SPEC_VERSION; - input->nAllocLen = drv_ctx.ip_buf.buffer_size; - input->pAppPrivate = appData; - input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; - DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr ); - eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes); - DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]); - /*Add the Buffers to freeq*/ - if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i], - (unsigned)NULL, (unsigned)NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:Free_q is full"); - return OMX_ErrorInsufficientResources; - } - } - else - { - return OMX_ErrorBadParameter; - } - - return eRet; - -} - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateInputBuffer - -DESCRIPTION - Helper function for allocate buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_input_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct vdec_setbuffer_cmd setbuffers; - OMX_BUFFERHEADERTYPE *input = NULL; - unsigned i = 0; - unsigned char *buf_addr = NULL; - int pmem_fd = -1; - - if(bytes != drv_ctx.ip_buf.buffer_size) - { - DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d", - bytes, drv_ctx.ip_buf.buffer_size); - return OMX_ErrorBadParameter; - } - - if(!m_inp_mem_ptr) - { - DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)", - drv_ctx.ip_buf.actualcount, - drv_ctx.ip_buf.buffer_size); - - m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount); - - if (m_inp_mem_ptr == NULL) - { - return OMX_ErrorInsufficientResources; - } - - drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \ - calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount); - - if (drv_ctx.ptr_inputbuffer == NULL) - { - return OMX_ErrorInsufficientResources; - } -#ifdef USE_ION - drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \ - calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount); - - if (drv_ctx.ip_buf_ion_info == NULL) - { - return OMX_ErrorInsufficientResources; - } -#endif - - for (i=0; i < drv_ctx.ip_buf.actualcount; i++) - { - drv_ctx.ptr_inputbuffer [i].pmem_fd = -1; -#ifdef USE_ION - drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1; -#endif - } - } - - for(i=0; i< drv_ctx.ip_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_inp_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i); - break; - } - } - - if(i < drv_ctx.ip_buf.actualcount) - { - struct v4l2_buffer buf; - struct v4l2_plane plane; - int rc; - DEBUG_PRINT_LOW("\n Allocate input Buffer"); -#ifdef USE_ION - drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory( - drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment, - &drv_ctx.ip_buf_ion_info[i].ion_alloc_data, - &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0); - if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd; -#else - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); - return OMX_ErrorInsufficientResources; - } - - if (pmem_fd == 0) - { - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer"); - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size, - drv_ctx.ip_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if (!secure_mode) { - buf_addr = (unsigned char *)mmap(NULL, - drv_ctx.ip_buf.buffer_size, - PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0); - - if (buf_addr == MAP_FAILED) - { - close(pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.ip_buf_ion_info[i]); -#endif - DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer"); - return OMX_ErrorInsufficientResources; - } - } - *bufferHdr = (m_inp_mem_ptr + i); - if (secure_mode) - drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr; - else - drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr; - drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd; - drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size; - drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size; - drv_ctx.ptr_inputbuffer [i].offset = 0; - - - buf.index = i; - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane.bytesused = 0; - plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size; - plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr; - plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd; - plane.reserved[1] = 0; - plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset; - buf.m.planes = &plane; - buf.length = 1; - - DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i, - drv_ctx.ptr_inputbuffer[i].bufferaddr); - - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); - - if (rc) { - DEBUG_PRINT_ERROR("Failed to prepare bufs\n"); - /*TODO: How to handle this case */ - return OMX_ErrorInsufficientResources; - } - - input = *bufferHdr; - BITMASK_SET(&m_inp_bm_count,i); - DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr); - if (secure_mode) - input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd; - else - input->pBuffer = (OMX_U8 *)buf_addr; - input->nSize = sizeof(OMX_BUFFERHEADERTYPE); - input->nVersion.nVersion = OMX_SPEC_VERSION; - input->nAllocLen = drv_ctx.ip_buf.buffer_size; - input->pAppPrivate = appData; - input->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; - input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; - - if (drv_ctx.disable_dmx) - { - eRet = allocate_desc_buffer(i); - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found"); - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateOutputBuffer - -DESCRIPTION - Helper fn for AllocateBuffer in the output pin - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything went well. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - struct vdec_setbuffer_cmd setbuffers; - int extra_idx = 0; -#ifdef USE_ION - int ion_device_fd =-1; - struct ion_allocation_data ion_alloc_data; - struct ion_fd_data fd_ion_data; -#endif - if(!m_out_mem_ptr) - { - DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)", - drv_ctx.op_buf.actualcount, - drv_ctx.op_buf.buffer_size); - int nBufHdrSize = 0; - int nPlatformEntrySize = 0; - int nPlatformListSize = 0; - int nPMEMInfoSize = 0; - int pmem_fd = -1; - unsigned char *pmem_baseaddress = NULL; - - OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; - - DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n", - drv_ctx.op_buf.actualcount); - nBufHdrSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_BUFFERHEADERTYPE); - - nPMEMInfoSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); - nPlatformListSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); - nPlatformEntrySize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); - - DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, - sizeof(OMX_BUFFERHEADERTYPE), - nPMEMInfoSize, - nPlatformListSize); - DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize, - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - ion_device_fd = alloc_map_ion_memory( - drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount, - drv_ctx.op_buf.alignment, - &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0); - if (ion_device_fd < 0) { - return OMX_ErrorInsufficientResources; - } - pmem_fd = fd_ion_data.fd; -#else - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", - drv_ctx.op_buf.buffer_size); - return OMX_ErrorInsufficientResources; - } - - if(pmem_fd == 0) - { - pmem_fd = open (MEM_DEVICE,O_RDWR); - - if (pmem_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d", - drv_ctx.op_buf.buffer_size); - return OMX_ErrorInsufficientResources; - } - } - - if(!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size * - drv_ctx.op_buf.actualcount, - drv_ctx.op_buf.alignment)) - { - DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed"); - close(pmem_fd); - return OMX_ErrorInsufficientResources; - } -#endif - if (!secure_mode) { - pmem_baseaddress = (unsigned char *)mmap(NULL, - (drv_ctx.op_buf.buffer_size * - drv_ctx.op_buf.actualcount), - PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0); - if (pmem_baseaddress == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\n MMAP failed for Size %d", - drv_ctx.op_buf.buffer_size); - close(pmem_fd); -#ifdef USE_ION - free_ion_memory(&drv_ctx.op_buf_ion_info[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - // Alloc mem for platform specific info - char *pPtr=NULL; - pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + - nPMEMInfoSize,1); - drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\ - calloc (sizeof(struct vdec_bufferpayload), - drv_ctx.op_buf.actualcount); - drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ - calloc (sizeof (struct vdec_output_frameinfo), - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - drv_ctx.op_buf_ion_info = (struct vdec_ion *)\ - calloc (sizeof(struct vdec_ion), - drv_ctx.op_buf.actualcount); -#endif - - if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer - && drv_ctx.ptr_respbuffer) - { - drv_ctx.ptr_outputbuffer[0].mmaped_size = - (drv_ctx.op_buf.buffer_size * - drv_ctx.op_buf.actualcount); - bufHdr = m_out_mem_ptr; - m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); - m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) - (((char *) m_platform_list) + nPlatformListSize); - m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - (((char *) m_platform_entry) + nPlatformEntrySize); - pPlatformList = m_platform_list; - pPlatformEntry = m_platform_entry; - pPMEMInfo = m_pmem_info; - - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); - - // Settting the entire storage nicely - DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry); - DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); - for(i=0; i < drv_ctx.op_buf.actualcount ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = bytes; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = appData; - bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - // Platform specific PMEM Information - // Initialize the Platform Entry - //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i); - pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pPlatformEntry->entry = pPMEMInfo; - // Initialize the Platform List - pPlatformList->nEntries = 1; - pPlatformList->entryList = pPlatformEntry; - // Keep pBuffer NULL till vdec is opened - bufHdr->pBuffer = NULL; - bufHdr->nOffset = 0; - - pPMEMInfo->offset = drv_ctx.op_buf.buffer_size*i; - pPMEMInfo->pmem_fd = 0; - bufHdr->pPlatformPrivate = pPlatformList; - - drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd; - m_pmem_info[i].pmem_fd = pmem_fd; -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd; - drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data; - drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data; -#endif - - /*Create a mapping between buffers*/ - bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; - drv_ctx.ptr_respbuffer[i].client_data = (void *)\ - &drv_ctx.ptr_outputbuffer[i]; - drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i; - drv_ctx.ptr_outputbuffer[i].bufferaddr = - pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i); - - DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p", - pmem_fd, drv_ctx.ptr_outputbuffer[i].offset, - drv_ctx.ptr_outputbuffer[i].bufferaddr); - // Move the buffer and buffer header pointers - bufHdr++; - pPMEMInfo++; - pPlatformEntry++; - pPlatformList++; - } - } - else - { - DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ - m_out_mem_ptr, pPtr); - if(m_out_mem_ptr) - { - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(pPtr) - { - free(pPtr); - pPtr = NULL; - } - if(drv_ctx.ptr_outputbuffer) - { - free(drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } - if(drv_ctx.ptr_respbuffer) - { - free(drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif - eRet = OMX_ErrorInsufficientResources; - } - if (eRet == OMX_ErrorNone) - eRet = allocate_extradata(); - } - - for(i=0; i< drv_ctx.op_buf.actualcount; i++) - { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); - break; - } - } - - if (eRet == OMX_ErrorNone) - { - if(i < drv_ctx.op_buf.actualcount) - { - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - int rc; - m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset; - - drv_ctx.ptr_outputbuffer[i].buffer_len = - drv_ctx.op_buf.buffer_size; - - *bufferHdr = (m_out_mem_ptr + i ); - if (secure_mode) { - drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr; - } - drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size; - - buf.index = i; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].length = drv_ctx.op_buf.buffer_size; - plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr - - (unsigned long)drv_ctx.ptr_outputbuffer[i].offset; -#ifdef USE_ION - plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd; -#endif - plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset; - plane[0].data_offset = 0; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; - plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - buf.m.planes = plane; - buf.length = drv_ctx.num_planes; - DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr); - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf); - if (rc) { - /*TODO: How to handle this case */ - return OMX_ErrorInsufficientResources; - } - - if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) { - enum v4l2_buf_type buf_type; - buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); - if (rc) { - return OMX_ErrorInsufficientResources; - } else { - streaming[CAPTURE_PORT] = true; - DEBUG_PRINT_LOW("\n STREAMON Successful \n "); - } - } - - (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr; - (*bufferHdr)->pAppPrivate = appData; - BITMASK_SET(&m_out_bm_count,i); - } - else - { - DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n"); - eRet = OMX_ErrorInsufficientResources; - } - } - - return eRet; -} - - -// AllocateBuffer -- API Call -/* ====================================================================== -FUNCTION - omx_vdec::AllocateBuffer - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - unsigned i = 0; - OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type - - DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if(port == OMX_CORE_INPUT_PORT_INDEX) - { - if (arbitrary_bytes) - { - eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes); - } - else - { - eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); - } - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - { - eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port, - appData,bytes); - } - else - { - DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); - if(eRet == OMX_ErrorNone) - { - if(allocate_done()){ - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - } - DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); - return eRet; -} - -// Free Buffer - API call -/* ====================================================================== -FUNCTION - omx_vdec::FreeBuffer - -DESCRIPTION - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int nPortIndex; - DEBUG_PRINT_LOW("In for decoder free_buffer \n"); - - if(m_state == OMX_StateIdle && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); - } - else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)|| - (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) - { - DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port); - } - else if ((port == OMX_CORE_INPUT_PORT_INDEX && - BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) || - (port == OMX_CORE_OUTPUT_PORT_INDEX && - BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) - { - DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port); - } - else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) - { - DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - - return OMX_ErrorIncorrectStateOperation; - } - else if (m_state != OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - } - - if(port == OMX_CORE_INPUT_PORT_INDEX) - { - /*Check if arbitrary bytes*/ - if(!arbitrary_bytes && !input_use_buffer) - nPortIndex = buffer - m_inp_mem_ptr; - else - nPortIndex = buffer - m_inp_heap_ptr; - - DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex); - if(nPortIndex < drv_ctx.ip_buf.actualcount) - { - // Clear the bit associated with it. - BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); - BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex); - if (input_use_buffer == true) - { - - DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex); - if(m_phdr_pmem_ptr) - free_input_buffer(m_phdr_pmem_ptr[nPortIndex]); - } - else - { - if (arbitrary_bytes) - { - if(m_phdr_pmem_ptr) - free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]); - else - free_input_buffer(nPortIndex,NULL); - } - else - free_input_buffer(buffer); - } - m_inp_bPopulated = OMX_FALSE; - /*Free the Buffer Header*/ - if (release_input_done()) - { - DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released"); - free_input_buffer_header(); - } - } - else - { - DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) - && release_input_done()) - { - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); - post_event(OMX_CommandPortDisable, - OMX_CORE_INPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else if(port == OMX_CORE_OUTPUT_PORT_INDEX) - { - // check if the buffer is valid - nPortIndex = buffer - client_buffers.get_il_buf_hdr(); - if(nPortIndex < drv_ctx.op_buf.actualcount) - { - DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex); - // Clear the bit associated with it. - BITMASK_CLEAR(&m_out_bm_count,nPortIndex); - m_out_bPopulated = OMX_FALSE; - client_buffers.free_output_buffer (buffer); - - if (release_output_done()) - { - free_output_buffer_header(); - } - } - else - { - DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) - && release_output_done()) - { - DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); - - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers"); - memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); - } -#endif - - post_event(OMX_CommandPortDisable, - OMX_CORE_OUTPUT_PORT_INDEX, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else - { - eRet = OMX_ErrorBadPortIndex; - } - if((eRet == OMX_ErrorNone) && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - if(release_done()) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); - post_event(OMX_CommandStateSet, OMX_StateLoaded, - OMX_COMPONENT_GENERATE_EVENT); - } - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_vdec::EmptyThisBuffer - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE ret1 = OMX_ErrorNone; - unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount; - - if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) - { - codec_config_flag = true; - DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__); - } - else - { - codec_config_flag = false; - } - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (buffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL"); - return OMX_ErrorBadParameter; - } - - if (!m_inp_bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled."); - return OMX_ErrorIncorrectStateOperation; - } - - if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) - { - DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex); - return OMX_ErrorBadPortIndex; - } - -#ifdef _ANDROID_ - if(iDivXDrmDecrypt) - { - OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer); - if(drmErr != OMX_ErrorNone) { - // this error can be ignored - DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr); - } - } -#endif //_ANDROID_ - if (perf_flag) - { - if (!latency) - { - dec_time.stop(); - latency = dec_time.processing_time_us(); - dec_time.start(); - } - } - - if (arbitrary_bytes) - { - nBufferIndex = buffer - m_inp_heap_ptr; - } - else - { - if (input_use_buffer == true) - { - nBufferIndex = buffer - m_inp_heap_ptr; - m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen; - m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp; - m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags; - buffer = &m_inp_mem_ptr[nBufferIndex]; - DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu", - &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen); - } - else{ - nBufferIndex = buffer - m_inp_mem_ptr; - } - } - - if (nBufferIndex > drv_ctx.ip_buf.actualcount ) - { - DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid"); - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)", - buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen); - if (arbitrary_bytes) - { - post_event ((unsigned)hComp,(unsigned)buffer, - OMX_COMPONENT_GENERATE_ETB_ARBITRARY); - } - else - { - if (!(client_extradata & OMX_TIMEINFO_EXTRADATA)) - set_frame_rate(buffer->nTimeStamp); - post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::empty_this_buffer_proxy - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - int push_cnt = 0,i=0; - unsigned nPortIndex = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - struct vdec_input_frameinfo frameinfo; - struct vdec_bufferpayload *temp_buffer; - struct vdec_seqheader seq_header; - bool port_setting_changed = true; - bool not_coded_vop = false; - - /*Should we generate a Aync error event*/ - if (buffer == NULL || buffer->pInputPortPrivate == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid"); - return OMX_ErrorBadParameter; - } - - nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - - if (nPortIndex > drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]", - nPortIndex); - return OMX_ErrorBadParameter; - } - - pending_input_buffers++; - - /* return zero length and not an EOS buffer */ - if (!arbitrary_bytes && (buffer->nFilledLen == 0) && - ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) - { - DEBUG_PRINT_HIGH("\n return zero legth buffer"); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorNone; - } - - - if(codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX){ - mp4StreamType psBits; - psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset); - psBits.numBytes = buffer->nFilledLen; - mp4_headerparser.parseHeader(&psBits); - not_coded_vop = mp4_headerparser.is_notcodec_vop( - (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); - if(not_coded_vop) { - DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u", - buffer->nFilledLen,frame_count); - if(buffer->nFlags & OMX_BUFFERFLAG_EOS){ - DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero"); - not_coded_vop = false; - buffer->nFilledLen = 0; - } - } - } - - if(input_flush_progress == true - - || not_coded_vop - - ) - { - DEBUG_PRINT_LOW("\n Flush in progress return buffer "); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorNone; - } - - temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate; - - if ((temp_buffer - drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) - { - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - /*for use buffer we need to memcpy the data*/ - temp_buffer->buffer_len = buffer->nFilledLen; - - if (input_use_buffer) - { - if (buffer->nFilledLen <= temp_buffer->buffer_len) - { - if(arbitrary_bytes) - { - memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen); - } - else - { - memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset), - buffer->nFilledLen); - } - } - else - { - return OMX_ErrorBadParameter; - } - - } - - frameinfo.bufferaddr = temp_buffer->bufferaddr; - frameinfo.client_data = (void *) buffer; - frameinfo.datalen = temp_buffer->buffer_len; - frameinfo.flags = 0; - frameinfo.offset = buffer->nOffset; - frameinfo.pmem_fd = temp_buffer->pmem_fd; - frameinfo.pmem_offset = temp_buffer->offset; - frameinfo.timestamp = buffer->nTimeStamp; - if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) - { - DEBUG_PRINT_LOW("ETB: dmx enabled"); - if (m_demux_entries == 0) - { - extract_demux_addr_offsets(buffer); - } - - DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries); - handle_demux_data(buffer); - frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr; - frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size; - } - else - { - frameinfo.desc_addr = NULL; - frameinfo.desc_size = 0; - } - if(!arbitrary_bytes) - { - frameinfo.flags |= buffer->nFlags; - } - -#ifdef _ANDROID_ - if (m_debug_timestamp) - { - if(arbitrary_bytes) - { - DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); - m_timestamp_list.insert_ts(buffer->nTimeStamp); - } - else if(!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) - { - DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp); - m_timestamp_list.insert_ts(buffer->nTimeStamp); - } - } -#endif - -#ifdef INPUT_BUFFER_LOG - if (output_capability == V4L2_PIX_FMT_VP8) { - struct vp8_ivf_frame_header{ - OMX_U32 framesize; - OMX_U32 timestamp_lo; - OMX_U32 timestamp_hi; - } vp8_frame_header; - vp8_frame_header.framesize = temp_buffer->buffer_len; - /* Currently FW doesn't use timestamp values */ - vp8_frame_header.timestamp_lo = 0; - vp8_frame_header.timestamp_hi = 0; - if (inputBufferFile1) - { - fwrite((const char *)&vp8_frame_header, - sizeof(vp8_frame_header),1,inputBufferFile1); - fwrite((const char *)temp_buffer->bufferaddr, - temp_buffer->buffer_len,1,inputBufferFile1); - } - } else { - if (inputBufferFile1) - { - fwrite((const char *)temp_buffer->bufferaddr, - temp_buffer->buffer_len,1,inputBufferFile1); - } - } -#endif - - if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) - { - frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; - } - - if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) - { - DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached"); - frameinfo.flags |= VDEC_BUFFERFLAG_EOS; - h264_scratch.nFilledLen = 0; - nal_count = 0; - look_ahead_nal = false; - frame_count = 0; - if (m_frame_parser.mutils) - m_frame_parser.mutils->initialize_frame_checking_environment(); - m_frame_parser.flush(); - h264_last_au_ts = LLONG_MAX; - h264_last_au_flags = 0; - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - } - struct v4l2_buffer buf; - struct v4l2_plane plane; - memset( (void *)&buf, 0, sizeof(buf)); - memset( (void *)&plane, 0, sizeof(plane)); - int rc; - unsigned long print_count; - if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) - { buf.flags = V4L2_BUF_FLAG_EOS; - DEBUG_PRINT_HIGH("\n INPUT EOS reached \n") ; - } - OMX_ERRORTYPE eRet = OMX_ErrorNone; - buf.index = nPortIndex; - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane.bytesused = temp_buffer->buffer_len; - plane.length = drv_ctx.ip_buf.buffer_size; - plane.m.userptr = (unsigned long)temp_buffer->bufferaddr - - (unsigned long)temp_buffer->offset; - plane.reserved[0] = temp_buffer->pmem_fd; - plane.reserved[1] = temp_buffer->offset; - plane.data_offset = 0; - buf.m.planes = &plane; - buf.length = 1; - if (frameinfo.timestamp >= LLONG_MAX) { - buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID; - } - //assumption is that timestamp is in milliseconds - buf.timestamp.tv_sec = frameinfo.timestamp / 1000000; - buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000); - buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0; - buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0; - - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); - if(rc) - { - DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n"); - return OMX_ErrorHardware; - } - if(!streaming[OUTPUT_PORT]) - { - enum v4l2_buf_type buf_type; - int ret,r; - - buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); - ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type); - if(!ret) { - DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n"); - streaming[OUTPUT_PORT] = true; - } else{ - DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n"); - DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued"); - post_event ((unsigned int)buffer,VDEC_S_SUCCESS, - OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorBadParameter; - } -} - DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)", - frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen); - time_stamp_dts.insert_timestamp(buffer); - - return ret; -} - -/* ====================================================================== -FUNCTION - omx_vdec::FillThisBuffer - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("FTB in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (!m_out_bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled."); - return OMX_ErrorIncorrectStateOperation; - } - - if (buffer == NULL || - ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) - { - return OMX_ErrorBadParameter; - } - - if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) - { - DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex); - return OMX_ErrorBadPortIndex; - } - - DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg); - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_vdec::fill_this_buffer_proxy - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::fill_this_buffer_proxy( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) -{ - OMX_ERRORTYPE nRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *buffer = bufferAdd; - unsigned nPortIndex = 0; - struct vdec_fillbuffer_cmd fillbuffer; - struct vdec_bufferpayload *ptr_outputbuffer = NULL; - struct vdec_output_frameinfo *ptr_respbuffer = NULL; - - nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()); - - if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) - return OMX_ErrorBadParameter; - - DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p", - bufferAdd, bufferAdd->pBuffer); - /*Return back the output buffer to client*/ - if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true) - { - DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - return OMX_ErrorNone; - } - pending_output_buffers++; - buffer = client_buffers.get_dr_buf_hdr(bufferAdd); - ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate; - if (ptr_respbuffer) - { - ptr_outputbuffer = (struct vdec_bufferpayload*)ptr_respbuffer->client_data; - } - - if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) - { - DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - pending_output_buffers--; - return OMX_ErrorBadParameter; - } - - /* memcpy (&fillbuffer.buffer,ptr_outputbuffer, - sizeof(struct vdec_bufferpayload)); - fillbuffer.client_data = bufferAdd;*/ - -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - // Acquire a write lock on this buffer. - if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle, - GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) { - DEBUG_PRINT_ERROR("Failed to acquire genlock"); - buffer->nFilledLen = 0; - m_cb.FillBufferDone (hComp,m_app_data,buffer); - pending_output_buffers--; - return OMX_ErrorInsufficientResources; - } else { - native_buffer[buffer - m_out_mem_ptr].inuse = true; - } - } -#endif - int rc = 0; - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - memset( (void *)&buf, 0, sizeof(buf)); - memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES)); - int extra_idx = 0; - - buf.index = nPortIndex; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].bytesused = buffer->nFilledLen; - plane[0].length = drv_ctx.op_buf.buffer_size; - plane[0].m.userptr = - (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr - - (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset; - plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd; - plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset; - plane[0].data_offset = 0; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].bytesused = 0; - plane[extra_idx].length = drv_ctx.extradata_info.buffer_size; - plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - buf.m.planes = plane; - buf.length = drv_ctx.num_planes; - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf); - if (rc) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to qbuf to driver"); - } -//#ifdef _ANDROID_ICS_ - // if (m_enable_android_native_buffers) - // { - // Unlock the buffer - // if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { - // DEBUG_PRINT_ERROR("Releasing genlock failed"); - // return OMX_ErrorInsufficientResources; - /// } else { - // native_buffer[buffer - m_out_mem_ptr].inuse = false; - // } - // } -//#endif - //m_cb.FillBufferDone (hComp,m_app_data,buffer); - // pending_output_buffers--; - // return OMX_ErrorBadParameter; - //} - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::SetCallbacks - -DESCRIPTION - Set the callbacks. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_CALLBACKTYPE* callbacks, - OMX_IN OMX_PTR appData) -{ - - m_cb = *callbacks; - DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\ - m_cb.EventHandler,m_cb.FillBufferDone); - m_app_data = appData; - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentDeInit - -DESCRIPTION - Destroys the component and release memory allocated to the heap. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp) -{ -#ifdef _ANDROID_ - if(iDivXDrmDecrypt) - { - delete iDivXDrmDecrypt; - iDivXDrmDecrypt=NULL; - } -#endif //_ANDROID_ - - unsigned i = 0; - if (OMX_StateLoaded != m_state) - { - DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ - m_state); - DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED"); - } - else - { - DEBUG_PRINT_HIGH("\n Playback Ended - PASSED"); - } - - /*Check if the output buffers have to be cleaned up*/ - if(m_out_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing the Output Memory\n"); - for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) - { - free_output_buffer (&m_out_mem_ptr[i]); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - if (native_buffer[i].inuse) - { - if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) { - DEBUG_PRINT_ERROR("Unlocking genlock failed"); - } - native_buffer[i].inuse = false; - } - } -#endif - } -#ifdef _ANDROID_ICS_ - memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS)); -#endif - } - - /*Check if the input buffers have to be cleaned up*/ - if(m_inp_mem_ptr || m_inp_heap_ptr) - { - DEBUG_PRINT_LOW("Freeing the Input Memory\n"); - for (i = 0; i. - -PARAMETERS - . - -RETURN VALUE - Not Implemented error. - -========================================================================== */ -OMX_ERRORTYPE omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN void* eglImage) -{ - OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info; - -#ifdef USE_EGL_IMAGE_GPU - PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc; - EGLint fd = -1, offset = 0,pmemPtr = 0; -#else - int fd = -1, offset = 0; -#endif - DEBUG_PRINT_HIGH("\nuse EGL image support for decoder"); - if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) { - DEBUG_PRINT_ERROR("\n "); - } -#ifdef USE_EGL_IMAGE_GPU - if(m_display_id == NULL) { - DEBUG_PRINT_ERROR("Display ID is not set by IL client \n"); - return OMX_ErrorInsufficientResources; - } - egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC) - eglGetProcAddress("eglQueryImageKHR"); - egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd); - egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset); - egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr); -#else //with OMX test app - struct temp_egl { - int pmem_fd; - int offset; - }; - struct temp_egl *temp_egl_id = NULL; - void * pmemPtr = (void *) eglImage; - temp_egl_id = (struct temp_egl *)eglImage; - if (temp_egl_id != NULL) - { - fd = temp_egl_id->pmem_fd; - offset = temp_egl_id->offset; - } -#endif - if (fd < 0) { - DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d \n",fd); - return OMX_ErrorInsufficientResources; - } - pmem_info.pmem_fd = (OMX_U32) fd; - pmem_info.offset = (OMX_U32) offset; - pmem_entry.entry = (void *) &pmem_info; - pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pmem_list.entryList = &pmem_entry; - pmem_list.nEntries = 1; - ouput_egl_buffers = true; - if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port, - (void *)&pmem_list, drv_ctx.op_buf.buffer_size, - (OMX_U8 *)pmemPtr)) { - DEBUG_PRINT_ERROR("use buffer call failed for egl image\n"); - return OMX_ErrorInsufficientResources; - } - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_vdec::ComponentRoleEnum - -DESCRIPTION - OMX Component Role Enum method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_U8* role, - OMX_IN OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - - else if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE)) - ) - - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) || - (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE)) - ) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_LOW("\n No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } - return eRet; -} - - - - -/* ====================================================================== -FUNCTION - omx_vdec::AllocateDone - -DESCRIPTION - Checks if entire buffer pool is allocated by IL Client or not. - Need this to move to IDLE state. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_vdec::allocate_done(void) -{ - bool bRet = false; - bool bRet_In = false; - bool bRet_Out = false; - - bRet_In = allocate_input_done(); - bRet_Out = allocate_output_done(); - - if(bRet_In && bRet_Out) - { - bRet = true; - } - - return bRet; -} -/* ====================================================================== -FUNCTION - omx_vdec::AllocateInputDone - -DESCRIPTION - Checks if I/P buffer pool is allocated by IL Client or not. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_vdec::allocate_input_done(void) -{ - bool bRet = false; - unsigned i=0; - - if (m_inp_mem_ptr == NULL) - { - return bRet; - } - if(m_inp_mem_ptr ) - { - for(;i= drv_ctx.op_buf.actualcount) - { - DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer); - return OMX_ErrorBadParameter; - } - else if (output_flush_progress) - { - DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer); - buffer->nFilledLen = 0; - buffer->nTimeStamp = 0; - buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ; - buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT; - } - - if (m_debug_extradata) - { - if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) - { - DEBUG_PRINT_HIGH("\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - } - - if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) - { - DEBUG_PRINT_HIGH("\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - } - } - - - DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", - buffer, buffer->pBuffer); - pending_output_buffers --; - - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) - { - DEBUG_PRINT_HIGH("\n Output EOS has been reached"); - if (!output_flush_progress) - post_event((unsigned)NULL, (unsigned)NULL, - OMX_COMPONENT_GENERATE_EOS_DONE); - - if (psource_frame) - { - m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame); - psource_frame = NULL; - } - if (pdest_frame) - { - pdest_frame->nFilledLen = 0; - m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL, - (unsigned)NULL); - pdest_frame = NULL; - } - } - - DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer); -#ifdef OUTPUT_BUFFER_LOG - if (outputBufferFile1 && buffer->nFilledLen) - { - int buf_index = buffer - m_out_mem_ptr; - int stride = drv_ctx.video_resolution.stride; - int scanlines = drv_ctx.video_resolution.scan_lines; - char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; - unsigned i; - int bytes_written = 0; - for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) { - bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); - temp += stride; - } - temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines; - int stride_c = stride; - for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) { - bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1); - temp += stride_c; - } - } -#endif - - /* For use buffer we need to copy the data */ - if (!output_flush_progress) - { - /* This is the error check for non-recoverable errros */ - bool is_duplicate_ts_valid = true; - bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive); - - if (output_capability == V4L2_PIX_FMT_MPEG4 || - output_capability == V4L2_PIX_FMT_MPEG2 || - output_capability == V4L2_PIX_FMT_DIVX || - output_capability == V4L2_PIX_FMT_DIVX_311) - is_duplicate_ts_valid = false; - - if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) { - bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; - if (mbaff) { - is_interlaced = false; - } - } - - if (buffer->nFilledLen > 0) { - time_stamp_dts.get_next_timestamp(buffer, - is_interlaced && is_duplicate_ts_valid); - if (m_debug_timestamp) - { - { - OMX_TICKS expected_ts = 0; - m_timestamp_list.pop_min_ts(expected_ts); - if (is_interlaced && is_duplicate_ts_valid) { - m_timestamp_list.pop_min_ts(expected_ts); - } - DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list", - buffer->nTimeStamp, expected_ts); - - if (buffer->nTimeStamp != expected_ts) { - DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check"); - } - } - } - } else { - m_inp_err_count++; - time_stamp_dts.remove_time_stamp( - buffer->nTimeStamp, - is_interlaced && is_duplicate_ts_valid); - } - - - } - if (m_cb.FillBufferDone) - { - if (buffer->nFilledLen > 0) - { - handle_extradata(buffer); - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - set_frame_rate(buffer->nTimeStamp); - else if (arbitrary_bytes) - adjust_timestamp(buffer->nTimeStamp); - if (perf_flag) - { - if (!proc_frms) - { - dec_time.stop(); - latency = dec_time.processing_time_us() - latency; - DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3); - dec_time.start(); - fps_metrics.start(); - } - proc_frms++; - if (buffer->nFlags & OMX_BUFFERFLAG_EOS) - { - OMX_U64 proc_time = 0; - fps_metrics.stop(); - proc_time = fps_metrics.processing_time_us(); - DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)", - proc_frms, (float)proc_time / 1e6, - (float)(1e6 * proc_frms) / proc_time); - proc_frms = 0; - } - } - -#ifdef OUTPUT_EXTRADATA_LOG - if (outputExtradataFile) - { - - OMX_OTHER_EXTRADATATYPE *p_extra = NULL; - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(buffer->pBuffer + buffer->nOffset + - buffer->nFilledLen + 3)&(~3)); - while(p_extra && - (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) - { - DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType); - fwrite (p_extra,1,p_extra->nSize,outputExtradataFile); - if (p_extra->eType == OMX_ExtraDataNone) - { - break; - } - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - } -#endif - } - if (buffer->nFlags & OMX_BUFFERFLAG_EOS){ - prev_ts = LLONG_MAX; - rst_prev_ts = true; - } - - pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) - buffer->pPlatformPrivate)->entryList->entry; - DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd); -#ifdef _ANDROID_ICS_ - if (m_enable_android_native_buffers) - { - if (native_buffer[buffer - m_out_mem_ptr].inuse) { - if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) { - DEBUG_PRINT_ERROR("Unlocking genlock failed"); - return OMX_ErrorInsufficientResources; - } - else { - native_buffer[buffer - m_out_mem_ptr].inuse = false; - } - } - } -#endif - OMX_BUFFERHEADERTYPE *il_buffer; - il_buffer = client_buffers.get_il_buf_hdr(buffer); - if (il_buffer) - m_cb.FillBufferDone (hComp,m_app_data,il_buffer); - else { - DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr"); - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd); - } - else - { - return OMX_ErrorBadParameter; - } - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE* buffer) -{ - - if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) - { - DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer); - return OMX_ErrorBadParameter; - } - - DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p", - buffer, buffer->pBuffer); - pending_input_buffers--; - - if (arbitrary_bytes) - { - if (pdest_frame == NULL && input_flush_progress == false) - { - DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer); - pdest_frame = buffer; - buffer->nFilledLen = 0; - buffer->nTimeStamp = LLONG_MAX; - push_input_buffer (hComp); - } - else - { - DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer); - buffer->nFilledLen = 0; - if (!m_input_free_q.insert_entry((unsigned)buffer, - (unsigned)NULL, (unsigned)NULL)) - { - DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error"); - } - } - } - else if(m_cb.EmptyBufferDone) - { - buffer->nFilledLen = 0; - if (input_use_buffer == true){ - buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr]; - } - m_cb.EmptyBufferDone(hComp ,m_app_data, buffer); - } - return OMX_ErrorNone; -} - -int omx_vdec::async_message_process (void *context, void* message) -{ - omx_vdec* omx = NULL; - struct vdec_msginfo *vdec_msg = NULL; - OMX_BUFFERHEADERTYPE* omxhdr = NULL; - struct v4l2_buffer *v4l2_buf_ptr = NULL; - struct vdec_output_frameinfo *output_respbuf = NULL; - int rc=1; - if (context == NULL || message == NULL) - { - DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check"); - return -1; - } - vdec_msg = (struct vdec_msginfo *)message; - - omx = reinterpret_cast(context); - - switch (vdec_msg->msgcode) - { - - case VDEC_MSG_EVT_HW_ERROR: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_HARDWARE_ERROR); - break; - - case VDEC_MSG_RESP_START_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_START_DONE); - break; - - case VDEC_MSG_RESP_STOP_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - break; - - case VDEC_MSG_RESP_RESUME_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_RESUME_DONE); - break; - - case VDEC_MSG_RESP_PAUSE_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_PAUSE_DONE); - break; - - case VDEC_MSG_RESP_FLUSH_INPUT_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); - break; - case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: - omx->post_event ((unsigned)NULL, vdec_msg->status_code,\ - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); - break; - case VDEC_MSG_RESP_INPUT_FLUSHED: - case VDEC_MSG_RESP_INPUT_BUFFER_DONE: - - /* omxhdr = (OMX_BUFFERHEADERTYPE* ) - vdec_msg->msgdata.input_frame_clientdata; */ - - v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata; - omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index; - if (omxhdr == NULL || - ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) - { - omxhdr = NULL; - vdec_msg->status_code = VDEC_S_EFATAL; - } - - omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code, - OMX_COMPONENT_GENERATE_EBD); - break; - case VDEC_MSG_EVT_INFO_FIELD_DROPPED: - int64_t *timestamp; - timestamp = (int64_t *) malloc(sizeof(int64_t)); - if (timestamp) { - *timestamp = vdec_msg->msgdata.output_frame.time_stamp; - omx->post_event ((unsigned int)timestamp, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED); - DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld", - vdec_msg->msgdata.output_frame.time_stamp); - } - break; - case VDEC_MSG_RESP_OUTPUT_FLUSHED: - case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: - - v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data; - omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index; - DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)", - omxhdr, vdec_msg->msgdata.output_frame.time_stamp, - vdec_msg->msgdata.output_frame.pic_type); - - if (omxhdr && omxhdr->pOutputPortPrivate && - ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) && - (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate - - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) - { - if ( vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen) - { - omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len; - omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset; - omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp; - omxhdr->nFlags = 0; - - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) - { - omxhdr->nFlags |= OMX_BUFFERFLAG_EOS; - //rc = -1; - } - if (omxhdr->nFilledLen) - { - omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME; - } - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) - { - omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; - } - else - { - omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME; - } - if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) - { - omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - } - if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) - { - omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY; - } - if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) && - !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) && - !(v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)) - { - omx->post_event ((unsigned)NULL,(unsigned int)omxhdr, - OMX_COMPONENT_GENERATE_FTB); - break; - } - if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) - { - omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; - } - vdec_msg->msgdata.output_frame.bufferaddr = - omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr; - int format_notably_changed = 0; - if (omxhdr->nFilledLen && - (omxhdr->nFilledLen != omx->prev_n_filled_len)) - { - if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) || - (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) { - DEBUG_PRINT_HIGH("\n Height/Width information has changed\n"); - omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom; - omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right; - format_notably_changed = 1; - } - } - if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft != - vdec_msg->msgdata.output_frame.framesize.left) - || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top) - || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right) - || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) { - if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) || - (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) { - omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom; - omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right; - DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n", - omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right, - omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom); - } - DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n", - omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right, - omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom); - omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left; - omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top; - omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right; - omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom; - format_notably_changed = 1; - } - if (format_notably_changed) { - if(omx->is_video_session_supported()) { - omx->post_event (NULL, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING); - } else { - if (!omx->client_buffers.update_buffer_req()) { - DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); - } - omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop, - OMX_COMPONENT_GENERATE_PORT_RECONFIG); - } - } - if (omxhdr->nFilledLen) - omx->prev_n_filled_len = omxhdr->nFilledLen; - - output_respbuf = (struct vdec_output_frameinfo *)\ - omxhdr->pOutputPortPrivate; - output_respbuf->len = vdec_msg->msgdata.output_frame.len; - output_respbuf->offset = vdec_msg->msgdata.output_frame.offset; - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) - { - output_respbuf->pic_type = PICTURE_TYPE_I; - } - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) - { - output_respbuf->pic_type = PICTURE_TYPE_P; - } - if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) { - output_respbuf->pic_type = PICTURE_TYPE_B; - } - - if (omx->output_use_buffer) - memcpy ( omxhdr->pBuffer, (void *) - ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr + - (unsigned long)vdec_msg->msgdata.output_frame.offset), - vdec_msg->msgdata.output_frame.len); - } - else - omxhdr->nFilledLen = 0; - omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_FBD); - } - else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) - omx->post_event ((unsigned int)NULL, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_EOS_DONE); - else - omx->post_event ((unsigned int)NULL, vdec_msg->status_code, - OMX_COMPONENT_GENERATE_HARDWARE_ERROR); - break; - case VDEC_MSG_EVT_CONFIG_CHANGED: - DEBUG_PRINT_HIGH("\n Port settings changed"); - omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition, - OMX_COMPONENT_GENERATE_PORT_RECONFIG); - break; - default: - break; - } - return rc; -} - -OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary ( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ) -{ - unsigned address,p2,id; - DEBUG_PRINT_LOW("\n Empty this arbitrary"); - - if (buffer == NULL) - { - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer); - DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld", - buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp); - - /* return zero length and not an EOS buffer */ - /* return buffer if input flush in progress */ - if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) && - ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) - { - DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress"); - m_cb.EmptyBufferDone (hComp,m_app_data,buffer); - return OMX_ErrorNone; - } - - if (psource_frame == NULL) - { - DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp); - psource_frame = buffer; - DEBUG_PRINT_LOW("\n Try to Push One Input Buffer "); - push_input_buffer (hComp); - } - else - { - DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer); - if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL, - (unsigned)NULL)) - { - return OMX_ErrorBadParameter; - } - } - - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp) -{ - unsigned address,p2,id; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if (pdest_frame == NULL || psource_frame == NULL) - { - /*Check if we have a destination buffer*/ - if (pdest_frame == NULL) - { - DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue"); - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *)address; - pdest_frame->nFilledLen = 0; - pdest_frame->nTimeStamp = LLONG_MAX; - DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame); - } - } - - /*Check if we have a destination buffer*/ - if (psource_frame == NULL) - { - DEBUG_PRINT_LOW("\n Get a source buffer from the queue"); - if (m_input_pending_q.m_size) - { - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *)address; - DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame, - psource_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu", - psource_frame->nFlags,psource_frame->nFilledLen); - - } - } - - } - - while ((pdest_frame != NULL) && (psource_frame != NULL)) - { - switch (codec_type_parse) - { - case CODEC_TYPE_MPEG4: - case CODEC_TYPE_H263: - case CODEC_TYPE_MPEG2: - ret = push_input_sc_codec(hComp); - break; - case CODEC_TYPE_H264: - ret = push_input_h264(hComp); - break; - case CODEC_TYPE_VC1: - ret = push_input_vc1(hComp); - break; - default: - break; - } - if (ret != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed"); - omx_report_error (); - break; - } - } - - return ret; -} - -OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp) -{ - OMX_U32 partial_frame = 1; - OMX_BOOL generate_ebd = OMX_TRUE; - unsigned address = 0, p2 = 0, id = 0; - - DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld", - psource_frame,psource_frame->nTimeStamp); - if (m_frame_parser.parse_sc_frame(psource_frame, - pdest_frame,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); - return OMX_ErrorBadParameter; - } - - if (partial_frame == 0) - { - DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d", - pdest_frame->nFilledLen,psource_frame,frame_count); - - - DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp); - /*First Parsed buffer will have only header Hence skip*/ - if (frame_count == 0) - { - DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame "); - - if(codec_type_parse == CODEC_TYPE_MPEG4 || - codec_type_parse == CODEC_TYPE_DIVX) { - mp4StreamType psBits; - psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset; - psBits.numBytes = pdest_frame->nFilledLen; - mp4_headerparser.parseHeader(&psBits); - } - - frame_count++; - } - else - { - pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; - if(pdest_frame->nFilledLen) - { - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *) address; - pdest_frame->nFilledLen = 0; - } - } - else if(!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) - { - DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL"); - m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL, - (unsigned)NULL); - pdest_frame = NULL; - } - } - } - else - { - DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen); - /*Check if Destination Buffer is full*/ - if (pdest_frame->nAllocLen == - pdest_frame->nFilledLen + pdest_frame->nOffset) - { - DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled"); - return OMX_ErrorStreamCorrupt; - } - } - - if (psource_frame->nFilledLen == 0) - { - if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) - { - if (pdest_frame) - { - pdest_frame->nFlags |= psource_frame->nFlags; - DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d", - pdest_frame->nFilledLen,frame_count++); - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - } - else - { - DEBUG_PRINT_LOW("\n Last frame in else dest addr") ; - generate_ebd = OMX_FALSE; - } - } - if(generate_ebd) - { - DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame); - m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); - psource_frame = NULL; - - if (m_input_pending_q.m_size) - { - DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame, - psource_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu", - psource_frame->nFlags,psource_frame->nFilledLen); - } - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp) -{ - OMX_U32 partial_frame = 1; - unsigned address = 0, p2 = 0, id = 0; - OMX_BOOL isNewFrame = OMX_FALSE; - OMX_BOOL generate_ebd = OMX_TRUE; - - if (h264_scratch.pBuffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated"); - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu " - "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal); - DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen); - if (h264_scratch.nFilledLen && look_ahead_nal) - { - look_ahead_nal = false; - if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame"); - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - if (nal_length == 0) - { - DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code"); - if (m_frame_parser.parse_sc_frame(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing Return Error"); - return OMX_ErrorBadParameter; - } - } - else - { - DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length); - if (m_frame_parser.parse_h264_nallength(psource_frame, - &h264_scratch,&partial_frame) == -1) - { - DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error"); - return OMX_ErrorBadParameter; - } - } - - if (partial_frame == 0) - { - if (nal_count == 0 && h264_scratch.nFilledLen == 0) - { - DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip"); - nal_count++; - h264_scratch.nTimeStamp = psource_frame->nTimeStamp; - h264_scratch.nFlags = psource_frame->nFlags; - } - else - { - DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen); - if(h264_scratch.nFilledLen) - { - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen, - NALU_TYPE_SPS); -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, - h264_scratch.nFilledLen, NALU_TYPE_SEI); - else if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - // If timeinfo is present frame info from SEI is already processed - h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, - h264_scratch.nFilledLen, NALU_TYPE_SEI); -#endif - m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame); - nal_count++; - if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) { - pdest_frame->nTimeStamp = h264_last_au_ts; - pdest_frame->nFlags = h264_last_au_flags; -#ifdef PANSCAN_HDLR - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - h264_parser->update_panscan_data(h264_last_au_ts); -#endif - } - if(m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR || - m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) { - h264_last_au_ts = h264_scratch.nTimeStamp; - h264_last_au_flags = h264_scratch.nFlags; -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts); - if (!VALID_TS(h264_last_au_ts)) - h264_last_au_ts = ts_in_sei; - } -#endif - } else - h264_last_au_ts = LLONG_MAX; - } - - if (!isNewFrame) - { - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu", - h264_scratch.nFilledLen); - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - if(m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ) - pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - else - { - look_ahead_nal = true; - DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d", - pdest_frame->nFilledLen,frame_count++); - - if (pdest_frame->nFilledLen == 0) - { - DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it"); - look_ahead_nal = false; - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - } - else - { - if(psource_frame->nFilledLen || h264_scratch.nFilledLen) - { - DEBUG_PRINT_LOW("\n Reset the EOS Flag"); - pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS; - } - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - //frame_count++; - pdest_frame = NULL; - if (m_input_free_q.m_size) - { - m_input_free_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame); - pdest_frame->nFilledLen = 0; - pdest_frame->nFlags = 0; - pdest_frame->nTimeStamp = LLONG_MAX; - } - } - } - } - } - else - { - DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen); - /*Check if Destination Buffer is full*/ - if (h264_scratch.nAllocLen == - h264_scratch.nFilledLen + h264_scratch.nOffset) - { - DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled"); - return OMX_ErrorStreamCorrupt; - } - } - - if (!psource_frame->nFilledLen) - { - DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame); - - if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) - { - if (pdest_frame) - { - DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer"); - if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >= - h264_scratch.nFilledLen) - { - memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen), - h264_scratch.pBuffer,h264_scratch.nFilledLen); - pdest_frame->nFilledLen += h264_scratch.nFilledLen; - h264_scratch.nFilledLen = 0; - } - else - { - DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264"); - return OMX_ErrorBadParameter; - } - pdest_frame->nTimeStamp = h264_scratch.nTimeStamp; - pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags; - - DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx", - pdest_frame->nFilledLen,pdest_frame->nTimeStamp); - DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++); -#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT - if (client_extradata & OMX_TIMEINFO_EXTRADATA) - { - OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp); - if (!VALID_TS(pdest_frame->nTimeStamp)) - pdest_frame->nTimeStamp = ts_in_sei; - } -#endif - /*Push the frame to the Decoder*/ - if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) - { - return OMX_ErrorBadParameter; - } - frame_count++; - pdest_frame = NULL; - } - else - { - DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu", - pdest_frame,h264_scratch.nFilledLen); - generate_ebd = OMX_FALSE; - } - } - } - if(generate_ebd && !psource_frame->nFilledLen) - { - m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame); - psource_frame = NULL; - if (m_input_pending_q.m_size) - { - DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame); - m_input_pending_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE *) address; - DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu", - psource_frame->nFlags,psource_frame->nFilledLen); - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp) -{ - OMX_U8 *buf, *pdest; - OMX_U32 partial_frame = 1; - OMX_U32 buf_len, dest_len; - - if(first_frame == 0) - { - first_frame = 1; - DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n"); - if(!m_vendor_config.pData) - { - DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n"); - buf = psource_frame->pBuffer; - buf_len = psource_frame->nFilledLen; - - if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) == - VC1_SP_MP_START_CODE) - { - m_vc1_profile = VC1_SP_MP_RCV; - } - else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) - { - m_vc1_profile = VC1_AP; - } - else - { - DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n"); - return OMX_ErrorStreamCorrupt; - } - } - else - { - pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen + - pdest_frame->nOffset; - dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen + - pdest_frame->nOffset); - - if(dest_len < m_vendor_config.nDataSize) - { - DEBUG_PRINT_ERROR("\nDestination buffer full\n"); - return OMX_ErrorBadParameter; - } - else - { - memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize); - pdest_frame->nFilledLen += m_vendor_config.nDataSize; - } - } - } - - switch(m_vc1_profile) - { - case VC1_AP: - DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code"); - if (push_input_sc_codec(hComp) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code"); - return OMX_ErrorBadParameter; - } - break; - - case VC1_SP_MP_RCV: - default: - DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n"); - return OMX_ErrorBadParameter; - } - return OMX_ErrorNone; -} - -#ifndef USE_ION -bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, - OMX_U32 alignment) -{ - struct pmem_allocation allocation; - allocation.size = buffer_size; - allocation.align = clip2(alignment); - if (allocation.align < 4096) - { - allocation.align = 4096; - } - if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) - { - DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", - allocation.align, allocation.size); - return false; - } - return true; -} -#endif -#ifdef USE_ION -int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size, - OMX_U32 alignment, struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data, int flag) -{ - int fd = -EINVAL; - int rc = -EINVAL; - int ion_dev_flag; - struct vdec_ion ion_buf_info; - if (!alloc_data || buffer_size <= 0 || !fd_data) { - DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n"); - return -EINVAL; - } - ion_dev_flag = O_RDONLY; - fd = open (MEM_DEVICE, ion_dev_flag); - if (fd < 0) { - DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd); - return fd; - } - alloc_data->flags = 0; - if(!secure_mode && (flag & ION_FLAG_CACHED)) - { - alloc_data->flags |= ION_FLAG_CACHED; - } - alloc_data->len = buffer_size; - alloc_data->align = clip2(alignment); - if (alloc_data->align < 4096) - { - alloc_data->align = 4096; - } - if ((secure_mode) && (flag & ION_SECURE)) - alloc_data->flags |= ION_SECURE; - - alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID); - if (secure_mode) - alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); - rc = ioctl(fd,ION_IOC_ALLOC,alloc_data); - if (rc || !alloc_data->handle) { - DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); - alloc_data->handle = NULL; - close(fd); - fd = -ENOMEM; - return fd; - } - fd_data->handle = alloc_data->handle; - rc = ioctl(fd,ION_IOC_MAP,fd_data); - if (rc) { - DEBUG_PRINT_ERROR("\n ION MAP failed "); - ion_buf_info.ion_alloc_data = *alloc_data; - ion_buf_info.ion_device_fd = fd; - ion_buf_info.fd_ion_data = *fd_data; - free_ion_memory(&ion_buf_info); - fd_data->fd =-1; - close(fd); - fd = -ENOMEM; - } - - return fd; -} - -void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info) { - - if(!buf_ion_info) { - DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata"); - return; - } - if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, - &buf_ion_info->ion_alloc_data.handle)) { - DEBUG_PRINT_ERROR("\n ION: free failed" ); - } - close(buf_ion_info->ion_device_fd); - buf_ion_info->ion_device_fd = -1; - buf_ion_info->ion_alloc_data.handle = NULL; - buf_ion_info->fd_ion_data.fd = -1; -} -#endif -void omx_vdec::free_output_buffer_header() -{ - DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released"); - output_use_buffer = false; - ouput_egl_buffers = false; - - if (m_out_mem_ptr) - { - free (m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - - if(m_platform_list) - { - free(m_platform_list); - m_platform_list = NULL; - } - - if (drv_ctx.ptr_respbuffer) - { - free (drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } - if (drv_ctx.ptr_outputbuffer) - { - free (drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif -} - -void omx_vdec::free_input_buffer_header() -{ - input_use_buffer = false; - if (arbitrary_bytes) - { - if (m_frame_parser.mutils) - { - DEBUG_PRINT_LOW("\n Free utils parser"); - delete (m_frame_parser.mutils); - m_frame_parser.mutils = NULL; - } - - if (m_inp_heap_ptr) - { - DEBUG_PRINT_LOW("\n Free input Heap Pointer"); - free (m_inp_heap_ptr); - m_inp_heap_ptr = NULL; - } - - if (m_phdr_pmem_ptr) - { - DEBUG_PRINT_LOW("\n Free input pmem header Pointer"); - free (m_phdr_pmem_ptr); - m_phdr_pmem_ptr = NULL; - } - } - if (m_inp_mem_ptr) - { - DEBUG_PRINT_LOW("\n Free input pmem Pointer area"); - free (m_inp_mem_ptr); - m_inp_mem_ptr = NULL; - } - if (drv_ctx.ptr_inputbuffer) - { - DEBUG_PRINT_LOW("\n Free Driver Context pointer"); - free (drv_ctx.ptr_inputbuffer); - drv_ctx.ptr_inputbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.ip_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free ion context"); - free(drv_ctx.ip_buf_ion_info); - drv_ctx.ip_buf_ion_info = NULL; - } -#endif -} - -int omx_vdec::stream_off(OMX_U32 port) -{ - enum v4l2_buf_type btype; - int rc = 0; - enum v4l2_ports v4l2_port = OUTPUT_PORT; - - if (port == OMX_CORE_INPUT_PORT_INDEX) { - btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - v4l2_port = OUTPUT_PORT; - } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) { - btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - v4l2_port = CAPTURE_PORT; - } else if (port == OMX_ALL) { - int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX); - int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX); - - if (!rc_input) - return rc_input; - else - return rc_output; - } - - if (!streaming[v4l2_port]) { - // already streamed off, warn and move on - DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port," - " which is already streamed off", v4l2_port); - return 0; - } - - DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port); - - rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype); - if (rc) { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port); - } else { - streaming[v4l2_port] = false; - } - - return rc; -} - -OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_requestbuffers bufreq; - unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; - struct v4l2_format fmt; - int ret = 0; - DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = 1; - if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ - bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.pixelformat = output_capability; - }else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT){ - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.pixelformat = capture_capability; - }else {eRet = OMX_ErrorBadParameter;} - if(eRet==OMX_ErrorNone){ - ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); - } - if(ret) - { - DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); - /*TODO: How to handle this case */ - eRet = OMX_ErrorInsufficientResources; - return eRet; - } - else - { - buffer_prop->actualcount = bufreq.count; - buffer_prop->mincount = bufreq.count; - DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count); - } - DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt); - - update_resolution(fmt.fmt.pix_mp.width, - fmt.fmt.pix_mp.height, - fmt.fmt.pix_mp.plane_fmt[0].bytesperline, - fmt.fmt.pix_mp.plane_fmt[0].reserved[0]); - if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) - drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes; - DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage); - - if(ret) - { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Requesting buffer requirements failed"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - int extra_idx = 0; - - eRet = is_video_session_supported(); - if (eRet) - return eRet; - - buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - buf_size = buffer_prop->buffer_size; - extra_idx = EXTRADATA_IDX(drv_ctx.num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - if (client_extradata & OMX_FRAMEINFO_EXTRADATA) - { - DEBUG_PRINT_HIGH("Frame info extra data enabled!"); - client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE; - } - if (client_extradata & OMX_INTERLACE_EXTRADATA) - { - client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE; - } - if (client_extradata & OMX_PORTDEF_EXTRADATA) - { - client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE; - DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n", - client_extra_data_size); - } - if (client_extra_data_size) - { - client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator - buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit - } - drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size; - drv_ctx.extradata_info.count = buffer_prop->actualcount; - drv_ctx.extradata_info.buffer_size = extra_data_size; - buf_size += client_extra_data_size; - buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); - DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size, buf_size); - if (in_reconfig) // BufReq will be set to driver when port is disabled - buffer_prop->buffer_size = buf_size; - else if (buf_size != buffer_prop->buffer_size) - { - buffer_prop->buffer_size = buf_size; - eRet = set_buffer_req(buffer_prop); - } - } - DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - return eRet; -} - -OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned buf_size = 0; - struct v4l2_format fmt; - struct v4l2_requestbuffers bufreq; - int ret; - DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)", - buffer_prop->actualcount, buffer_prop->buffer_size); - buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1)); - if (buf_size != buffer_prop->buffer_size) - { - DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)", - buffer_prop->buffer_size, buf_size); - eRet = OMX_ErrorBadParameter; - } - else - { - fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height; - fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width; - - if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT){ - fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.pixelformat = output_capability; - } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { - fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.pixelformat = capture_capability; - } else {eRet = OMX_ErrorBadParameter;} - - ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt); - if (ret) - { - /*TODO: How to handle this case */ - DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret); - eRet = OMX_ErrorInsufficientResources; - } - - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = buffer_prop->actualcount; - if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) { - bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) { - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - } else {eRet = OMX_ErrorBadParameter;} - - if (eRet==OMX_ErrorNone) { - ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq); - } - - if (ret) - { - DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret); - /*TODO: How to handle this case */ - eRet = OMX_ErrorInsufficientResources; - } else if (bufreq.count < buffer_prop->actualcount) { - DEBUG_PRINT_ERROR("Driver refused to change the number of buffers" - " on v4l2 port %d to %d (prefers %d)", bufreq.type, - buffer_prop->actualcount, bufreq.count); - eRet = OMX_ErrorInsufficientResources; - } else { - if (!client_buffers.update_buffer_req()) { - DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed"); - eRet = OMX_ErrorInsufficientResources; - } - } - } - return eRet; -} - -OMX_ERRORTYPE omx_vdec::update_picture_resolution() -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - return eRet; -} - -OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (!portDefn) - { - return OMX_ErrorBadParameter; - } - DEBUG_PRINT_LOW("omx_vdec::update_portdef\n"); - portDefn->nVersion.nVersion = OMX_SPEC_VERSION; - portDefn->nSize = sizeof(portDefn); - portDefn->eDomain = OMX_PortDomainVideo; - if (drv_ctx.frame_rate.fps_denominator > 0) - portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator / - drv_ctx.frame_rate.fps_denominator; - else { - DEBUG_PRINT_ERROR("Error: Divide by zero \n"); - return OMX_ErrorBadParameter; - } - if (0 == portDefn->nPortIndex) - { - portDefn->eDir = OMX_DirInput; - portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount; - portDefn->nBufferCountMin = drv_ctx.ip_buf.mincount; - portDefn->nBufferSize = drv_ctx.ip_buf.buffer_size; - portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused; - portDefn->format.video.eCompressionFormat = eCompressionFormat; - portDefn->bEnabled = m_inp_bEnabled; - portDefn->bPopulated = m_inp_bPopulated; - } - else if (1 == portDefn->nPortIndex) - { - unsigned int buf_size = 0; - if (!client_buffers.update_buffer_req()) { - DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed"); - return OMX_ErrorHardware; - } - if (!client_buffers.get_buffer_req(buf_size)) { - DEBUG_PRINT_ERROR("\n update buffer requirements"); - return OMX_ErrorHardware; - } - portDefn->nBufferSize = buf_size; - portDefn->eDir = OMX_DirOutput; - portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount; - portDefn->nBufferCountMin = drv_ctx.op_buf.mincount; - portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - portDefn->bEnabled = m_out_bEnabled; - portDefn->bPopulated = m_out_bPopulated; - if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) { - DEBUG_PRINT_ERROR("\n Error in getting color format"); - return OMX_ErrorHardware; - } - } - else - { - portDefn->eDir = OMX_DirMax; - DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - portDefn->format.video.nFrameHeight = drv_ctx.video_resolution.frame_height; - portDefn->format.video.nFrameWidth = drv_ctx.video_resolution.frame_width; - portDefn->format.video.nStride = drv_ctx.video_resolution.stride; - portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines; - DEBUG_PRINT_ERROR("update_portdef Width = %lu Height = %lu Stride = %ld" - " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight, - portDefn->format.video.nStride, - portDefn->format.video.nSliceHeight); - return eRet; - -} - -OMX_ERRORTYPE omx_vdec::allocate_output_headers() -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr = NULL; - unsigned i= 0; - - if(!m_out_mem_ptr) { - DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation"); - int nBufHdrSize = 0; - int nPlatformEntrySize = 0; - int nPlatformListSize = 0; - int nPMEMInfoSize = 0; - OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList; - OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo; - - DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n", - drv_ctx.op_buf.actualcount); - nBufHdrSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_BUFFERHEADERTYPE); - - nPMEMInfoSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO); - nPlatformListSize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST); - nPlatformEntrySize = drv_ctx.op_buf.actualcount * - sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY); - - DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize, - sizeof(OMX_BUFFERHEADERTYPE), - nPMEMInfoSize, - nPlatformListSize); - DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize, - m_out_bm_count); - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - // Alloc mem for platform specific info - char *pPtr=NULL; - pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize + - nPMEMInfoSize,1); - drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \ - calloc (sizeof(struct vdec_bufferpayload), - drv_ctx.op_buf.actualcount); - drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo *)\ - calloc (sizeof (struct vdec_output_frameinfo), - drv_ctx.op_buf.actualcount); -#ifdef USE_ION - drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \ - calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount); -#endif - - if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer - && drv_ctx.ptr_respbuffer) - { - bufHdr = m_out_mem_ptr; - m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr); - m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) - (((char *) m_platform_list) + nPlatformListSize); - m_pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - (((char *) m_platform_entry) + nPlatformEntrySize); - pPlatformList = m_platform_list; - pPlatformEntry = m_platform_entry; - pPMEMInfo = m_pmem_info; - - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); - - // Settting the entire storage nicely - DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, - m_out_mem_ptr,pPlatformEntry); - DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo); - for(i=0; i < drv_ctx.op_buf.actualcount ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = 0; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = NULL; - bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - pPlatformEntry->type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pPlatformEntry->entry = pPMEMInfo; - // Initialize the Platform List - pPlatformList->nEntries = 1; - pPlatformList->entryList = pPlatformEntry; - // Keep pBuffer NULL till vdec is opened - bufHdr->pBuffer = NULL; - pPMEMInfo->offset = 0; - pPMEMInfo->pmem_fd = 0; - bufHdr->pPlatformPrivate = pPlatformList; - drv_ctx.ptr_outputbuffer[i].pmem_fd = -1; -#ifdef USE_ION - drv_ctx.op_buf_ion_info[i].ion_device_fd =-1; -#endif - /*Create a mapping between buffers*/ - bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i]; - drv_ctx.ptr_respbuffer[i].client_data = (void *) \ - &drv_ctx.ptr_outputbuffer[i]; - // Move the buffer and buffer header pointers - bufHdr++; - pPMEMInfo++; - pPlatformEntry++; - pPlatformList++; - } - } - else - { - DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\ - m_out_mem_ptr, pPtr); - if(m_out_mem_ptr) - { - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(pPtr) - { - free(pPtr); - pPtr = NULL; - } - if(drv_ctx.ptr_outputbuffer) - { - free(drv_ctx.ptr_outputbuffer); - drv_ctx.ptr_outputbuffer = NULL; - } - if(drv_ctx.ptr_respbuffer) - { - free(drv_ctx.ptr_respbuffer); - drv_ctx.ptr_respbuffer = NULL; - } -#ifdef USE_ION - if (drv_ctx.op_buf_ion_info) { - DEBUG_PRINT_LOW("\n Free o/p ion context"); - free(drv_ctx.op_buf_ion_info); - drv_ctx.op_buf_ion_info = NULL; - } -#endif - eRet = OMX_ErrorInsufficientResources; - } - } else { - eRet = OMX_ErrorInsufficientResources; - } - return eRet; -} - -void omx_vdec::complete_pending_buffer_done_cbs() -{ - unsigned p1; - unsigned p2; - unsigned ident; - omx_cmd_queue tmp_q, pending_bd_q; - pthread_mutex_lock(&m_lock); - // pop all pending GENERATE FDB from ftb queue - while (m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_FBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to ftb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_ftb_q.insert_entry(p1,p2,ident); - } - // pop all pending GENERATE EDB from etb queue - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_EBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to etb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_etb_q.insert_entry(p1,p2,ident); - } - pthread_mutex_unlock(&m_lock); - // process all pending buffer dones - while(pending_bd_q.m_size) - { - pending_bd_q.pop_entry(&p1,&p2,&ident); - switch(ident) - { - case OMX_COMPONENT_GENERATE_EBD: - if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); - omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FBD: - if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); - omx_report_error (); - } - break; - } - } -} - -void omx_vdec::set_frame_rate(OMX_S64 act_timestamp) -{ - OMX_U32 new_frame_interval = 0; - if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts - && llabs(act_timestamp - prev_ts) > 2000) - { - new_frame_interval = client_set_fps ? frm_int : - llabs(act_timestamp - prev_ts); - if (new_frame_interval < frm_int || frm_int == 0) - { - frm_int = new_frame_interval; - if(frm_int) - { - drv_ctx.frame_rate.fps_numerator = 1e6; - drv_ctx.frame_rate.fps_denominator = frm_int; - DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)", - frm_int, drv_ctx.frame_rate.fps_numerator / - (float)drv_ctx.frame_rate.fps_denominator); - - /* We need to report the difference between this FBD and the previous FBD - * back to the driver for clock scaling purposes. */ - struct v4l2_outputparm oparm; - /*XXX: we're providing timing info as seconds per frame rather than frames - * per second.*/ - oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator; - oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator; - - struct v4l2_streamparm sparm; - sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - sparm.parm.output = oparm; - if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) - { - DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \ - performance might be affected"); - } - - } - } - } - prev_ts = act_timestamp; -} - -void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp) -{ - if (rst_prev_ts && VALID_TS(act_timestamp)) - { - prev_ts = act_timestamp; - rst_prev_ts = false; - } - else if (VALID_TS(prev_ts)) - { - bool codec_cond = (drv_ctx.timestamp_adjust)? - (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)? - (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)): - (!VALID_TS(act_timestamp) || act_timestamp == prev_ts); - if(frm_int > 0 && codec_cond) - { - DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp); - act_timestamp = prev_ts + frm_int; - DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp); - prev_ts = act_timestamp; - } - else - set_frame_rate(act_timestamp); - } - else if (frm_int > 0) // In this case the frame rate was set along - { // with the port definition, start ts with 0 - act_timestamp = prev_ts = 0; // and correct if a valid ts is received. - rst_prev_ts = true; - } -} - -void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr) -{ - OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL; - OMX_U32 num_conceal_MB = 0; - OMX_U32 frame_rate = 0; - int consumed_len = 0; - OMX_U32 num_MB_in_frame; - OMX_U32 recovery_sei_flags = 1; - int enable = 0; - OMX_U32 mbaff = 0; - int buf_index = p_buf_hdr - m_out_mem_ptr; - struct msm_vidc_panscan_window_payload *panscan_payload = NULL; - OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) + - p_buf_hdr->nOffset; - if (!drv_ctx.extradata_info.uaddr) { - return; - } - p_extra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3)); - char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size; - if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen)) - p_extra = NULL; - OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata; - if (data) { - while((consumed_len < drv_ctx.extradata_info.buffer_size) - && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) { - if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) { - DEBUG_PRINT_LOW("Invalid extra data size"); - break; - } - switch((unsigned long)data->eType) { - case EXTRADATA_INTERLACE_VIDEO: - struct msm_vidc_interlace_payload *payload; - payload = (struct msm_vidc_interlace_payload *)data->data; - mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; - if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; - else { - drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; - enable = 1; - } - if(m_enable_android_native_buffers) - setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle, - PP_PARAM_INTERLACED, (void*)&enable); - if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) { - append_interlace_extradata(p_extra, payload->format); - p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize); - } - break; - case EXTRADATA_FRAME_RATE: - struct msm_vidc_framerate_payload *frame_rate_payload; - frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data; - frame_rate = frame_rate_payload->frame_rate; - break; - case EXTRADATA_TIMESTAMP: - struct msm_vidc_ts_payload *time_stamp_payload; - time_stamp_payload = (struct msm_vidc_ts_payload *)data->data; - p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo; - p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32); - break; - case EXTRADATA_NUM_CONCEALED_MB: - struct msm_vidc_concealmb_payload *conceal_mb_payload; - conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data; - num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * - (drv_ctx.video_resolution.frame_height + 15)) >> 8; - num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0); - break; - case EXTRADATA_INDEX: - int *etype; - etype = (int *)(data->data); - if (etype && *etype == EXTRADATA_ASPECT_RATIO) { - struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload; - aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype); - if (aspect_ratio_payload) { - ((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width; - ((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height; - } - } - break; - case EXTRADATA_RECOVERY_POINT_SEI: - struct msm_vidc_recoverysei_payload *recovery_sei_payload; - recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data; - recovery_sei_flags = recovery_sei_payload->flags; - if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT; - DEBUG_PRINT_HIGH("\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); - DEBUG_PRINT_HIGH("***************************************************\n"); - } - break; - case EXTRADATA_PANSCAN_WINDOW: - panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data; - break; - case EXTRADATA_MPEG2_SEQDISP: - struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload; - seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data; - if (seqdisp_payload) { - m_disp_hor_size = seqdisp_payload->disp_width; - m_disp_vert_size = seqdisp_payload->disp_height; - } - break; - default: - goto unrecognized_extradata; - } - consumed_len += data->nSize; - data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize); - } - if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) { - p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA; - append_frame_info_extradata(p_extra, - num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate, - panscan_payload,&((struct vdec_output_frameinfo *) - p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);} - } -unrecognized_extradata: - if(!secure_mode && client_extradata) - append_terminator_extradata(p_extra); - return; -} - -OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, - bool is_internal, bool enable) -{ - OMX_ERRORTYPE ret = OMX_ErrorNone; - struct v4l2_control control; - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only"); - return OMX_ErrorIncorrectStateOperation; - } - DEBUG_PRINT_ERROR("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n", - client_extradata, requested_extradata, enable, is_internal); - - if (!is_internal) { - if (enable) - client_extradata |= requested_extradata; - else - client_extradata = client_extradata & ~requested_extradata; - } - - if (enable) { - if (requested_extradata & OMX_INTERLACE_EXTRADATA) { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set interlaced extradata." - " Quality of interlaced clips might be impacted.\n"); - } - } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) - { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set framerate extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); - } - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); - } - if (output_capability == V4L2_PIX_FMT_MPEG2) - { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set panscan extradata\n"); - } - } - } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) - { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP; - if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n"); - } - } - } - ret = get_buffer_req(&drv_ctx.op_buf); - return ret; -} - -OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0; - OMX_U8 *data_ptr = extra->data, data = 0; - while (byte_count < extra->nDataSize) - { - data = *data_ptr; - while (data) - { - num_MB += (data&0x01); - data >>= 1; - } - data_ptr++; - byte_count++; - } - num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) * - (drv_ctx.video_resolution.frame_height + 15)) >> 8; - return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0); -} - -void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - if (!m_debug_extradata) - return; - - DEBUG_PRINT_HIGH( - "============== Extra Data ==============\n" - " Size: %lu \n" - " Version: %lu \n" - " PortIndex: %lu \n" - " Type: %x \n" - " DataSize: %lu \n", - extra->nSize, extra->nVersion.nVersion, - extra->nPortIndex, extra->eType, extra->nDataSize); - - if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) - { - OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data; - DEBUG_PRINT_HIGH( - "------ Interlace Format ------\n" - " Size: %lu \n" - " Version: %lu \n" - " PortIndex: %lu \n" - " Is Interlace Format: %d \n" - " Interlace Formats: %lu \n" - "=========== End of Interlace ===========\n", - intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex, - intfmt->bInterlaceFormat, intfmt->nInterlaceFormats); - } - else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) - { - OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; - - DEBUG_PRINT_HIGH( - "-------- Frame Format --------\n" - " Picture Type: %d \n" - " Interlace Type: %d \n" - " Pan Scan Total Frame Num: %lu \n" - " Concealed Macro Blocks: %lu \n" - " frame rate: %lu \n" - " Aspect Ratio X: %lu \n" - " Aspect Ratio Y: %lu \n", - fminfo->ePicType, - fminfo->interlaceType, - fminfo->panScan.numWindows, - fminfo->nConcealedMacroblocks, - fminfo->nFrameRate, - fminfo->aspectRatio.aspectRatioX, - fminfo->aspectRatio.aspectRatioY); - - for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) - { - DEBUG_PRINT_HIGH( - "------------------------------\n" - " Pan Scan Frame Num: %lu \n" - " Rectangle x: %ld \n" - " Rectangle y: %ld \n" - " Rectangle dx: %ld \n" - " Rectangle dy: %ld \n", - i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y, - fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy); - } - - DEBUG_PRINT_HIGH("========= End of Frame Format =========="); - } - else if (extra->eType == OMX_ExtraDataNone) - { - DEBUG_PRINT_HIGH("========== End of Terminator ==========="); - } - else - { - DEBUG_PRINT_HIGH("======= End of Driver Extradata ========"); - } -} - -void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 interlaced_format_type) -{ - OMX_STREAMINTERLACEFORMAT *interlace_format; - OMX_U32 mbaff = 0; - if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) { - return; - } - extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat; - extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT); - interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data; - interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT); - interlace_format->nVersion.nVersion = OMX_SPEC_VERSION; - interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - mbaff = (h264_parser)? (h264_parser->is_mbaff()): false; - if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE) && !mbaff) - { - interlace_format->bInterlaceFormat = OMX_FALSE; - interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive; - drv_ctx.interlace = VDEC_InterlaceFrameProgressive; - } - else - { - interlace_format->bInterlaceFormat = OMX_TRUE; - interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst; - drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst; - } - print_debug_extradata(extra); -} - -void omx_vdec::fill_aspect_ratio_info( - struct vdec_aspectratioinfo *aspect_ratio_info, - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info) -{ - m_extradata = frame_info; - m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width; - m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height; - DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX, - m_extradata->aspectRatio.aspectRatioY); -} - -void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra, - OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate, - struct msm_vidc_panscan_window_payload *panscan_payload, - struct vdec_aspectratioinfo *aspect_ratio_info) -{ - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL; - struct msm_vidc_panscan_window *panscan_window; - if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) { - return; - } - extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo; - extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO); - frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data; - switch (picture_type) - { - case PICTURE_TYPE_I: - frame_info->ePicType = OMX_VIDEO_PictureTypeI; - break; - case PICTURE_TYPE_P: - frame_info->ePicType = OMX_VIDEO_PictureTypeP; - break; - case PICTURE_TYPE_B: - frame_info->ePicType = OMX_VIDEO_PictureTypeB; - break; - default: - frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0; - } - if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst) - frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst; - else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst) - frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst; - else - frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive; - memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio)); - frame_info->nConcealedMacroblocks = num_conceal_mb; - frame_info->nFrameRate = frame_rate; - frame_info->panScan.numWindows = 0; - if (output_capability == V4L2_PIX_FMT_MPEG2) - { - if (m_disp_hor_size && m_disp_vert_size) - { - frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size; - frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size; - } - } - - if(panscan_payload) { - frame_info->panScan.numWindows = panscan_payload->num_panscan_windows; - panscan_window = &panscan_payload->wnd[0]; - for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) - { - frame_info->panScan.window[i].x = panscan_window->panscan_window_width; - frame_info->panScan.window[i].y = panscan_window->panscan_window_height; - frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset; - frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset; - panscan_window++; - } - } - fill_aspect_ratio_info(aspect_ratio_info, frame_info); - print_debug_extradata(extra); -} - -void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL; - extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE; - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef; - extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data; - *portDefn = m_port_def; - DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu " - "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight, - portDefn->format.video.nFrameWidth, - portDefn->format.video.nStride, - portDefn->format.video.nSliceHeight); -} - -void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra) -{ - if (!client_extradata) { - return; - } - extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE); - extra->nVersion.nVersion = OMX_SPEC_VERSION; - extra->eType = OMX_ExtraDataNone; - extra->nDataSize = 0; - extra->data[0] = 0; - - print_debug_extradata(extra); -} - -OMX_ERRORTYPE omx_vdec::allocate_desc_buffer(OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (index >= drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found"); - return OMX_ErrorInsufficientResources; - } - if (m_desc_buffer_ptr == NULL) - { - m_desc_buffer_ptr = (desc_buffer_hdr*) \ - calloc( (sizeof(desc_buffer_hdr)), - drv_ctx.ip_buf.actualcount); - if (m_desc_buffer_ptr == NULL) - { - DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - } - - m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8)); - if (m_desc_buffer_ptr[index].buf_addr == NULL) - { - DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed "); - return OMX_ErrorInsufficientResources; - } - - return eRet; -} - -void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset) -{ - DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries); - if (m_demux_entries < 8192) - { - m_demux_offsets[m_demux_entries++] = address_offset; - } - return; -} - -void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr) -{ - OMX_U32 bytes_to_parse = buf_hdr->nFilledLen; - OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset; - OMX_U32 index = 0; - - m_demux_entries = 0; - - while (index < bytes_to_parse) - { - if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) && - (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) || - ((buf[index] == 0x00) && (buf[index+1] == 0x00) && - (buf[index+2] == 0x01)) ) - { - //Found start code, insert address offset - insert_demux_addr_offset(index); - if (buf[index+2] == 0x01) // 3 byte start code - index += 3; - else //4 byte start code - index += 4; - } - else - index++; - } - DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries); - return; -} - -OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr) -{ - //fix this, handle 3 byte start code, vc1 terminator entry - OMX_U8 *p_demux_data = NULL; - OMX_U32 desc_data = 0; - OMX_U32 start_addr = 0; - OMX_U32 nal_size = 0; - OMX_U32 suffix_byte = 0; - OMX_U32 demux_index = 0; - OMX_U32 buffer_index = 0; - - if (m_desc_buffer_ptr == NULL) - { - DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries."); - return OMX_ErrorBadParameter; - } - - buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - if (buffer_index > drv_ctx.ip_buf.actualcount) - { - DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index); - return OMX_ErrorBadParameter; - } - - p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr; - - if ( ((OMX_U8*)p_demux_data == NULL) || - ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) - { - DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries."); - return OMX_ErrorBadParameter; - } - else - { - for (; demux_index < m_demux_entries; demux_index++) - { - desc_data = 0; - start_addr = m_demux_offsets[demux_index]; - if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) - { - suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3]; - } - else - { - suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4]; - } - if (demux_index < (m_demux_entries - 1)) - { - nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2; - } - else - { - nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2; - } - DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)", - (void *)start_addr, - suffix_byte, - nal_size, - demux_index); - desc_data = (start_addr >> 3) << 1; - desc_data |= (start_addr & 7) << 21; - desc_data |= suffix_byte << 24; - - memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); - memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32)); - memset(p_demux_data + 8, 0, sizeof(OMX_U32)); - memset(p_demux_data + 12, 0, sizeof(OMX_U32)); - - p_demux_data += 16; - } - if (codec_type_parse == CODEC_TYPE_VC1) - { - DEBUG_PRINT_LOW("VC1 terminator entry"); - desc_data = 0; - desc_data = 0x82 << 24; - memcpy(p_demux_data, &desc_data, sizeof(OMX_U32)); - memset(p_demux_data + 4, 0, sizeof(OMX_U32)); - memset(p_demux_data + 8, 0, sizeof(OMX_U32)); - memset(p_demux_data + 12, 0, sizeof(OMX_U32)); - p_demux_data += 16; - m_demux_entries++; - } - //Add zero word to indicate end of descriptors - memset(p_demux_data, 0, sizeof(OMX_U32)); - - m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32); - DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size); - } - memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) ); - m_demux_entries = 0; - DEBUG_PRINT_LOW("Demux table complete!"); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_vdec::createDivxDrmContext() -{ - OMX_ERRORTYPE err = OMX_ErrorNone; - iDivXDrmDecrypt = DivXDrmDecrypt::Create(); - if (iDivXDrmDecrypt) { - OMX_ERRORTYPE err = iDivXDrmDecrypt->Init(); - if(err!=OMX_ErrorNone) { - DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err); - delete iDivXDrmDecrypt; - iDivXDrmDecrypt = NULL; - } - } - else { - DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM"); - err = OMX_ErrorUndefined; - } - return err; -} - -omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf() -{ - enabled = false; - omx = NULL; - init_members(); - ColorFormat = OMX_COLOR_FormatMax; -} - -void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client) -{ - omx = reinterpret_cast(client); -} - -void omx_vdec::allocate_color_convert_buf::init_members() { - allocated_count = 0; - buffer_size_req = 0; - buffer_alignment_req = 0; - memset(m_platform_list_client,0,sizeof(m_platform_list_client)); - memset(m_platform_entry_client,0,sizeof(m_platform_entry_client)); - memset(m_pmem_info_client,0,sizeof(m_pmem_info_client)); - memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client)); -#ifdef USE_ION - memset(op_buf_ion_info,0,sizeof(m_platform_entry_client)); -#endif - for (int i = 0; i < MAX_COUNT;i++) - pmem_fd[i] = -1; -} - -omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf() { - c2d.destroy(); -} - -bool omx_vdec::allocate_color_convert_buf::update_buffer_req() -{ - bool status = true; - unsigned int src_size = 0, destination_size = 0; - OMX_COLOR_FORMATTYPE drv_color_format; - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid client in color convert"); - return false; - } - if (!enabled){ - DEBUG_PRINT_ERROR("\n No color conversion required"); - return status; - } - pthread_mutex_lock(&omx->c_lock); - if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 && - ColorFormat != OMX_COLOR_FormatYUV420Planar) { - DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion"); - status = false; - goto fail_update_buf_req; - } - c2d.close(); - status = c2d.open(omx->drv_ctx.video_resolution.frame_height, - omx->drv_ctx.video_resolution.frame_width, - NV12_128m,YCbCr420P); - if (status) { - status = c2d.get_buffer_size(C2D_INPUT,src_size); - if (status) - status = c2d.get_buffer_size(C2D_OUTPUT,destination_size); - } - if (status) { - if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size || - !destination_size) { - DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d" - "driver size %d destination size %d", - src_size,omx->drv_ctx.op_buf.buffer_size,destination_size); - status = false; - c2d.close(); - buffer_size_req = 0; - } else { - buffer_size_req = destination_size; - if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size) - buffer_size_req = omx->drv_ctx.op_buf.buffer_size; - if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) - buffer_alignment_req = omx->drv_ctx.op_buf.alignment; - } - } -fail_update_buf_req: - pthread_mutex_unlock(&omx->c_lock); - return status; -} - -bool omx_vdec::allocate_color_convert_buf::set_color_format( - OMX_COLOR_FORMATTYPE dest_color_format) -{ - bool status = true; - OMX_COLOR_FORMATTYPE drv_color_format; - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid client in color convert"); - return false; - } - pthread_mutex_lock(&omx->c_lock); - if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) - drv_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - else { - DEBUG_PRINT_ERROR("\n Incorrect color format"); - status = false; - } - if (status && (drv_color_format != dest_color_format)) { - DEBUG_PRINT_LOW("Enabling C2D\n"); - if (dest_color_format != OMX_COLOR_FormatYUV420Planar) { - DEBUG_PRINT_ERROR("\n Unsupported color format for c2d"); - status = false; - } else { - ColorFormat = OMX_COLOR_FormatYUV420Planar; - if (enabled) - c2d.destroy(); - enabled = false; - if (!c2d.init()) { - DEBUG_PRINT_ERROR("\n open failed for c2d"); - status = false; - } else - enabled = true; - } - } else { - if (enabled) - c2d.destroy(); - enabled = false; - } - pthread_mutex_unlock(&omx->c_lock); - return status; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr() -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return omx->m_out_mem_ptr; - return m_out_mem_ptr_client; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr - (OMX_BUFFERHEADERTYPE *bufadd) -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return bufadd; - - unsigned index = 0; - index = bufadd - omx->m_out_mem_ptr; - if (index < omx->drv_ctx.op_buf.actualcount) { - m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS); - m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp; - bool status; - if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) { - pthread_mutex_lock(&omx->c_lock); - status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd, - omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index], - pmem_baseaddress[index], pmem_baseaddress[index]); - pthread_mutex_unlock(&omx->c_lock); - m_out_mem_ptr_client[index].nFilledLen = buffer_size_req; - if (!status){ - DEBUG_PRINT_ERROR("\n Failed color conversion %d", status); - m_out_mem_ptr_client[index].nFilledLen = 0; - return &m_out_mem_ptr_client[index]; - } - } else - m_out_mem_ptr_client[index].nFilledLen = 0; - return &m_out_mem_ptr_client[index]; - } - DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr"); - return NULL; -} - -OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr - (OMX_BUFFERHEADERTYPE *bufadd) -{ - if (!omx){ - DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr"); - return NULL; - } - if (!enabled) - return bufadd; - unsigned index = 0; - index = bufadd - m_out_mem_ptr_client; - if (index < omx->drv_ctx.op_buf.actualcount) { - return &omx->m_out_mem_ptr[index]; - } - DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr"); - return NULL; -} -bool omx_vdec::allocate_color_convert_buf::get_buffer_req - (unsigned int &buffer_size) -{ - bool status = true; - pthread_mutex_lock(&omx->c_lock); - if (!enabled) - buffer_size = omx->drv_ctx.op_buf.buffer_size; - else { - if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) { - DEBUG_PRINT_ERROR("\n Get buffer size failed"); - status = false; - goto fail_get_buffer_size; - } - } - if (buffer_size < omx->drv_ctx.op_buf.buffer_size) - buffer_size = omx->drv_ctx.op_buf.buffer_size; - if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment) - buffer_alignment_req = omx->drv_ctx.op_buf.alignment; -fail_get_buffer_size: - pthread_mutex_unlock(&omx->c_lock); - return status; -} -OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer( - OMX_BUFFERHEADERTYPE *bufhdr) { - unsigned int index = 0; - - if (!enabled) - return omx->free_output_buffer(bufhdr); - if (enabled && omx->is_component_secure()) - return OMX_ErrorNone; - if (!allocated_count || !bufhdr) { - DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr); - return OMX_ErrorBadParameter; - } - index = bufhdr - m_out_mem_ptr_client; - if (index >= omx->drv_ctx.op_buf.actualcount){ - DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer"); - return OMX_ErrorBadParameter; - } - if (pmem_fd[index] > 0) { - munmap(pmem_baseaddress[index], buffer_size_req); - close(pmem_fd[index]); - } - pmem_fd[index] = -1; -#ifdef USE_ION - omx->free_ion_memory(&op_buf_ion_info[index]); -#endif - m_heap_ptr[index].video_heap_ptr = NULL; - if (allocated_count > 0) - allocated_count--; - else - allocated_count = 0; - if (!allocated_count) { - pthread_mutex_lock(&omx->c_lock); - c2d.close(); - init_members(); - pthread_mutex_unlock(&omx->c_lock); - } - return omx->free_output_buffer(&omx->m_out_mem_ptr[index]); -} - -OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if (!enabled){ - eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); - return eRet; - } - if (enabled && omx->is_component_secure()) { - DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d", - omx->is_component_secure()); - return OMX_ErrorUnsupportedSetting; - } - if (!bufferHdr || bytes > buffer_size_req) { - DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr); - DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu", - buffer_size_req,bytes); - return OMX_ErrorBadParameter; - } - if (allocated_count >= omx->drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert"); - return OMX_ErrorInsufficientResources; - } - OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL; - eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr, - port,appData,omx->drv_ctx.op_buf.buffer_size); - if (eRet != OMX_ErrorNone || !temp_bufferHdr){ - DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert"); - return eRet; - } - if ((temp_bufferHdr - omx->m_out_mem_ptr) >= - omx->drv_ctx.op_buf.actualcount) { - DEBUG_PRINT_ERROR("\n Invalid header index %d", - (temp_bufferHdr - omx->m_out_mem_ptr)); - return OMX_ErrorUndefined; - } - unsigned int i = allocated_count; -#ifdef USE_ION - op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory( - buffer_size_req,buffer_alignment_req, - &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data, - 0); - pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd; - if (op_buf_ion_info[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert"); - return OMX_ErrorInsufficientResources; - } - pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req, - PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0); - - if (pmem_baseaddress[i] == MAP_FAILED) { - DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req); - close(pmem_fd[i]); - omx->free_ion_memory(&op_buf_ion_info[i]); - return OMX_ErrorInsufficientResources; - } - m_heap_ptr[i].video_heap_ptr = new VideoHeap ( - op_buf_ion_info[i].ion_device_fd,buffer_size_req, - pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]); -#endif - m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get(); - m_pmem_info_client[i].offset = 0; - m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i]; - m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - m_platform_list_client[i].nEntries = 1; - m_platform_list_client[i].entryList = &m_platform_entry_client[i]; - m_out_mem_ptr_client[i].pOutputPortPrivate = NULL; - m_out_mem_ptr_client[i].nAllocLen = buffer_size_req; - m_out_mem_ptr_client[i].nFilledLen = 0; - m_out_mem_ptr_client[i].nFlags = 0; - m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; - m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE); - m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION; - m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i]; - m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i]; - m_out_mem_ptr_client[i].pAppPrivate = appData; - *bufferHdr = &m_out_mem_ptr_client[i]; - DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr); - allocated_count++; - return eRet; -} - -bool omx_vdec::is_component_secure() -{ - return secure_mode; -} - -bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format) -{ - bool status = true; - if (!enabled) { - if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) - dest_color_format = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; - else - status = false; - } else { - if (ColorFormat != OMX_COLOR_FormatYUV420Planar) { - status = false; - } else - dest_color_format = OMX_COLOR_FormatYUV420Planar; - } - return status; -} diff --git a/mm-video/vidc/vdec/src/power_module.cpp b/mm-video/vidc/vdec/src/power_module.cpp deleted file mode 100644 index 38492186..00000000 --- a/mm-video/vidc/vdec/src/power_module.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*------------------------------------------------------------------------- -Copyright (c) 2012, The Linux Foundation. All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#include "power_module.h" - -PowerModule *PowerModule::mPowerModuleInstance = NULL; - -PowerModule *PowerModule::getInstance() -{ - if (mPowerModuleInstance == NULL) { - mPowerModuleInstance = new PowerModule; - - if (mPowerModuleInstance) { - mPowerModuleInstance->mPowerModuleHandle = NULL; - - hw_get_module(POWER_HARDWARE_MODULE_ID, - (const hw_module_t **)&(mPowerModuleInstance->mPowerModuleHandle)); - } - } - - return mPowerModuleInstance; -} - -power_module_t *PowerModule::getPowerModuleHandle() -{ - return mPowerModuleHandle; -} diff --git a/mm-video/vidc/vdec/src/queue.c b/mm-video/vidc/vdec/src/queue.c deleted file mode 100755 index 368d7c4d..00000000 --- a/mm-video/vidc/vdec/src/queue.c +++ /dev/null @@ -1,128 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -/* - Queue with Linked list -*/ - -#include "queue.h" -#include -#include - - -typedef struct Node -{ - void *element; - struct Node *next; -} Node; - -struct Queue -{ - Node *head; - Node *tail; - int current_size; -}; - -Queue *alloc_queue() -{ - Queue *q = (Queue *) malloc(sizeof(Queue)); - if (q) - { - q->head = q->tail = NULL; - q->current_size = 0; - } - return q; -} - -void free_queue(Queue *q) -{ - while (q->current_size) - { - pop(q); - } -} - -void free_queue_and_qelement(Queue *q) -{ - while (q->current_size) - { - void *element = pop(q); - if (element) - free(element); - } -} - -int push(Queue *q, void * element) -{ - Node *new_node = (Node *) malloc(sizeof(Node)); - - if (new_node == NULL) - return -1; - - new_node->element = element; - new_node->next = NULL; - - if (q->current_size == 0) - { - q->head = new_node; - } - else - { - q->tail->next = new_node; - } - - q->tail = new_node; - q->current_size++; - - return 0; -} - -void *pop(Queue *q) -{ - Node *temp; - void *element; - - if (q->current_size == 0) - return NULL; - - temp = q->head; - element = temp->element; - - if (q->current_size == 1) - { - q->head = q->tail = NULL; - } - else - { - q->head = q->head->next; - } - - free(temp); - q->current_size--; - return element; -} - diff --git a/mm-video/vidc/vdec/src/ts_parser.cpp b/mm-video/vidc/vdec/src/ts_parser.cpp deleted file mode 100644 index 44aa2005..00000000 --- a/mm-video/vidc/vdec/src/ts_parser.cpp +++ /dev/null @@ -1,268 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "ts_parser.h" - -#define DEBUG ALOGE -void omx_time_stamp_reorder::set_timestamp_reorder_mode(bool mode) -{ - reorder_ts = mode; -} - -void omx_time_stamp_reorder::enable_debug_print(bool flag) -{ - print_debug = flag; -} - -omx_time_stamp_reorder::~omx_time_stamp_reorder() -{ - delete_list(); -} - -omx_time_stamp_reorder::omx_time_stamp_reorder() -{ - reorder_ts = false; - phead = pcurrent = NULL; - error = false; - print_debug = false; -} - -void omx_time_stamp_reorder::delete_list() -{ - time_stamp_list *ptemp; - if (!phead) return; - while(phead->next != phead) { - ptemp = phead; - phead = phead->next; - phead->prev = ptemp->prev; - ptemp->prev->next = phead; - delete ptemp; - } - delete phead; - phead = NULL; -} - -bool omx_time_stamp_reorder::get_current_list() -{ - if (!phead) { - if(!add_new_list()) { - handle_error(); - return false; - } - } - pcurrent = phead->prev; - return true; -} - -bool omx_time_stamp_reorder::update_head() -{ - time_stamp_list *ptemp; - if(!phead) return false; - if (phead->next != phead) { - ptemp = phead; - phead = ptemp->next; - phead->prev = ptemp->prev; - ptemp->prev->next = phead; - delete ptemp; - } - return true; -} - -bool omx_time_stamp_reorder::add_new_list() -{ - bool status = true; - time_stamp_list *ptemp = NULL; - if (!phead) { - ptemp = phead = new time_stamp_list; - if (!phead) { - handle_error(); - status = false; - return status; - } - phead->prev = phead->next = phead; - } else { - ptemp = new time_stamp_list; - if (!ptemp) { - handle_error(); - status = false; - return status; - } - ptemp->prev = phead->prev; - ptemp->next = phead; - phead->prev->next = ptemp; - phead->prev = ptemp; - } - ptemp->entries_filled = 0; - for(int i=0; i < TIME_SZ; i++) { - ptemp->input_timestamps[i].in_use = false; - ptemp->input_timestamps[i].timestamps = -1; - } - return status; -} - -bool omx_time_stamp_reorder::insert_timestamp(OMX_BUFFERHEADERTYPE *header) -{ - OMX_TICKS *table_entry = NULL; - if (!reorder_ts || error || !header) { - if (error || !header) - DEBUG("\n Invalid condition in insert_timestamp %p", header); - return false; - } - if(!get_current_list()) { - handle_error(); - return false; - } - if (pcurrent->entries_filled > (TIME_SZ - 1)) { - DEBUG("\n Table full return error"); - handle_error(); - return false; - } - if (header->nFlags & OMX_BUFFERFLAG_CODECCONFIG) { - return true; - } - if ((header->nFlags & OMX_BUFFERFLAG_EOS) && !header->nFilledLen) - { - DEBUG("\n EOS with zero length recieved"); - if (!add_new_list()) { - handle_error(); - return false; - } - return true; - } - for(int i = 0; i < TIME_SZ && !table_entry; i++) { - if (!pcurrent->input_timestamps[i].in_use) { - table_entry = &pcurrent->input_timestamps[i].timestamps; - pcurrent->input_timestamps[i].in_use = true; - pcurrent->entries_filled++; - } - } - if (!table_entry) { - DEBUG("\n All entries in use"); - handle_error(); - return false; - } - *table_entry = header->nTimeStamp; - if (print_debug) - DEBUG("Time stamp inserted %lld", header->nTimeStamp); - if (header->nFlags & OMX_BUFFERFLAG_EOS) { - if (!add_new_list()) { - handle_error(); - return false; - } - } - return true; -} - -bool omx_time_stamp_reorder::remove_time_stamp(OMX_TICKS ts, bool is_interlaced = false) -{ - unsigned int num_ent_remove = (is_interlaced)?2:1; - if (!reorder_ts || error) { - DEBUG("\n not in avi mode"); - return false; - } - if (!phead || !phead->entries_filled) return false; - for(int i=0; i < TIME_SZ && num_ent_remove; i++) { - if (phead->input_timestamps[i].in_use && phead->input_timestamps[i].timestamps == ts) { - phead->input_timestamps[i].in_use = false; - phead->entries_filled--; - num_ent_remove--; - if (print_debug) - DEBUG("Removed TS %lld", ts); - } - } - if (!phead->entries_filled) { - if (!update_head()) { - handle_error(); - return false; - } - } - return true; -} - -void omx_time_stamp_reorder::flush_timestamp() -{ - delete_list(); -} - -bool omx_time_stamp_reorder::get_next_timestamp(OMX_BUFFERHEADERTYPE *header, bool is_interlaced) -{ - timestamp *element = NULL,*duplicate = NULL; - bool status = false; - if (!reorder_ts || error || !header) { - if (error || !header) - DEBUG("\n Invalid condition in insert_timestamp %p", header); - return false; - } - if(!phead || !phead->entries_filled) return false; - for(int i=0; i < TIME_SZ; i++) { - if (phead->input_timestamps[i].in_use) { - status = true; - if (!element) - element = &phead->input_timestamps[i]; - else { - if (element->timestamps > phead->input_timestamps[i].timestamps){ - element = &phead->input_timestamps[i]; - duplicate = NULL; - } else if(element->timestamps == phead->input_timestamps[i].timestamps) - duplicate = &phead->input_timestamps[i]; - } - } - } - if (element) { - phead->entries_filled--; - header->nTimeStamp = element->timestamps; - if (print_debug) - DEBUG("Getnext Time stamp %lld", header->nTimeStamp); - element->in_use = false; - } - if(is_interlaced && duplicate) { - phead->entries_filled--; - duplicate->in_use = false; - } else if (is_interlaced && !duplicate) { - element = NULL; - for(int i=0; i < TIME_SZ; i++) { - if (phead->input_timestamps[i].in_use) { - if (!element) - element = &phead->input_timestamps[i]; - else if (element->timestamps > phead->input_timestamps[i].timestamps) - element = &phead->input_timestamps[i]; - } - } - if (element) { - phead->entries_filled--; - header->nTimeStamp = element->timestamps; - element->in_use = false; - } - } - if (!phead->entries_filled) { - if (!update_head()) { - handle_error(); - return false; - } - } - return status; -} diff --git a/mm-video/vidc/vdec/test/decoder_driver_test.c b/mm-video/vidc/vdec/test/decoder_driver_test.c deleted file mode 100755 index fe870f82..00000000 --- a/mm-video/vidc/vdec/test/decoder_driver_test.c +++ /dev/null @@ -1,1198 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "decoder_driver_test.h" - -#define DEBUG_PRINT printf -/************************************************************************/ -/* #DEFINES */ -/************************************************************************/ - -#define VOP_START_CODE 0x000001B6 -#define SHORT_HEADER_START_CODE 0x00008000 -#define H264_START_CODE 0x00000001 - -/************************************************************************/ -/* STATIC VARIABLES */ -/************************************************************************/ - -static int Code_type; -static int total_frames = 0; -static unsigned int header_code = 0; -static pthread_mutex_t read_lock; - -static unsigned int read_frame ( unsigned char *dataptr,unsigned int length, - FILE * inputBufferFile - ); -static int Read_Buffer_From_DAT_File( unsigned char *dataptr, unsigned int length, - FILE * inputBufferFile - ); - -static unsigned clp2(unsigned x) -{ - x = x - 1; - x = x | (x >> 1); - x = x | (x >> 2); - x = x | (x >> 4); - x = x | (x >> 8); - x = x | (x >>16); - return x + 1; -} - -static void* video_thread (void *); -static void* async_thread (void *); - -int main (int argc, char **argv) -{ - struct video_decoder_context *decoder_context = NULL; - char *file_name = NULL; - FILE *file_ptr = NULL; - int temp1 =0,temp2 =0; - int error = 1; - unsigned int i = 0; - - file_name = argv [1]; - file_ptr = fopen (file_name,"rb"); - - if (file_ptr == NULL) - { - DEBUG_PRINT("\n File is not located "); - return -1; - } - - - decoder_context = (struct video_decoder_context *) \ - calloc (sizeof (struct video_decoder_context),1); - if (decoder_context == NULL) - { - return -1; - } - decoder_context->outputBufferFile = NULL; - decoder_context->inputBufferFile = NULL; - decoder_context->video_driver_fd = -1; - decoder_context->inputBufferFile = file_ptr; - - file_ptr = fopen ("/data/output.yuv","wb"); - if (file_ptr == NULL) - { - DEBUG_PRINT("\n File can't be created"); - free (decoder_context); - return -1; - } - decoder_context->outputBufferFile = file_ptr; - - switch (atoi(argv[2])) - { - case 0: - DEBUG_PRINT("\n MPEG4 codec selected"); - decoder_context->decoder_format = VDEC_CODECTYPE_MPEG4; - Code_type = 0; - break; - case 1: - DEBUG_PRINT("\n H.263"); - decoder_context->decoder_format = VDEC_CODECTYPE_H263; - Code_type = 0; - break; - case 2: - DEBUG_PRINT("\n H.264"); - decoder_context->decoder_format = VDEC_CODECTYPE_H264; - Code_type = 1; - break; - default: - DEBUG_PRINT("\n Wrong codec type"); - error = -1; - break; - } - - if (error != -1) - { - temp1 = atoi(argv[3]); - temp2 = atoi(argv[4]); - - if (((temp1%16) != 0) || ((temp2%16) != 0)) - { - error = -1; - } - else - { - decoder_context->video_resoultion.frame_height = temp1; - decoder_context->video_resoultion.frame_width = temp2; - } - } - - switch (atoi(argv[5])) - { - case 0: - DEBUG_PRINT("\n No Sink"); - decoder_context->outputBufferFile = NULL; - break; - } - - if ( error != -1 && (init_decoder (decoder_context) == -1 )) - { - DEBUG_PRINT("\n Init decoder fails "); - error = -1; - } - DEBUG_PRINT("\n Decoder open successfull"); - - - /*Allocate input and output buffers*/ - if (error != -1 && (allocate_buffer (VDEC_BUFFER_TYPE_INPUT, - decoder_context)== -1)) - { - DEBUG_PRINT("\n Error in input Buffer allocation"); - error = -1; - } - - if (error != -1 && (allocate_buffer (VDEC_BUFFER_TYPE_OUTPUT, - decoder_context)== -1)) - { - DEBUG_PRINT("\n Error in output Buffer allocation"); - error = -1; - } - - - if (error != -1 && (start_decoding (decoder_context) == -1)) - { - DEBUG_PRINT("\n Error in start decoding call"); - error = -1; - } - - if (error != -1 && (stop_decoding (decoder_context) == -1)) - { - DEBUG_PRINT("\n Error in stop decoding call"); - error = -1; - } - - DEBUG_PRINT("\n De-init the decoder"); - if ((deinit_decoder (decoder_context) == -1)) - { - error = -1; - } - - - (void)free_buffer (VDEC_BUFFER_TYPE_INPUT,decoder_context); - (void)free_buffer (VDEC_BUFFER_TYPE_OUTPUT,decoder_context); - - if (decoder_context->inputBufferFile != NULL) - { - fclose (decoder_context->inputBufferFile); - } - if (decoder_context->outputBufferFile != NULL) - { - fclose (decoder_context->outputBufferFile); - } - DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames); - DEBUG_PRINT("\n closing the driver"); - free (decoder_context); - - return error; -} - -int init_decoder ( struct video_decoder_context *init_decode ) -{ - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - struct video_queue_context *queue_ptr = NULL; -#ifdef MAX_RES_720P - enum vdec_output_fromat output_format = VDEC_YUV_FORMAT_NV12; -#endif -#ifdef MAX_RES_1080P - enum vdec_output_fromat output_format = VDEC_YUV_FORMAT_TILE_4x2; -#endif - - pthread_mutexattr_t init_values; - - DEBUG_PRINT("\n Before calling the open"); - - init_decode->video_driver_fd = open ("/dev/msm_vidc_dec", \ - O_RDWR | O_NONBLOCK); - - - - if (init_decode->video_driver_fd < 0) - { - DEBUG_PRINT("\n Open failed"); - return -1; - } - - - /*Initialize Decoder with codec type and resolution*/ - ioctl_msg.in = &init_decode->decoder_format; - ioctl_msg.out = NULL; - - if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_CODEC, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set codec type failed"); - return -1; - } - - /*Set the output format*/ - ioctl_msg.in = &output_format; - ioctl_msg.out = NULL; - - if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set output format failed"); - return -1; - } - - ioctl_msg.in = &init_decode->video_resoultion; - ioctl_msg.out = NULL; - - if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_PICRES, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set Resolution failed"); - return -1; - } - DEBUG_PRINT("\n After Set Resolution"); - - DEBUG_PRINT("\n Query Input bufffer requirements"); - /*Get the Buffer requirements for input and output ports*/ - - init_decode->input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; - ioctl_msg.in = NULL; - ioctl_msg.out = &init_decode->input_buffer; - - if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Requesting for input buffer requirements failed"); - return -1; - } - - DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \ - init_decode->input_buffer.buffer_size,\ - init_decode->input_buffer.mincount,\ - init_decode->input_buffer.actualcount); - - - init_decode->input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT; - ioctl_msg.in = &init_decode->input_buffer; - ioctl_msg.out = NULL; - init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2; - - if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set Buffer Requirements Failed"); - return -1; - } - - - DEBUG_PRINT("\n Query output bufffer requirements"); - init_decode->output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT; - ioctl_msg.in = NULL; - ioctl_msg.out = &init_decode->output_buffer; - - if (ioctl (init_decode->video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Requesting for output buffer requirements failed"); - return -1; - } - - DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \ - init_decode->output_buffer.buffer_size,\ - init_decode->output_buffer.mincount,\ - init_decode->output_buffer.actualcount); - - /*Create Queue related data structures*/ - queue_ptr = &init_decode->queue_context; - queue_ptr->commandq_size = 50; - queue_ptr->dataq_size = 50; - - sem_init(&queue_ptr->sem_message,0, 0); - sem_init(&init_decode->sem_synchronize,0, 0); - - pthread_mutexattr_init (&init_values); - pthread_mutex_init (&queue_ptr->mutex,&init_values); - pthread_mutex_init (&read_lock,&init_values); - DEBUG_PRINT("\n create Queues"); - queue_ptr->ptr_cmdq = (struct video_msgq*) \ - calloc (sizeof (struct video_msgq), - queue_ptr->commandq_size); - queue_ptr->ptr_dataq = (struct video_msgq*) \ - calloc (sizeof (struct video_msgq), - queue_ptr->dataq_size - ); - - if ( queue_ptr->ptr_cmdq == NULL || - queue_ptr->ptr_dataq == NULL - ) - { - return -1; - } - DEBUG_PRINT("\n create Threads"); - /*Create two threads*/ - if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread, - init_decode) < 0) || - (pthread_create (&init_decode->asyncthread_id,NULL,async_thread, - init_decode) < 0) - ) - { - return -1; - } - - return 1; -} - - - -int free_buffer ( enum vdec_buffer buffer_dir, - struct video_decoder_context *decode_context - ) -{ - unsigned int buffercount = 0,i=0; - struct vdec_bufferpayload **ptemp = NULL; - - if (decode_context == NULL) - { - return -1; - } - - if (buffer_dir == VDEC_BUFFER_TYPE_INPUT && decode_context->ptr_inputbuffer) - { - buffercount = decode_context->input_buffer.actualcount; - ptemp = decode_context->ptr_inputbuffer; - - for (i=0;ipmem_fd != -1) - { - munmap ( ptemp [i]->bufferaddr,ptemp [i]->mmaped_size); - ptemp [i]->bufferaddr = NULL; - close (ptemp [i]->pmem_fd); - } - free (ptemp [i]); - ptemp [i] = NULL; - } - } - free (decode_context->ptr_inputbuffer); - decode_context->ptr_inputbuffer = NULL; - } - else if ( buffer_dir == VDEC_BUFFER_TYPE_OUTPUT ) - { - buffercount = decode_context->output_buffer.actualcount; - ptemp = decode_context->ptr_outputbuffer; - - if (decode_context->ptr_respbuffer) - { - for (i=0;iptr_respbuffer [i]) - { - free (decode_context->ptr_respbuffer[i]); - decode_context->ptr_respbuffer [i] = NULL; - } - } - free (decode_context->ptr_respbuffer); - decode_context->ptr_respbuffer = NULL; - } - - if (ptemp) - { - for (i=0;ipmem_fd != -1) - { - munmap ( ptemp [i]->bufferaddr,ptemp [i]->mmaped_size); - ptemp [i]->bufferaddr = NULL; - close (ptemp [i]->pmem_fd); - } - free (ptemp [i]); - ptemp [i] = NULL; - } - } - free (ptemp); - decode_context->ptr_outputbuffer = NULL; - } - } - - return 1; -} - -int allocate_buffer ( enum vdec_buffer buffer_dir, - struct video_decoder_context *decode_context - ) -{ - struct vdec_setbuffer_cmd setbuffers; - struct vdec_bufferpayload **ptemp = NULL; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - unsigned int buffercount = 0,i=0,alignedsize=0; - unsigned int buffersize = 0; - - if ( decode_context == NULL) - { - DEBUG_PRINT ("\nallocate_buffer: context is NULL"); - return -1; - } - - if ( buffer_dir == VDEC_BUFFER_TYPE_INPUT ) - { - /*Check if buffers are allocated*/ - if (decode_context->ptr_inputbuffer != NULL) - { - DEBUG_PRINT ("\nallocate_buffer: decode_context->ptr_inputbuffer is set"); - return -1; - } - - buffercount = decode_context->input_buffer.actualcount; - alignedsize = decode_context->input_buffer.alignment; - buffersize = decode_context->input_buffer.buffer_size; - buffersize = (buffersize + alignedsize) & (~alignedsize); - } - else if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT) - { - /*Check if buffers are allocated*/ - if (decode_context->ptr_outputbuffer != NULL) - { - DEBUG_PRINT ("\nallocate_buffer: Double allcoate output"); - return -1; - } - - buffercount = decode_context->output_buffer.actualcount; - alignedsize = decode_context->output_buffer.alignment; - buffersize = decode_context->output_buffer.buffer_size; - buffersize = (buffersize + alignedsize) & (~alignedsize); - - decode_context->ptr_respbuffer = (struct vdec_output_frameinfo **)\ - calloc (sizeof (struct vdec_output_frameinfo *),buffercount); - - if (decode_context->ptr_respbuffer == NULL) - { - DEBUG_PRINT ("\n Allocate failure ptr_respbuffer"); - return -1; - } - - for (i=0; i< buffercount; i++) - { - decode_context->ptr_respbuffer [i] = (struct vdec_output_frameinfo *)\ - calloc (sizeof (struct vdec_output_frameinfo),buffercount); - if (decode_context->ptr_respbuffer [i] == NULL) - { - DEBUG_PRINT ("\nfailed to allocate vdec_output_frameinfo"); - return -1; - } - } - } - else - { - DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions"); - return -1; - } - - ptemp = (struct vdec_bufferpayload **)\ - calloc (sizeof (struct vdec_bufferpayload *),buffercount); - - if (ptemp == NULL) - { - DEBUG_PRINT ("\nallocate_buffer: vdec_bufferpayload failure"); - return -1; - } - - - if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT) - { - DEBUG_PRINT ("\nallocate_buffer: OUT"); - decode_context->ptr_outputbuffer = ptemp; - } - else - { - DEBUG_PRINT ("\nallocate_buffer: IN"); - decode_context->ptr_inputbuffer = ptemp; - } - - /*Allocate buffer headers*/ - for (i=0; i< buffercount; i++) - { - ptemp [i] = (struct vdec_bufferpayload*)\ - calloc (sizeof (struct vdec_bufferpayload),1); - - if (ptemp [i] == NULL) - { - DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure"); - return -1; - } - - if (buffer_dir == VDEC_BUFFER_TYPE_OUTPUT) - { - decode_context->ptr_respbuffer [i]->client_data = \ - (void *) ptemp [i]; - } - ptemp [i]->pmem_fd = -1; - - } - - for (i=0; i< buffercount; i++) - { - ptemp [i]->pmem_fd = open ("/dev/pmem_adsp",O_RDWR); - - if (ptemp [i]->pmem_fd < 0) - { - DEBUG_PRINT ("\nallocate_buffer: open pmem_adsp failed"); - return -1; - } - - ptemp [i]->bufferaddr = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE, - MAP_SHARED,ptemp [i]->pmem_fd,0); - DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->pmem_fd,\ - ptemp [i]->bufferaddr); - if (ptemp [i]->bufferaddr == MAP_FAILED) - { - ptemp [i]->bufferaddr = NULL; - DEBUG_PRINT ("\nallocate_buffer: MMAP failed"); - return -1; - } - ptemp [i]->buffer_len = buffersize; - ptemp [i]->mmaped_size = clp2 (buffersize); - - setbuffers.buffer_type = buffer_dir; - memcpy (&setbuffers.buffer,ptemp [i],sizeof (struct vdec_bufferpayload)); - - ioctl_msg.in = &setbuffers; - ioctl_msg.out = NULL; - - if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_SET_BUFFER, - &ioctl_msg) < 0) - { - DEBUG_PRINT ("\nallocate_buffer: Set Buffer IOCTL failed"); - return -1; - } - - } - DEBUG_PRINT ("\nallocate_buffer: Success"); - return 1; -} - - - -int start_decoding (struct video_decoder_context *decode_context) -{ - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - struct vdec_input_frameinfo frameinfo; - struct vdec_fillbuffer_cmd fillbuffer; - unsigned int i = 0; - unsigned int data_len =0; - - memset ((unsigned char*)&frameinfo,0,sizeof (struct vdec_input_frameinfo)); - memset ((unsigned char*)&fillbuffer,0,sizeof (struct vdec_fillbuffer_cmd)); - - if (decode_context == NULL) - { - return -1; - } - - if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_CMD_START, - NULL) < 0) - { - DEBUG_PRINT("\n Start failed"); - return -1; - } - - DEBUG_PRINT("\n Start Issued successfully waiting for Start Done"); - /*Wait for Start command response*/ - sem_wait (&decode_context->sem_synchronize); - - /*Push output Buffers*/ - i = 0; - while (i < decode_context->output_buffer.mincount) - { - fillbuffer.buffer.buffer_len = - decode_context->ptr_outputbuffer [i]->buffer_len; - fillbuffer.buffer.bufferaddr = - decode_context->ptr_outputbuffer [i]->bufferaddr; - fillbuffer.buffer.offset = - decode_context->ptr_outputbuffer [i]->offset; - fillbuffer.buffer.pmem_fd = - decode_context->ptr_outputbuffer [i]->pmem_fd; - fillbuffer.client_data = (void *)decode_context->ptr_respbuffer [i]; - DEBUG_PRINT ("\n Client Data on output = %p",fillbuffer.client_data); - ioctl_msg.in = &fillbuffer; - ioctl_msg.out = NULL; - - if (ioctl (decode_context->video_driver_fd, - VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Decoder frame failed"); - return -1; - } - i++; - } - - - /*push input buffers*/ - i = 0; - while (i < decode_context->input_buffer.mincount) - { - DEBUG_PRINT("\n Read Frame from File"); - data_len = read_frame ( decode_context->ptr_inputbuffer [i]->bufferaddr, - decode_context->ptr_inputbuffer [i]->buffer_len, - decode_context->inputBufferFile); - if (data_len == 0) - { - DEBUG_PRINT("\n Length is zero error"); - return -1; - } - DEBUG_PRINT("\n Read Frame from File szie = %u",data_len); - frameinfo.bufferaddr = - decode_context->ptr_inputbuffer [i]->bufferaddr; - frameinfo.offset = 0; - frameinfo.pmem_fd = decode_context->ptr_inputbuffer [i]->pmem_fd; - frameinfo.pmem_offset = decode_context->ptr_inputbuffer [i]->offset; - frameinfo.datalen = data_len; - frameinfo.client_data = (struct vdec_bufferpayload *)\ - decode_context->ptr_inputbuffer [i]; - /*TODO: Time stamp needs to be updated*/ - ioctl_msg.in = &frameinfo; - ioctl_msg.out = NULL; - - if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_DECODE_FRAME, - &ioctl_msg) < 0) - { - DEBUG_PRINT("\n Decoder frame failed"); - return -1; - } - total_frames++; - i++; - } - DEBUG_PRINT ("\n Wait for EOS"); - /*Wait for EOS or Error condition*/ - sem_wait (&decode_context->sem_synchronize); - DEBUG_PRINT ("\n Reached EOS"); - - return 1; -} - -int stop_decoding (struct video_decoder_context *decode_context) -{ - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_INPUT; - - if (decode_context == NULL) - { - return -1; - } - - ioctl_msg.in = &flush_dir; - ioctl_msg.out = NULL; - - if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_FLUSH, - &ioctl_msg) < 0) - { - DEBUG_PRINT("\n Flush input failed"); - } - else - { - sem_wait (&decode_context->sem_synchronize); - } - - flush_dir = VDEC_FLUSH_TYPE_OUTPUT; - ioctl_msg.in = &flush_dir; - ioctl_msg.out = NULL; - - if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_FLUSH, - &ioctl_msg) < 0) - { - DEBUG_PRINT("\n Flush output failed"); - } - else - { - sem_wait (&decode_context->sem_synchronize); - } - - DEBUG_PRINT("\n Stop VDEC_IOCTL_CMD_STOP"); - if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_CMD_STOP, - NULL) < 0) - { - DEBUG_PRINT("\n Stop failed"); - } - else - { - sem_wait (&decode_context->sem_synchronize); - } - return 1; -} - -int deinit_decoder (struct video_decoder_context *init_decode) -{ - if (init_decode == NULL) - { - return -1; - } - - /*Close the driver*/ - if (init_decode->video_driver_fd != -1) - { - close (init_decode->video_driver_fd); - } - - if (init_decode->queue_context.ptr_cmdq) - { - free (init_decode->queue_context.ptr_cmdq); - init_decode->queue_context.ptr_cmdq = NULL; - } - - if (init_decode->queue_context.ptr_dataq) - { - free (init_decode->queue_context.ptr_dataq); - init_decode->queue_context.ptr_dataq = NULL; - } - - sem_destroy (&init_decode->queue_context.sem_message); - sem_destroy (&init_decode->sem_synchronize); - - pthread_mutex_destroy(&init_decode->queue_context.mutex); - pthread_mutex_destroy (&read_lock); - - return 1; -} - -static void* video_thread (void *context) -{ - struct video_decoder_context *decode_context = NULL; - struct video_msgq *queueitem = NULL; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - struct vdec_input_frameinfo frameinfo; - struct vdec_fillbuffer_cmd fillbuffer; - struct vdec_output_frameinfo *outputbuffer = NULL; - struct vdec_bufferpayload *tempbuffer = NULL; - unsigned int data_len =0; - - - if (context == NULL) - { - DEBUG_PRINT("\n video thread recieved NULL context"); - return NULL; - } - decode_context = (struct video_decoder_context *) context; - - /* Thread function which will accept commands from async thread - * or main thread - */ - while (1) - { - queueitem = queue_get_cmd (&decode_context ->queue_context); - if (queueitem != NULL) - { - switch (queueitem->cmd) - { - case VDEC_MSG_EVT_HW_ERROR: - DEBUG_PRINT("\n FATAL ERROR "); - break; - case VDEC_MSG_RESP_INPUT_FLUSHED: - DEBUG_PRINT("\n Input Buffer Flushed"); - break; - case VDEC_MSG_RESP_OUTPUT_FLUSHED: - DEBUG_PRINT("\n Output buffer Flushed"); - break; - case VDEC_MSG_RESP_START_DONE: - DEBUG_PRINT("\n recived start done command"); - sem_post (&decode_context->sem_synchronize); - break; - - case VDEC_MSG_RESP_STOP_DONE: - DEBUG_PRINT("\n recieved stop done"); - sem_post (&decode_context->sem_synchronize); - break; - - case VDEC_MSG_RESP_INPUT_BUFFER_DONE: - - tempbuffer = (struct vdec_bufferpayload *)queueitem->clientdata; - if (tempbuffer == NULL) - { - DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); - sem_post (&decode_context->sem_synchronize); - break; - } - data_len = read_frame ( tempbuffer->bufferaddr, - tempbuffer->buffer_len, - decode_context->inputBufferFile - ); - - if (data_len == 0) - { - DEBUG_PRINT ("\n End of stream reached"); - sem_post (&decode_context->sem_synchronize); - break; - } - - frameinfo.bufferaddr = tempbuffer->bufferaddr; - frameinfo.offset = 0; - frameinfo.pmem_fd = tempbuffer->pmem_fd; - frameinfo.pmem_offset = tempbuffer->offset; - frameinfo.datalen = data_len; - frameinfo.client_data = (struct vdec_bufferpayload *)\ - tempbuffer; - /*TODO: Time stamp needs to be updated*/ - ioctl_msg.in = &frameinfo; - ioctl_msg.out = NULL; - total_frames++; - if (ioctl(decode_context->video_driver_fd,VDEC_IOCTL_DECODE_FRAME, - &ioctl_msg) < 0) - { - DEBUG_PRINT("\n Decoder frame failed"); - sem_post (&decode_context->sem_synchronize); - } - DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\ - total_frames); - break; - - case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: - - outputbuffer = (struct vdec_output_frameinfo *)\ - queueitem->clientdata; - DEBUG_PRINT("\n Value of client Data in VT %p",queueitem->clientdata); - if (outputbuffer == NULL || outputbuffer->bufferaddr == NULL || - outputbuffer->client_data == NULL - ) - { - DEBUG_PRINT("\n FATAL ERROR output buffer is bad"); - DEBUG_PRINT("\nValues outputbuffer = %p",outputbuffer); - if (outputbuffer != NULL) - { - DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\ - outputbuffer->bufferaddr); - DEBUG_PRINT("\nValues outputbuffer->client_data = %p",\ - outputbuffer->client_data); - } - sem_post (&decode_context->sem_synchronize); - break; - } - - - if (outputbuffer->len == 0) - { - DEBUG_PRINT("\n Filled Length is zero Close decoding"); - sem_post (&decode_context->sem_synchronize); - break; - } - - if (decode_context->outputBufferFile != NULL) - { - fwrite (outputbuffer->bufferaddr,1,outputbuffer->len, - decode_context->outputBufferFile); - } - - tempbuffer = (struct vdec_bufferpayload *)\ - outputbuffer->client_data; - - DEBUG_PRINT("\n recieved output buffer consume outbuffer"); - DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\ - outputbuffer->bufferaddr); - DEBUG_PRINT ("\n Vir address of allocated buffer %p",\ - tempbuffer->bufferaddr); - fillbuffer.buffer.buffer_len = tempbuffer->buffer_len; - fillbuffer.buffer.bufferaddr = tempbuffer->bufferaddr; - fillbuffer.buffer.offset = tempbuffer->offset; - fillbuffer.buffer.pmem_fd = tempbuffer->pmem_fd; - fillbuffer.client_data = (void *)outputbuffer; - - ioctl_msg.in = &fillbuffer; - ioctl_msg.out = NULL; - - if (ioctl (decode_context->video_driver_fd, - VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Decoder frame failed"); - return NULL; - } - - break; - - case VDEC_MSG_RESP_FLUSH_INPUT_DONE: - DEBUG_PRINT("\n Flush input complete"); - sem_post (&decode_context->sem_synchronize); - break; - - case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: - DEBUG_PRINT("\n Flush output complete"); - sem_post (&decode_context->sem_synchronize); - break; - } - - if (queueitem->cmd == VDEC_MSG_RESP_STOP_DONE) - { - DEBUG_PRINT("\n Playback has ended thread will exit"); - return NULL; - } - } - else - { - DEBUG_PRINT("\n Error condition recieved NULL from Queue"); - } - - } -} - -static void* async_thread (void *context) -{ - struct video_decoder_context *decode_context = NULL; - struct vdec_output_frameinfo *outputframe = NULL; - struct video_msgq queueitem ; - struct vdec_msginfo vdec_msg; - struct vdec_ioctl_msg ioctl_msg = {NULL,NULL}; - int result = -1; - - if (context == NULL) - { - DEBUG_PRINT("\n aynsc thread recieved NULL context"); - return NULL; - } - decode_context = (struct video_decoder_context *) context; - DEBUG_PRINT("\n Entering the async thread"); - - while (1) - { - ioctl_msg.in = NULL; - - ioctl_msg.out = (void*)&vdec_msg; - DEBUG_PRINT ("\n Sizeof vdec_msginfo = %d ",sizeof (vdec_msg)); - DEBUG_PRINT("\n Address of Vdec msg in async thread %p",\ - ioctl_msg.out); - if (ioctl (decode_context->video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG,\ - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Error in ioctl read next msg"); - } - else - { - switch (vdec_msg.msgcode) - { - case VDEC_MSG_RESP_FLUSH_INPUT_DONE: - case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE: - case VDEC_MSG_RESP_START_DONE: - case VDEC_MSG_RESP_STOP_DONE: - case VDEC_MSG_EVT_HW_ERROR: - DEBUG_PRINT("\nioctl read next msg"); - queueitem.cmd = vdec_msg.msgcode; - queueitem.status = vdec_msg.status_code; - queueitem.clientdata = NULL; - break; - - case VDEC_MSG_RESP_INPUT_FLUSHED: - case VDEC_MSG_RESP_INPUT_BUFFER_DONE: - - queueitem.cmd = vdec_msg.msgcode; - queueitem.status = vdec_msg.status_code; - queueitem.clientdata = (void *)\ - vdec_msg.msgdata.input_frame_clientdata; - break; - - case VDEC_MSG_RESP_OUTPUT_FLUSHED: - case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE: - queueitem.cmd = vdec_msg.msgcode; - queueitem.status = vdec_msg.status_code; - outputframe = (struct vdec_output_frameinfo *)\ - vdec_msg.msgdata.output_frame.client_data; - DEBUG_PRINT ("\n Client Data value in %p", \ - vdec_msg.msgdata.output_frame.client_data); - outputframe->bufferaddr = vdec_msg.msgdata.output_frame.bufferaddr; - outputframe->framesize.bottom = \ - vdec_msg.msgdata.output_frame.framesize.bottom; - outputframe->framesize.left = \ - vdec_msg.msgdata.output_frame.framesize.left; - outputframe->framesize.right = \ - vdec_msg.msgdata.output_frame.framesize.right; - outputframe->framesize.top = \ - vdec_msg.msgdata.output_frame.framesize.top; - outputframe->framesize = vdec_msg.msgdata.output_frame.framesize; - outputframe->len = vdec_msg.msgdata.output_frame.len; - outputframe->time_stamp = vdec_msg.msgdata.output_frame.time_stamp; - queueitem.clientdata = (void *)outputframe; - DEBUG_PRINT ("\n Client Data value Copy %p",queueitem.clientdata); - break; - - default: - DEBUG_PRINT("\nIn Default of get next message %d",vdec_msg.msgcode); - queueitem.cmd = vdec_msg.msgcode; - queueitem.status = vdec_msg.status_code; - queueitem.clientdata = NULL; - break; - } - result = queue_post_cmdq (&decode_context->queue_context,&queueitem); - while (result == 0) - { - result = queue_post_cmdq (&decode_context->queue_context, - &queueitem); - } - - if (result == -1) - { - DEBUG_PRINT("\n FATAL ERROR WITH Queue"); - } - } - if (vdec_msg.msgcode == VDEC_MSG_RESP_STOP_DONE) - { - /*Thread can exit at this point*/ - return NULL; - } - } -} - - -static unsigned int read_frame (unsigned char *dataptr, unsigned int length, - FILE * inputBufferFile) -{ - - unsigned int readOffset = 0; - int bytes_read = 0; - unsigned int code = 0; - int found = 0; - - DEBUG_PRINT ("\n Inside the readframe"); - - if (dataptr == NULL || length == 0) - { - DEBUG_PRINT ("\n dataptr = %p length = %u",dataptr,length); - return 0; - } - - if (!Code_type) - { - /* Start of Critical Section*/ - pthread_mutex_lock(&read_lock); - do - { - //Start codes are always byte aligned. - bytes_read = fread(&dataptr[readOffset],1, 1,inputBufferFile); - if( !bytes_read) - { - DEBUG_PRINT("\n Bytes read Zero \n"); - break; - } - code <<= 8; - code |= (0x000000FF & dataptr[readOffset]); - //VOP start code comparision - if (readOffset>3) - { - if(!header_code ) - { - if( VOP_START_CODE == code) - { - DEBUG_PRINT ("\n Found VOP Code"); - header_code = VOP_START_CODE; - } - else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE ) - { - header_code = SHORT_HEADER_START_CODE; - } - } - if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE)) - { - //Seek backwards by 4 - fseek(inputBufferFile, -4, SEEK_CUR); - readOffset-=4; - found = 1; - break; - - } - else if (( header_code == SHORT_HEADER_START_CODE ) && - ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00))) - { - //Seek backwards by 4 - fseek(inputBufferFile, -4, SEEK_CUR); - readOffset-=4; - found = 1; - break; - } - } - readOffset++; - }while (readOffset < length); - pthread_mutex_unlock(&read_lock); - /* End of Critical Section*/ - if (found == 1) - { - //DEBUG_PRINT ("Found a Frame"); - return (readOffset+1); - } - else - { - //DEBUG_PRINT ("No Frames detected"); - return 0; - } - } - else - { - - readOffset = Read_Buffer_From_DAT_File(dataptr,length,inputBufferFile); - if (total_frames == 0) - { - bytes_read = Read_Buffer_From_DAT_File(&dataptr[readOffset], - (length-readOffset), - inputBufferFile); - readOffset += bytes_read; - } - return (readOffset); - } - -} - -static int Read_Buffer_From_DAT_File(unsigned char *dataptr, unsigned int length, - FILE * inputBufferFile) -{ - - - long frameSize=0; - char temp_buffer[10]; - char temp_byte; - int bytes_read=0; - int i=0; - unsigned char *read_buffer=NULL; - char c = '1'; //initialize to anything except '\0'(0) - char inputFrameSize[12]; - int count =0; char cnt =0; - memset(temp_buffer, 0, sizeof(temp_buffer)); - - while (cnt < 10) - /* Check the input file format, may result in infinite loop */ - { - count = fread(&inputFrameSize[cnt],1,1,inputBufferFile); - if(inputFrameSize[cnt] == '\0' ) - break; - cnt++; - } - inputFrameSize[cnt]='\0'; - frameSize = atoi(inputFrameSize); - //length = 0; - DEBUG_PRINT ("\n Frame Size is %d",frameSize); - - /* get the frame length */ - fseek(inputBufferFile, -1, SEEK_CUR); - bytes_read = fread(dataptr, 1, frameSize, inputBufferFile); - - if(bytes_read == 0 || bytes_read < frameSize ) { - return 0; - } - return bytes_read; -} diff --git a/mm-video/vidc/vdec/test/omx_vdec_test.cpp b/mm-video/vidc/vdec/test/omx_vdec_test.cpp deleted file mode 100644 index a191ee28..00000000 --- a/mm-video/vidc/vdec/test/omx_vdec_test.cpp +++ /dev/null @@ -1,4543 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -/* - An Open max test application .... -*/ - -#define LOG_TAG "OMX-VDEC-TEST" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "OMX_QCOMExtns.h" -#include -#include - -#include - -#ifdef _ANDROID_ -#include - -extern "C"{ -#include -} -#define DEBUG_PRINT -#define DEBUG_PRINT_ERROR ALOGE - -//#define __DEBUG_DIVX__ // Define this macro to print (through logcat) - // the kind of frames packed per buffer and - // timestamps adjustments for divx. - -//#define TEST_TS_FROM_SEI // Define this macro to calculate the timestamps - // from the SEI and VUI data for H264 - -#else -#include -#define strlcpy g_strlcpy - -#define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args) -#define DEBUG_PRINT printf -#define DEBUG_PRINT_ERROR printf -#endif /* _ANDROID_ */ - -#include "OMX_Core.h" -#include "OMX_Component.h" -#include "OMX_QCOMExtns.h" -extern "C" { -#include "queue.h" -} - -#include -#include -#include - -/************************************************************************/ -/* #DEFINES */ -/************************************************************************/ -#define DELAY 66 -#define false 0 -#define true 1 -#define H264_START_CODE 0x00000001 -#define VOP_START_CODE 0x000001B6 -#define SHORT_HEADER_START_CODE 0x00008000 -#define MPEG2_FRAME_START_CODE 0x00000100 -#define MPEG2_SEQ_START_CODE 0x000001B3 -#define VC1_START_CODE 0x00000100 -#define VC1_FRAME_START_CODE 0x0000010D -#define VC1_FRAME_FIELD_CODE 0x0000010C -#define VC1_SEQUENCE_START_CODE 0x0000010F -#define VC1_ENTRY_POINT_START_CODE 0x0000010E -#define NUMBER_OF_ARBITRARYBYTES_READ (4 * 1024) -#define VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC 32 -#define VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC 16 -static int previous_vc1_au = 0; -#define CONFIG_VERSION_SIZE(param) \ - param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\ - param.nSize = sizeof(param); - -#define FAILED(result) (result != OMX_ErrorNone) - -#define SUCCEEDED(result) (result == OMX_ErrorNone) -#define SWAPBYTES(ptrA, ptrB) { char t = *ptrA; *ptrA = *ptrB; *ptrB = t;} -#define SIZE_NAL_FIELD_MAX 4 -#define MDP_DEINTERLACE 0x80000000 - -#define ALLOCATE_BUFFER 0 - -#ifdef MAX_RES_720P -#define PMEM_DEVICE "/dev/pmem_adsp" -#elif MAX_RES_1080P_EBI -#define PMEM_DEVICE "/dev/pmem_adsp" -#elif MAX_RES_1080P -#define PMEM_DEVICE "/dev/pmem_smipool" -#endif - -//#define USE_EXTERN_PMEM_BUF - -/************************************************************************/ -/* GLOBAL DECLARATIONS */ -/************************************************************************/ -#ifdef _ANDROID_ -using namespace android; -#endif - -#ifdef _MSM8974_ -typedef unsigned short int uint16; -const uint16 CRC_INIT = 0xFFFF ; - -const uint16 crc_16_l_table[ 256 ] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -#ifdef ANDROID_JELLYBEAN_MR1 -//Since this is unavailable on Android 4.2.2, defining it in terms of base 10 -static inline float log2f(const float& x) { - return log(x) / log(2); -} -#endif - -uint16 crc_16_l_step_nv12 (uint16 seed, const void *buf_ptr, - unsigned int byte_len, unsigned int height, unsigned int width) -{ - uint16 crc_16 = ~seed; - char *buf = (char *)buf_ptr; - char *byte_ptr = buf; - int i, j; - const unsigned int width_align = 32; - const unsigned int height_align = 32; - unsigned int stride = (width + width_align -1) & (~(width_align-1)); - unsigned int scan_lines = (height + height_align -1) & (~(height_align-1)); - for (i = 0; i < height; i++) { - for (j = 0; j < stride; j++) { - if (j < width) { - crc_16 = crc_16_l_table[ (crc_16 ^ *byte_ptr) & 0x00ff ] ^ (crc_16 >> 8); - } - byte_ptr++; - } - } - byte_ptr = buf + (scan_lines * stride); - for (i = scan_lines; i < scan_lines + height/2;i++) { - for (j = 0; j < stride; j++) { - if (j < width) { - crc_16 = crc_16_l_table[ (crc_16 ^ *byte_ptr) & 0x00ff ] ^ (crc_16 >> 8); - } - byte_ptr++; - } - } - return( ~crc_16 ); -} -#endif - -typedef enum { - CODEC_FORMAT_H264 = 1, - CODEC_FORMAT_MP4, - CODEC_FORMAT_H263, - CODEC_FORMAT_VC1, - CODEC_FORMAT_DIVX, - CODEC_FORMAT_MPEG2, -#ifdef _MSM8974_ - CODEC_FORMAT_VP8, - CODEC_FORMAT_HEVC, -#endif - CODEC_FORMAT_MAX -} codec_format; - -typedef enum { - FILE_TYPE_DAT_PER_AU = 1, - FILE_TYPE_ARBITRARY_BYTES, - FILE_TYPE_COMMON_CODEC_MAX, - - FILE_TYPE_START_OF_H264_SPECIFIC = 10, - FILE_TYPE_264_NAL_SIZE_LENGTH = FILE_TYPE_START_OF_H264_SPECIFIC, - FILE_TYPE_264_START_CODE_BASED, - - FILE_TYPE_START_OF_MP4_SPECIFIC = 20, - FILE_TYPE_PICTURE_START_CODE = FILE_TYPE_START_OF_MP4_SPECIFIC, - - FILE_TYPE_START_OF_VC1_SPECIFIC = 30, - FILE_TYPE_RCV = FILE_TYPE_START_OF_VC1_SPECIFIC, - FILE_TYPE_VC1, - - FILE_TYPE_START_OF_DIVX_SPECIFIC = 40, - FILE_TYPE_DIVX_4_5_6 = FILE_TYPE_START_OF_DIVX_SPECIFIC, - FILE_TYPE_DIVX_311, - - FILE_TYPE_START_OF_MPEG2_SPECIFIC = 50, - FILE_TYPE_MPEG2_START_CODE = FILE_TYPE_START_OF_MPEG2_SPECIFIC, - -#ifdef _MSM8974_ - FILE_TYPE_START_OF_VP8_SPECIFIC = 60, - FILE_TYPE_VP8_START_CODE = FILE_TYPE_START_OF_VP8_SPECIFIC, - FILE_TYPE_VP8 -#endif - -} file_type; - -typedef enum { - GOOD_STATE = 0, - PORT_SETTING_CHANGE_STATE, - ERROR_STATE -} test_status; - -typedef enum { - FREE_HANDLE_AT_LOADED = 1, - FREE_HANDLE_AT_IDLE, - FREE_HANDLE_AT_EXECUTING, - FREE_HANDLE_AT_PAUSE -} freeHandle_test; - -struct temp_egl { - int pmem_fd; - int offset; -}; - -static int (*Read_Buffer)(OMX_BUFFERHEADERTYPE *pBufHdr ); - -int inputBufferFileFd; - -FILE * outputBufferFile; -#ifdef _MSM8974_ -FILE * crcFile; -#endif -FILE * seqFile; -int takeYuvLog = 0; -int displayYuv = 0; -int displayWindow = 0; -int realtime_display = 0; -int num_frames_to_decode = 0; -int thumbnailMode = 0; - -Queue *etb_queue = NULL; -Queue *fbd_queue = NULL; - -pthread_t ebd_thread_id; -pthread_t fbd_thread_id; -void* ebd_thread(void*); -void* fbd_thread(void*); - -pthread_mutex_t etb_lock; -pthread_mutex_t fbd_lock; -pthread_mutex_t lock; -pthread_cond_t cond; -pthread_mutex_t eos_lock; -pthread_cond_t eos_cond; -pthread_mutex_t enable_lock; - -sem_t etb_sem; -sem_t fbd_sem; -sem_t seq_sem; -sem_t in_flush_sem, out_flush_sem; - -OMX_PARAM_PORTDEFINITIONTYPE portFmt; -OMX_PORT_PARAM_TYPE portParam; -OMX_ERRORTYPE error; -OMX_COLOR_FORMATTYPE color_fmt; -static bool input_use_buffer = false,output_use_buffer = false; -QOMX_VIDEO_DECODER_PICTURE_ORDER picture_order; - -#ifdef MAX_RES_1080P -unsigned int color_fmt_type = 1; -#else -unsigned int color_fmt_type = 0; -#endif - -#define CLR_KEY 0xe8fd -#define COLOR_BLACK_RGBA_8888 0x00000000 -#define FRAMEBUFFER_32 - -static int fb_fd = -1; -static struct fb_var_screeninfo vinfo; -static struct fb_fix_screeninfo finfo; -static struct mdp_overlay overlay, *overlayp; -static struct msmfb_overlay_data ov_front; -static int vid_buf_front_id; -static char tempbuf[16]; -int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr); -void overlay_set(); -void overlay_unset(); -void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr); -int disable_output_port(); -int enable_output_port(); -int output_port_reconfig(); -void free_output_buffers(); -int open_display(); -void close_display(); -/************************************************************************/ -/* GLOBAL INIT */ -/************************************************************************/ -int input_buf_cnt = 0; -int height =0, width =0; -int sliceheight = 0, stride = 0; -int used_ip_buf_cnt = 0; -unsigned free_op_buf_cnt = 0; -volatile int event_is_done = 0; -int ebd_cnt= 0, fbd_cnt = 0; -int bInputEosReached = 0; -int bOutputEosReached = 0; -char in_filename[512]; -#ifdef _MSM8974_ -char crclogname[512]; -#endif -char seq_file_name[512]; -unsigned char seq_enabled = 0; -bool anti_flickering = true; -unsigned char flush_input_progress = 0, flush_output_progress = 0; -unsigned cmd_data = ~(unsigned)0, etb_count = 0; - -char curr_seq_command[100]; -OMX_S64 timeStampLfile = 0; -int fps = 30; -unsigned int timestampInterval = 33333; -codec_format codec_format_option; -file_type file_type_option; -freeHandle_test freeHandle_option; -int nalSize = 0; -int sent_disabled = 0; -int waitForPortSettingsChanged = 1; -test_status currentStatus = GOOD_STATE; -struct timeval t_start = {0, 0}, t_end = {0, 0}; - -//* OMX Spec Version supported by the wrappers. Version = 1.1 */ -const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101; -OMX_COMPONENTTYPE* dec_handle = 0; - -OMX_BUFFERHEADERTYPE **pInputBufHdrs = NULL; -OMX_BUFFERHEADERTYPE **pOutYUVBufHdrs= NULL; - -static OMX_BOOL use_external_pmem_buf = OMX_FALSE; - -int rcv_v1=0; -static struct temp_egl **p_eglHeaders = NULL; -static unsigned use_buf_virt_addr[32]; - -OMX_QCOM_PLATFORM_PRIVATE_LIST *pPlatformList = NULL; -OMX_QCOM_PLATFORM_PRIVATE_ENTRY *pPlatformEntry = NULL; -OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; -OMX_CONFIG_RECTTYPE crop_rect = {0,0,0,0}; - -static int bHdrflag = 0; - -/* Performance related variable*/ -//QPERF_INIT(render_fb); -//QPERF_INIT(client_decode); - -/************************************************************************/ -/* GLOBAL FUNC DECL */ -/************************************************************************/ -int Init_Decoder(); -int Play_Decoder(); -int run_tests(); - -/**************************************************************************/ -/* STATIC DECLARATIONS */ -/**************************************************************************/ -static int video_playback_count = 1; -static int open_video_file (); -static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr ); -static int Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr); -#ifdef _MSM8974_ -static int Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE *pBufHdr); -#endif -static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE *pBufHdr); -static int Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE *pBufHdr); - -static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***pBufHdrs, - OMX_U32 nPortIndex, - long bufCntMin, long bufSize); - -static OMX_ERRORTYPE use_input_buffer(OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***bufferHdr, - OMX_U32 nPortIndex, - OMX_U32 bufSize, - long bufcnt); - -static OMX_ERRORTYPE use_output_buffer(OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***bufferHdr, - OMX_U32 nPortIndex, - OMX_U32 bufSize, - long bufcnt); - -static OMX_ERRORTYPE use_output_buffer_multiple_fd(OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***bufferHdr, - OMX_U32 nPortIndex, - OMX_U32 bufSize, - long bufcnt); - -static 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); -static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer); -static OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent, - OMX_OUT OMX_PTR pAppData, - OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer); - -static void do_freeHandle_and_clean_up(bool isDueToError); - -#ifndef USE_ION -static bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, - OMX_U32 alignment); -#endif -void getFreePmem(); -static int overlay_vsync_ctrl(int enable); - -static int clip2(int x) - { - x = x -1; - x = x | x >> 1; - x = x | x >> 2; - x = x | x >> 4; - x = x | x >> 16; - x = x + 1; - return x; - } -void wait_for_event(void) -{ - DEBUG_PRINT("Waiting for event\n"); - pthread_mutex_lock(&lock); - while (event_is_done == 0) { - pthread_cond_wait(&cond, &lock); - } - event_is_done = 0; - pthread_mutex_unlock(&lock); - DEBUG_PRINT("Running .... get the event\n"); -} - -void event_complete(void ) -{ - pthread_mutex_lock(&lock); - if (event_is_done == 0) { - event_is_done = 1; - pthread_cond_broadcast(&cond); - } - pthread_mutex_unlock(&lock); -} -int get_next_command(FILE *seq_file) -{ - int i = -1; - do{ - i++; - if(fread(&curr_seq_command[i], 1, 1, seq_file) != 1) - return -1; - }while(curr_seq_command[i] != '\n'); - curr_seq_command[i] = 0; - printf("\n cmd_str = %s", curr_seq_command); - return 0; -} - -int process_current_command(const char *seq_command) -{ - char *data_str = NULL; - unsigned int data = 0, bufCnt = 0, i = 0; - int frameSize; - - if(strstr(seq_command, "pause") == seq_command) - { - printf("\n\n $$$$$ PAUSE $$$$$"); - data_str = (char*)seq_command + strlen("pause") + 1; - data = atoi(data_str); - printf("\n After frame number %u", data); - cmd_data = data; - sem_wait(&seq_sem); - if (!bOutputEosReached && !bInputEosReached) - { - printf("\n Sending PAUSE cmd to OMX compt"); - OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0); - wait_for_event(); - printf("\n EventHandler for PAUSE DONE"); - } - else - seq_enabled = 0; - } - else if(strstr(seq_command, "sleep") == seq_command) - { - printf("\n\n $$$$$ SLEEP $$$$$"); - data_str = (char*)seq_command + strlen("sleep") + 1; - data = atoi(data_str); - printf("\n Sleep Time = %u ms", data); - usleep(data*1000); - } - else if(strstr(seq_command, "resume") == seq_command) - { - printf("\n\n $$$$$ RESUME $$$$$"); - printf("\n Immediate effect"); - printf("\n Sending RESUME cmd to OMX compt"); - OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0); - wait_for_event(); - printf("\n EventHandler for RESUME DONE"); - } - else if(strstr(seq_command, "flush") == seq_command) - { - printf("\n\n $$$$$ FLUSH $$$$$"); - data_str = (char*)seq_command + strlen("flush") + 1; - data = atoi(data_str); - printf("\n After frame number %u", data); - if (previous_vc1_au) - { - printf("\n Flush not allowed on Field boundary"); - return 0; - } - cmd_data = data; - sem_wait(&seq_sem); - if (!bOutputEosReached && !bInputEosReached) - { - printf("\n Sending FLUSH cmd to OMX compt"); - flush_input_progress = 1; - flush_output_progress = 1; - OMX_SendCommand(dec_handle, OMX_CommandFlush, OMX_ALL, 0); - wait_for_event(); - printf("\n EventHandler for FLUSH DONE"); - printf("\n Post EBD_thread flush sem"); - sem_post(&in_flush_sem); - printf("\n Post FBD_thread flush sem"); - sem_post(&out_flush_sem); - } - else - seq_enabled = 0; - } - else if(strstr(seq_command, "disable_op") == seq_command) - { - printf("\n\n $$$$$ DISABLE OP PORT $$$$$"); - data_str = (char*)seq_command + strlen("disable_op") + 1; - data = atoi(data_str); - printf("\n After frame number %u", data); - cmd_data = data; - sem_wait(&seq_sem); - printf("\n Sending DISABLE OP cmd to OMX compt"); - if (disable_output_port() != 0) - { - printf("\n ERROR: While DISABLE OP..."); - do_freeHandle_and_clean_up(true); - return -1; - } - else - printf("\n EventHandler for DISABLE OP"); - } - else if(strstr(seq_command, "enable_op") == seq_command) - { - printf("\n\n $$$$$ ENABLE OP PORT $$$$$"); - data_str = (char*)seq_command + strlen("enable_op") + 1; - printf("\n Sending ENABLE OP cmd to OMX compt"); - if (enable_output_port() != 0) - { - printf("\n ERROR: While ENABLE OP..."); - do_freeHandle_and_clean_up(true); - return -1; - } - else - printf("\n EventHandler for ENABLE OP"); - } - else - { - printf("\n\n $$$$$ INVALID CMD $$$$$"); - printf("\n seq_command[%s] is invalid", seq_command); - seq_enabled = 0; - } - return 0; -} - -void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement) -{ - printf("id (%d)\n", - framePackingArrangement.id); - printf("cancel_flag (%d)\n", - framePackingArrangement.cancel_flag); - printf("type (%d)\n", - framePackingArrangement.type); - printf("quincunx_sampling_flag (%d)\n", - framePackingArrangement.quincunx_sampling_flag); - printf("content_interpretation_type (%d)\n", - framePackingArrangement.content_interpretation_type); - printf("spatial_flipping_flag (%d)\n", - framePackingArrangement.spatial_flipping_flag); - printf("frame0_flipped_flag (%d)\n", - framePackingArrangement.frame0_flipped_flag); - printf("field_views_flag (%d)\n", - framePackingArrangement.field_views_flag); - printf("current_frame_is_frame0_flag (%d)\n", - framePackingArrangement.current_frame_is_frame0_flag); - printf("frame0_self_contained_flag (%d)\n", - framePackingArrangement.frame0_self_contained_flag); - printf("frame1_self_contained_flag (%d)\n", - framePackingArrangement.frame1_self_contained_flag); - printf("frame0_grid_position_x (%d)\n", - framePackingArrangement.frame0_grid_position_x); - printf("frame0_grid_position_y (%d)\n", - framePackingArrangement.frame0_grid_position_y); - printf("frame1_grid_position_x (%d)\n", - framePackingArrangement.frame1_grid_position_x); - printf("frame1_grid_position_y (%d)\n", - framePackingArrangement.frame1_grid_position_y); - printf("reserved_byte (%d)\n", - framePackingArrangement.reserved_byte); - printf("repetition_period (%d)\n", - framePackingArrangement.repetition_period); - printf("extension_flag (%d)\n", - framePackingArrangement.extension_flag); -} -void* ebd_thread(void* pArg) -{ - int signal_eos = 0; - while(currentStatus != ERROR_STATE) - { - int readBytes =0; - OMX_BUFFERHEADERTYPE* pBuffer = NULL; - - if(flush_input_progress) - { - DEBUG_PRINT("\n EBD_thread flush wait start"); - sem_wait(&in_flush_sem); - DEBUG_PRINT("\n EBD_thread flush wait complete"); - } - - sem_wait(&etb_sem); - pthread_mutex_lock(&etb_lock); - pBuffer = (OMX_BUFFERHEADERTYPE *) pop(etb_queue); - pthread_mutex_unlock(&etb_lock); - if(pBuffer == NULL) - { - DEBUG_PRINT_ERROR("Error - No etb pBuffer to dequeue\n"); - continue; - } - - if (num_frames_to_decode && (etb_count >= num_frames_to_decode)) { - printf("\n Signal EOS %d frames decoded \n", num_frames_to_decode); - signal_eos = 1; - } - - pBuffer->nOffset = 0; - if(((readBytes = Read_Buffer(pBuffer)) > 0) && !signal_eos) { - pBuffer->nFilledLen = readBytes; - DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pBuffer->nTimeStamp); - OMX_EmptyThisBuffer(dec_handle,pBuffer); - etb_count++; - } - else - { - pBuffer->nFlags |= OMX_BUFFERFLAG_EOS; - bInputEosReached = true; - pBuffer->nFilledLen = readBytes; - DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pBuffer->nTimeStamp); - OMX_EmptyThisBuffer(dec_handle,pBuffer); - DEBUG_PRINT("EBD::Either EOS or Some Error while reading file\n"); - etb_count++; - break; - } - } - return NULL; -} - -void* fbd_thread(void* pArg) -{ - long unsigned act_time = 0, display_time = 0, render_time = 5e3, lipsync = 15e3; - struct timeval t_avsync = {0, 0}, base_avsync = {0, 0}; - float total_time = 0; - int canDisplay = 1, contigous_drop_frame = 0, bytes_written = 0, ret = 0; - OMX_S64 base_timestamp = 0, lastTimestamp = 0; - OMX_BUFFERHEADERTYPE *pBuffer = NULL, *pPrevBuff = NULL; - char value[PROPERTY_VALUE_MAX] = {0}; - OMX_U32 aspectratio_prop = 0; - pthread_mutex_lock(&eos_lock); -#ifdef _MSM8974_ - int stride,scanlines,stride_c,i; -#endif - DEBUG_PRINT("First Inside %s\n", __FUNCTION__); - property_get("vidc.vdec.debug.aspectratio", value, "0"); - aspectratio_prop = atoi(value); - while(currentStatus != ERROR_STATE && !bOutputEosReached) - { - pthread_mutex_unlock(&eos_lock); - DEBUG_PRINT("Inside %s\n", __FUNCTION__); - if(flush_output_progress) - { - DEBUG_PRINT("\n FBD_thread flush wait start"); - sem_wait(&out_flush_sem); - DEBUG_PRINT("\n FBD_thread flush wait complete"); - } - sem_wait(&fbd_sem); - pthread_mutex_lock(&enable_lock); - if (sent_disabled) - { - pthread_mutex_unlock(&enable_lock); - pthread_mutex_lock(&fbd_lock); - if (pPrevBuff != NULL ) { - if(push(fbd_queue, (void *)pBuffer)) - DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); - else - sem_post(&fbd_sem); - pPrevBuff = NULL; - } - if (free_op_buf_cnt == portFmt.nBufferCountActual) - free_output_buffers(); - pthread_mutex_unlock(&fbd_lock); - pthread_mutex_lock(&eos_lock); - continue; - } - pthread_mutex_unlock(&enable_lock); - if (anti_flickering) - pPrevBuff = pBuffer; - pthread_mutex_lock(&fbd_lock); - pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue); - pthread_mutex_unlock(&fbd_lock); - if (pBuffer == NULL) - { - if (anti_flickering) - pBuffer = pPrevBuff; - DEBUG_PRINT("Error - No pBuffer to dequeue\n"); - pthread_mutex_lock(&eos_lock); - continue; - } - else if (pBuffer->nFilledLen > 0) - { - if (!fbd_cnt) - { - gettimeofday(&t_start, NULL); - } - fbd_cnt++; - DEBUG_PRINT("%s: fbd_cnt(%d) Buf(%p) Timestamp(%lld)", - __FUNCTION__, fbd_cnt, pBuffer, pBuffer->nTimeStamp); - canDisplay = 1; - if (realtime_display) - { - if (pBuffer->nTimeStamp != (lastTimestamp + timestampInterval)) - { - DEBUG_PRINT("Unexpected timestamp[%lld]! Expected[%lld]\n", - pBuffer->nTimeStamp, lastTimestamp + timestampInterval); - } - lastTimestamp = pBuffer->nTimeStamp; - gettimeofday(&t_avsync, NULL); - if (!base_avsync.tv_sec && !base_avsync.tv_usec) - { - display_time = 0; - base_avsync = t_avsync; - base_timestamp = pBuffer->nTimeStamp; - DEBUG_PRINT("base_avsync Sec(%lu) uSec(%lu) base_timestamp(%lld)", - base_avsync.tv_sec, base_avsync.tv_usec, base_timestamp); - } - else - { - act_time = (t_avsync.tv_sec - base_avsync.tv_sec) * 1e6 - + t_avsync.tv_usec - base_avsync.tv_usec; - display_time = pBuffer->nTimeStamp - base_timestamp; - DEBUG_PRINT("%s: act_time(%lu) display_time(%lu)", - __FUNCTION__, act_time, display_time); - //Frame rcvd on time - if (((act_time + render_time) >= (display_time - lipsync) && - (act_time + render_time) <= (display_time + lipsync)) || - //Display late frame - (contigous_drop_frame > 5)) - display_time = 0; - else if ((act_time + render_time) < (display_time - lipsync)) - //Delaying early frame - display_time -= (lipsync + act_time + render_time); - else - { - //Dropping late frame - canDisplay = 0; - contigous_drop_frame++; - } - } - } - if (displayYuv && canDisplay) - { - if (display_time) - usleep(display_time); - ret = overlay_fb(pBuffer); - if (ret != 0) - { - printf("\nERROR in overlay_fb, disabling display!"); - close_display(); - displayYuv = 0; - } - usleep(render_time); - contigous_drop_frame = 0; - } - - if (takeYuvLog) - { - if (color_fmt == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) - { - printf("\n width: %d height: %d\n", crop_rect.nWidth, crop_rect.nHeight); - unsigned int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portFmt.format.video.nFrameWidth); - unsigned int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portFmt.format.video.nFrameHeight); - char *temp = (char *) pBuffer->pBuffer; - int i = 0; - - temp += (stride * (int)crop_rect.nTop) + (int)crop_rect.nLeft; - for (i = 0; i < crop_rect.nHeight; i++) { - bytes_written = fwrite(temp, crop_rect.nWidth, 1, outputBufferFile); - temp += stride; - } - - temp = (char *)pBuffer->pBuffer + stride * scanlines; - temp += (stride * (int)crop_rect.nTop) + (int)crop_rect.nLeft; - for(i = 0; i < crop_rect.nHeight/2; i++) { - bytes_written += fwrite(temp, crop_rect.nWidth, 1, outputBufferFile); - temp += stride; - } - } - else - { - bytes_written = fwrite((const char *)pBuffer->pBuffer, - pBuffer->nFilledLen,1,outputBufferFile); - } - if (bytes_written < 0) { - DEBUG_PRINT("\nFillBufferDone: Failed to write to the file\n"); - } - else { - DEBUG_PRINT("\nFillBufferDone: Wrote %d YUV bytes to the file\n", - bytes_written); - } - } -#ifdef _MSM8974_ - if (crcFile) { - uint16 crc_val; - crc_val = crc_16_l_step_nv12(CRC_INIT, pBuffer->pBuffer, - pBuffer->nFilledLen, height, width); - int num_bytes = fwrite(&crc_val, 1, sizeof(crc_val), crcFile); - if (num_bytes < sizeof(crc_val)) { - printf("Failed to write CRC value into file\n"); - } - } -#endif - if (pBuffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) - { - OMX_OTHER_EXTRADATATYPE *pExtra; - DEBUG_PRINT(">> BUFFER WITH EXTRA DATA RCVD <<<"); - pExtra = (OMX_OTHER_EXTRADATATYPE *) - ((unsigned)(pBuffer->pBuffer + pBuffer->nOffset + - pBuffer->nFilledLen + 3)&(~3)); - while(pExtra && - (OMX_U8*)pExtra < (pBuffer->pBuffer + pBuffer->nAllocLen) && - pExtra->eType != OMX_ExtraDataNone ) - { - DEBUG_PRINT("ExtraData : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)", - pBuffer, pBuffer->nTimeStamp, pExtra->eType, pExtra->nDataSize); - switch (pExtra->eType) - { - case OMX_ExtraDataInterlaceFormat: - { - OMX_STREAMINTERLACEFORMAT *pInterlaceFormat = (OMX_STREAMINTERLACEFORMAT *)pExtra->data; - DEBUG_PRINT("OMX_ExtraDataInterlaceFormat: Buf(%p) TSmp(%lld) IntPtr(%p) Fmt(%x)", - pBuffer->pBuffer, pBuffer->nTimeStamp, - pInterlaceFormat, pInterlaceFormat->nInterlaceFormats); - break; - } - case OMX_ExtraDataFrameInfo: - { - OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtra->data; - DEBUG_PRINT("OMX_ExtraDataFrameInfo: Buf(%p) TSmp(%lld) PicType(%u) IntT(%u) ConMB(%u)", - pBuffer->pBuffer, pBuffer->nTimeStamp, frame_info->ePicType, - frame_info->interlaceType, frame_info->nConcealedMacroblocks); - if (aspectratio_prop) - DEBUG_PRINT_ERROR(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)", - frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, - frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, - frame_info->displayAspectRatio.displayVerticalSize); - else - DEBUG_PRINT(" FrmRate(%u), AspRatioX(%u), AspRatioY(%u) DispWidth(%u) DispHeight(%u)", - frame_info->nFrameRate, frame_info->aspectRatio.aspectRatioX, - frame_info->aspectRatio.aspectRatioY, frame_info->displayAspectRatio.displayHorizontalSize, - frame_info->displayAspectRatio.displayVerticalSize); - DEBUG_PRINT("PANSCAN numWindows(%d)", frame_info->panScan.numWindows); - for (int i = 0; i < frame_info->panScan.numWindows; i++) - { - DEBUG_PRINT("WINDOW Lft(%d) Tp(%d) Rgt(%d) Bttm(%d)", - frame_info->panScan.window[i].x, - frame_info->panScan.window[i].y, - frame_info->panScan.window[i].dx, - frame_info->panScan.window[i].dy); - } - break; - } - break; - case OMX_ExtraDataConcealMB: - { - OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; - OMX_U32 concealMBnum = 0, bytes_cnt = 0; - while (bytes_cnt < pExtra->nDataSize) - { - data = *data_ptr; - while (data) - { - concealMBnum += (data&0x01); - data >>= 1; - } - data_ptr++; - bytes_cnt++; - } - DEBUG_PRINT("OMX_ExtraDataConcealMB: Buf(%p) TSmp(%lld) ConcealMB(%u)", - pBuffer->pBuffer, pBuffer->nTimeStamp, concealMBnum); - } - break; - case OMX_ExtraDataMP2ExtnData: - { - DEBUG_PRINT("\nOMX_ExtraDataMP2ExtnData"); - OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; - OMX_U32 bytes_cnt = 0; - while (bytes_cnt < pExtra->nDataSize) - { - DEBUG_PRINT("\n MPEG-2 Extension Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); - data_ptr++; - bytes_cnt++; - } - } - break; - case OMX_ExtraDataMP2UserData: - { - DEBUG_PRINT("\nOMX_ExtraDataMP2UserData"); - OMX_U8 data = 0, *data_ptr = (OMX_U8 *)pExtra->data; - OMX_U32 bytes_cnt = 0; - while (bytes_cnt < pExtra->nDataSize) - { - DEBUG_PRINT("\n MPEG-2 User Data Values[%d] = 0x%x", bytes_cnt, *data_ptr); - data_ptr++; - bytes_cnt++; - } - } - break; - default: - DEBUG_PRINT_ERROR("Unknown Extrata!"); - } - if (pExtra->nSize < (pBuffer->nAllocLen - (OMX_U32)pExtra)) - pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) pExtra) + pExtra->nSize); - else - { - DEBUG_PRINT_ERROR("ERROR: Extradata pointer overflow buffer(%p) extra(%p)", - pBuffer, pExtra); - pExtra = NULL; - } - } - } - } - if(pBuffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) - { - DEBUG_PRINT("\n"); - DEBUG_PRINT("***************************************************\n"); - DEBUG_PRINT("FillBufferDone: End Of Sequence Received\n"); - DEBUG_PRINT("***************************************************\n"); - } - if(pBuffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) - { - DEBUG_PRINT("\n"); - DEBUG_PRINT("***************************************************\n"); - DEBUG_PRINT("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n"); - DEBUG_PRINT("***************************************************\n"); - } - /********************************************************************/ - /* De-Initializing the open max and relasing the buffers and */ - /* closing the files.*/ - /********************************************************************/ - if (pBuffer->nFlags & OMX_BUFFERFLAG_EOS ) - { - OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement; - OMX_GetConfig(dec_handle, - (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement, - &framePackingArrangement); - PrintFramePackArrangement(framePackingArrangement); - - gettimeofday(&t_end, NULL); - total_time = ((float) ((t_end.tv_sec - t_start.tv_sec) * 1e6 - + t_end.tv_usec - t_start.tv_usec))/ 1e6; - //total frames is fbd_cnt - 1 since the start time is - //recorded after the first frame is decoded. - printf("\nAvg decoding frame rate=%f\n", (fbd_cnt - 1)/total_time); - - DEBUG_PRINT("***************************************************\n"); - DEBUG_PRINT("FillBufferDone: End Of Stream Reached\n"); - DEBUG_PRINT("***************************************************\n"); - pthread_mutex_lock(&eos_lock); - bOutputEosReached = true; - break; - } - - pthread_mutex_lock(&enable_lock); - if (flush_output_progress || sent_disabled) - { - pBuffer->nFilledLen = 0; - pBuffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA; - pthread_mutex_lock(&fbd_lock); - if ( pPrevBuff != NULL ) { - if(push(fbd_queue, (void *)pPrevBuff)) - DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); - else - sem_post(&fbd_sem); - pPrevBuff = NULL; - } - if(push(fbd_queue, (void *)pBuffer) < 0) - { - DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); - } - else - sem_post(&fbd_sem); - pthread_mutex_unlock(&fbd_lock); - } - else - { - if (!anti_flickering) - pPrevBuff = pBuffer; - if (pPrevBuff) - { - pthread_mutex_lock(&fbd_lock); - pthread_mutex_lock(&eos_lock); - if (!bOutputEosReached) - { - if ( OMX_FillThisBuffer(dec_handle, pPrevBuff) == OMX_ErrorNone ) { - free_op_buf_cnt--; - } - } - pthread_mutex_unlock(&eos_lock); - pthread_mutex_unlock(&fbd_lock); - } - } - pthread_mutex_unlock(&enable_lock); - if(cmd_data <= fbd_cnt) - { - sem_post(&seq_sem); - printf("\n Posted seq_sem Frm(%d) Req(%d)", fbd_cnt, cmd_data); - cmd_data = ~(unsigned)0; - } - pthread_mutex_lock(&eos_lock); - } - if(seq_enabled) - { - seq_enabled = 0; - sem_post(&seq_sem); - printf("\n Posted seq_sem in EOS \n"); - } - pthread_cond_broadcast(&eos_cond); - pthread_mutex_unlock(&eos_lock); - return NULL; -} - -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) -{ - DEBUG_PRINT("Function %s \n", __FUNCTION__); - - switch(eEvent) { - case OMX_EventCmdComplete: - DEBUG_PRINT("\n OMX_EventCmdComplete \n"); - if(OMX_CommandPortDisable == (OMX_COMMANDTYPE)nData1) - { - DEBUG_PRINT("*********************************************\n"); - DEBUG_PRINT("Recieved DISABLE Event Command Complete[%d]\n",nData2); - DEBUG_PRINT("*********************************************\n"); - } - else if(OMX_CommandPortEnable == (OMX_COMMANDTYPE)nData1) - { - DEBUG_PRINT("*********************************************\n"); - DEBUG_PRINT("Recieved ENABLE Event Command Complete[%d]\n",nData2); - DEBUG_PRINT("*********************************************\n"); - if (currentStatus == PORT_SETTING_CHANGE_STATE) - currentStatus = GOOD_STATE; - pthread_mutex_lock(&enable_lock); - sent_disabled = 0; - pthread_mutex_unlock(&enable_lock); - } - else if(OMX_CommandFlush == (OMX_COMMANDTYPE)nData1) - { - DEBUG_PRINT("*********************************************\n"); - DEBUG_PRINT("Received FLUSH Event Command Complete[%d]\n",nData2); - DEBUG_PRINT("*********************************************\n"); - if (nData2 == 0) - flush_input_progress = 0; - else if (nData2 == 1) - flush_output_progress = 0; - } - if (!flush_input_progress && !flush_output_progress) - event_complete(); - break; - - case OMX_EventError: - printf("*********************************************\n"); - printf("Received OMX_EventError Event Command !\n"); - printf("*********************************************\n"); - currentStatus = ERROR_STATE; - if (OMX_ErrorInvalidState == (OMX_ERRORTYPE)nData1 || - OMX_ErrorHardware == (OMX_ERRORTYPE)nData1) - { - printf("Invalid State or hardware error \n"); - if(event_is_done == 0) - { - DEBUG_PRINT("Event error in the middle of Decode \n"); - pthread_mutex_lock(&eos_lock); - bOutputEosReached = true; - pthread_mutex_unlock(&eos_lock); - if(seq_enabled) - { - seq_enabled = 0; - sem_post(&seq_sem); - printf("\n Posted seq_sem in ERROR"); - } - } - } - if (waitForPortSettingsChanged) - { - waitForPortSettingsChanged = 0; - event_complete(); - } - break; - case OMX_EventPortSettingsChanged: - DEBUG_PRINT("OMX_EventPortSettingsChanged port[%d]\n", nData1); - if (nData2 == OMX_IndexConfigCommonOutputCrop) { - OMX_U32 outPortIndex = 1; - if (nData1 == outPortIndex) { - crop_rect.nPortIndex = outPortIndex; - OMX_ERRORTYPE ret = OMX_GetConfig(dec_handle, - OMX_IndexConfigCommonOutputCrop, &crop_rect); - if (FAILED(ret)) { - DEBUG_PRINT_ERROR("Failed to get crop rectangle\n"); - break; - } else - DEBUG_PRINT("Got Crop Rect: (%d, %d) (%d x %d)\n", - crop_rect.nLeft, crop_rect.nTop, crop_rect.nWidth, crop_rect.nHeight); - } - currentStatus = GOOD_STATE; - break; - } - -#ifdef _MSM8974_ - if (nData2 != OMX_IndexParamPortDefinition) - break; -#endif - currentStatus = PORT_SETTING_CHANGE_STATE; - if (waitForPortSettingsChanged) - { - waitForPortSettingsChanged = 0; - event_complete(); - } - else - { - pthread_mutex_lock(&eos_lock); - pthread_cond_broadcast(&eos_cond); - pthread_mutex_unlock(&eos_lock); - } - break; - - case OMX_EventBufferFlag: - DEBUG_PRINT("OMX_EventBufferFlag port[%d] flags[%x]\n", nData1, nData2); -#if 0 - // we should not set the bOutputEosReached here. in stead we wait until fbd_thread to - // check the flag so that all frames can be dumped for bit exactness check. - if (nData1 == 1 && (nData2 & OMX_BUFFERFLAG_EOS)) { - pthread_mutex_lock(&eos_lock); - bOutputEosReached = true; - pthread_mutex_unlock(&eos_lock); - if(seq_enabled) - { - seq_enabled = 0; - sem_post(&seq_sem); - printf("\n Posted seq_sem in OMX_EventBufferFlag"); - } - } - else - { - DEBUG_PRINT_ERROR("OMX_EventBufferFlag Event not handled\n"); - } -#endif - break; - case OMX_EventIndexsettingChanged: - DEBUG_PRINT("OMX_EventIndexSettingChanged Interlace mode[%x]\n", nData1); - break; - default: - DEBUG_PRINT_ERROR("ERROR - Unknown Event \n"); - break; - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) -{ - int readBytes =0; int bufCnt=0; - OMX_ERRORTYPE result; - - DEBUG_PRINT("Function %s cnt[%d]\n", __FUNCTION__, ebd_cnt); - ebd_cnt++; - - - if(bInputEosReached) { - DEBUG_PRINT("*****EBD:Input EoS Reached************\n"); - return OMX_ErrorNone; - } - - pthread_mutex_lock(&etb_lock); - if(push(etb_queue, (void *) pBuffer) < 0) - { - DEBUG_PRINT_ERROR("Error in enqueue ebd data\n"); - return OMX_ErrorUndefined; - } - pthread_mutex_unlock(&etb_lock); - sem_post(&etb_sem); - - return OMX_ErrorNone; -} - -OMX_ERRORTYPE FillBufferDone(OMX_OUT OMX_HANDLETYPE hComponent, - OMX_OUT OMX_PTR pAppData, - OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) -{ - DEBUG_PRINT("Inside %s callback_count[%d] \n", __FUNCTION__, fbd_cnt); - - /* Test app will assume there is a dynamic port setting - * In case that there is no dynamic port setting, OMX will not call event cb, - * instead OMX will send empty this buffer directly and we need to clear an event here - */ - if(waitForPortSettingsChanged) - { - waitForPortSettingsChanged = 0; - if(displayYuv) - overlay_set(); - event_complete(); - } - - pthread_mutex_lock(&fbd_lock); - free_op_buf_cnt++; - if(push(fbd_queue, (void *)pBuffer) < 0) - { - pthread_mutex_unlock(&fbd_lock); - DEBUG_PRINT_ERROR("Error in enqueueing fbd_data\n"); - return OMX_ErrorUndefined; - } - pthread_mutex_unlock(&fbd_lock); - sem_post(&fbd_sem); - - return OMX_ErrorNone; -} - -int main(int argc, char **argv) -{ - int i=0; - int bufCnt=0; - int num=0; - int outputOption = 0; - int test_option = 0; - int pic_order = 0; - OMX_ERRORTYPE result; - sliceheight = height = 144; - stride = width = 176; - - crop_rect.nLeft = 0; - crop_rect.nTop = 0; - crop_rect.nWidth = width; - crop_rect.nHeight = height; - - - if (argc < 2) - { - printf("To use it: ./mm-vdec-omx-test \n"); - printf("Command line argument is also available\n"); - return -1; - } - - strlcpy(in_filename, argv[1], strlen(argv[1])+1); -#ifdef _MSM8974_ - strlcpy(crclogname, argv[1], strlen(argv[1])+1); - strcat(crclogname, ".crc"); -#endif - if(argc > 2) - { - codec_format_option = (codec_format)atoi(argv[2]); - // file_type, out_op, tst_op, nal_sz, disp_win, rt_dis, (fps), color, pic_order, num_frames_to_decode - int param[10] = {2, 1, 1, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF}; - int next_arg = 3, idx = 0; - while (argc > next_arg && idx < 10) - { - if (strlen(argv[next_arg]) > 2) - { - strlcpy(seq_file_name, argv[next_arg],strlen(argv[next_arg]) + 1); - next_arg = argc; - } - else - param[idx++] = atoi(argv[next_arg++]); - } - idx = 0; - file_type_option = (file_type)param[idx++]; - if (codec_format_option == CODEC_FORMAT_H264 && file_type_option == 3) - { - nalSize = param[idx++]; - if (nalSize != 2 && nalSize != 4) - { - printf("Error - Can't pass NAL length size = %d\n", nalSize); - return -1; - } - } - outputOption = param[idx++]; - test_option = param[idx++]; - if ((outputOption == 1 || outputOption ==3) && test_option != 3) { - displayWindow = param[idx++]; - if (displayWindow > 0) - printf("Only entire display window supported! Ignoring value\n"); - realtime_display = param[idx++]; - } - if (realtime_display) - { - takeYuvLog = 0; - if(param[idx] != 0xFF) - { - fps = param[idx++]; - timestampInterval = 1e6 / fps; - } - } - color_fmt_type = (param[idx] != 0xFF)? param[idx++] : color_fmt_type; - if (test_option != 3) { - pic_order = (param[idx] != 0xFF)? param[idx++] : 0; - num_frames_to_decode = param[idx++]; - } - printf("Executing DynPortReconfig QCIF 144 x 176 \n"); - } - else - { - printf("Command line argument is available\n"); - printf("To use it: ./mm-vdec-omx-test \n"); - printf(" \n"); - printf(" \n\n\n"); - printf(" *********************************************\n"); - printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n"); - printf(" *********************************************\n"); - printf(" 1--> H264\n"); - printf(" 2--> MP4\n"); - printf(" 3--> H263\n"); - printf(" 4--> VC1\n"); - printf(" 5--> DivX\n"); - printf(" 6--> MPEG2\n"); -#ifdef _MSM8974_ - printf(" 7--> VP8\n"); - printf(" 8--> HEVC\n"); -#endif - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&codec_format_option); - fflush(stdin); - if (codec_format_option > CODEC_FORMAT_MAX) - { - printf(" Wrong test case...[%d] \n", codec_format_option); - return -1; - } - printf(" *********************************************\n"); - printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n"); - printf(" *********************************************\n"); - printf(" 1--> PER ACCESS UNIT CLIP (.dat). Clip only available for H264 and Mpeg4\n"); - printf(" 2--> ARBITRARY BYTES (need .264/.264c/.m4v/.263/.rcv/.vc1/.m2v)\n"); - if (codec_format_option == CODEC_FORMAT_H264) - { - printf(" 3--> NAL LENGTH SIZE CLIP (.264c)\n"); - printf(" 4--> START CODE BASED CLIP (.264/.h264)\n"); - } - else if ( (codec_format_option == CODEC_FORMAT_MP4) || (codec_format_option == CODEC_FORMAT_H263) ) - { - printf(" 3--> MP4 VOP or H263 P0 SHORT HEADER START CODE CLIP (.m4v or .263)\n"); - } - else if (codec_format_option == CODEC_FORMAT_VC1) - { - printf(" 3--> VC1 clip Simple/Main Profile (.rcv)\n"); - printf(" 4--> VC1 clip Advance Profile (.vc1)\n"); - } - else if (codec_format_option == CODEC_FORMAT_DIVX) - { - printf(" 3--> DivX 4, 5, 6 clip (.cmp)\n"); -#ifdef MAX_RES_1080P - printf(" 4--> DivX 3.11 clip \n"); -#endif - } - else if (codec_format_option == CODEC_FORMAT_MPEG2) - { - printf(" 3--> MPEG2 START CODE CLIP (.m2v)\n"); - } -#ifdef _MSM8974_ - else if (codec_format_option == CODEC_FORMAT_VP8) - { - printf(" 61--> VP8 START CODE CLIP (.ivf)\n"); - } -#endif - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&file_type_option); -#ifdef _MSM8974_ - if (codec_format_option == CODEC_FORMAT_VP8) - { - file_type_option = FILE_TYPE_VP8; - } -#endif - fflush(stdin); - if (codec_format_option == CODEC_FORMAT_H264 && file_type_option == 3) - { - printf(" Enter Nal length size [2 or 4] \n"); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&nalSize); - if (nalSize != 2 && nalSize != 4) - { - printf("Error - Can't pass NAL length size = %d\n", nalSize); - return -1; - } - } - - printf(" *********************************************\n"); - printf(" Output buffer option:\n"); - printf(" *********************************************\n"); - printf(" 0 --> No display and no YUV log\n"); - printf(" 1 --> Diplay YUV\n"); - printf(" 2 --> Take YUV log\n"); - printf(" 3 --> Display YUV and take YUV log\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&outputOption); - fflush(stdin); - - printf(" *********************************************\n"); - printf(" ENTER THE TEST CASE YOU WOULD LIKE TO EXECUTE\n"); - printf(" *********************************************\n"); - printf(" 1 --> Play the clip till the end\n"); - printf(" 2 --> Run compliance test. Do NOT expect any display for most option. \n"); - printf(" Please only see \"TEST SUCCESSFULL\" to indicate test pass\n"); - printf(" 3 --> Thumbnail decode mode\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&test_option); - fflush(stdin); - if (test_option == 3) - thumbnailMode = 1; - - if ((outputOption == 1 || outputOption == 3) && thumbnailMode == 0) - { - printf(" *********************************************\n"); - printf(" ENTER THE PORTION OF DISPLAY TO USE\n"); - printf(" *********************************************\n"); - printf(" 0 --> Entire Screen\n"); - printf(" 1 --> 1/4 th of the screen starting from top left corner to middle \n"); - printf(" 2 --> 1/4 th of the screen starting from middle to top right corner \n"); - printf(" 3 --> 1/4 th of the screen starting from middle to bottom left \n"); - printf(" 4 --> 1/4 th of the screen starting from middle to bottom right \n"); - printf(" Please only see \"TEST SUCCESSFULL\" to indidcate test pass\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&displayWindow); - fflush(stdin); - if(displayWindow > 0) - { - printf(" Curently display window 0 only supported; ignoring other values\n"); - displayWindow = 0; - } - } - - if ((outputOption == 1 || outputOption == 3) && thumbnailMode == 0) - { - printf(" *********************************************\n"); - printf(" DO YOU WANT TEST APP TO RENDER in Real time \n"); - printf(" 0 --> NO\n 1 --> YES\n"); - printf(" Warning: For H264, it require one NAL per frame clip.\n"); - printf(" For Arbitrary bytes option, Real time display is not recommended\n"); - printf(" *********************************************\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&realtime_display); - fflush(stdin); - } - - - if (realtime_display) - { - printf(" *********************************************\n"); - printf(" ENTER THE CLIP FPS\n"); - printf(" Exception: Timestamp extracted from clips will be used.\n"); - printf(" *********************************************\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&fps); - fflush(stdin); - timestampInterval = 1000000/fps; - } - - printf(" *********************************************\n"); - printf(" ENTER THE COLOR FORMAT \n"); - printf(" 0 --> Semiplanar \n 1 --> Tile Mode\n"); - printf(" *********************************************\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&color_fmt_type); - fflush(stdin); - - if (thumbnailMode != 1) { - printf(" *********************************************\n"); - printf(" Output picture order option: \n"); - printf(" *********************************************\n"); - printf(" 0 --> Display order\n 1 --> Decode order\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&pic_order); - fflush(stdin); - - printf(" *********************************************\n"); - printf(" Number of frames to decode: \n"); - printf(" 0 ---> decode all frames: \n"); - printf(" *********************************************\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&num_frames_to_decode); - fflush(stdin); - } - } - if (file_type_option >= FILE_TYPE_COMMON_CODEC_MAX) - { - switch (codec_format_option) - { - case CODEC_FORMAT_H264: - file_type_option = (file_type)(FILE_TYPE_START_OF_H264_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); - break; - case CODEC_FORMAT_DIVX: - file_type_option = (file_type)(FILE_TYPE_START_OF_DIVX_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); - break; - case CODEC_FORMAT_MP4: - case CODEC_FORMAT_H263: - file_type_option = (file_type)(FILE_TYPE_START_OF_MP4_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); - break; - case CODEC_FORMAT_VC1: - file_type_option = (file_type)(FILE_TYPE_START_OF_VC1_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); - break; - case CODEC_FORMAT_MPEG2: - file_type_option = (file_type)(FILE_TYPE_START_OF_MPEG2_SPECIFIC + file_type_option - FILE_TYPE_COMMON_CODEC_MAX); - break; -#ifdef _MSM8974_ - case CODEC_FORMAT_VP8: - break; -#endif - default: - printf("Error: Unknown code %d\n", codec_format_option); - } - } - - CONFIG_VERSION_SIZE(picture_order); - picture_order.eOutputPictureOrder = QOMX_VIDEO_DISPLAY_ORDER; - if (pic_order == 1) - picture_order.eOutputPictureOrder = QOMX_VIDEO_DECODE_ORDER; - - if (outputOption == 0) - { - displayYuv = 0; - takeYuvLog = 0; - realtime_display = 0; - } - else if (outputOption == 1) - { - displayYuv = 1; - } - else if (outputOption == 2) - { - takeYuvLog = 1; - realtime_display = 0; - } - else if (outputOption == 3) - { - displayYuv = 1; - takeYuvLog = !realtime_display; - } - else - { - printf("Wrong option. Assume you want to see the YUV display\n"); - displayYuv = 1; - } - - if (test_option == 2) - { - printf(" *********************************************\n"); - printf(" ENTER THE COMPLIANCE TEST YOU WOULD LIKE TO EXECUTE\n"); - printf(" *********************************************\n"); - printf(" 1 --> Call Free Handle at the OMX_StateLoaded\n"); - printf(" 2 --> Call Free Handle at the OMX_StateIdle\n"); - printf(" 3 --> Call Free Handle at the OMX_StateExecuting\n"); - printf(" 4 --> Call Free Handle at the OMX_StatePause\n"); - fflush(stdin); - fgets(tempbuf,sizeof(tempbuf),stdin); - sscanf(tempbuf,"%d",&freeHandle_option); - fflush(stdin); - } - else - { - freeHandle_option = (freeHandle_test)0; - } - - printf("Input values: inputfilename[%s]\n", in_filename); - printf("*******************************************************\n"); - pthread_cond_init(&cond, 0); - pthread_cond_init(&eos_cond, 0); - pthread_mutex_init(&eos_lock, 0); - pthread_mutex_init(&lock, 0); - pthread_mutex_init(&etb_lock, 0); - pthread_mutex_init(&fbd_lock, 0); - pthread_mutex_init(&enable_lock, 0); - if (-1 == sem_init(&etb_sem, 0, 0)) - { - printf("Error - sem_init failed %d\n", errno); - } - if (-1 == sem_init(&fbd_sem, 0, 0)) - { - printf("Error - sem_init failed %d\n", errno); - } - if (-1 == sem_init(&seq_sem, 0, 0)) - { - printf("Error - sem_init failed %d\n", errno); - } - if (-1 == sem_init(&in_flush_sem, 0, 0)) - { - printf("Error - sem_init failed %d\n", errno); - } - if (-1 == sem_init(&out_flush_sem, 0, 0)) - { - printf("Error - sem_init failed %d\n", errno); - } - etb_queue = alloc_queue(); - if (etb_queue == NULL) - { - printf("\n Error in Creating etb_queue\n"); - return -1; - } - - fbd_queue = alloc_queue(); - if (fbd_queue == NULL) - { - printf("\n Error in Creating fbd_queue\n"); - free_queue(etb_queue); - return -1; - } - - if(0 != pthread_create(&fbd_thread_id, NULL, fbd_thread, NULL)) - { - printf("\n Error in Creating fbd_thread \n"); - free_queue(etb_queue); - free_queue(fbd_queue); - return -1; - } - - if (displayYuv) - { - if (open_display() != 0) - { - printf("\n Error opening display! Video won't be displayed..."); - displayYuv = 0; - } - } - - run_tests(); - pthread_cond_destroy(&cond); - pthread_mutex_destroy(&lock); - pthread_mutex_destroy(&etb_lock); - pthread_mutex_destroy(&fbd_lock); - pthread_mutex_destroy(&enable_lock); - pthread_cond_destroy(&eos_cond); - pthread_mutex_destroy(&eos_lock); - if (-1 == sem_destroy(&etb_sem)) - { - DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); - } - if (-1 == sem_destroy(&fbd_sem)) - { - DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); - } - if (-1 == sem_destroy(&seq_sem)) - { - DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); - } - if (-1 == sem_destroy(&in_flush_sem)) - { - DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); - } - if (-1 == sem_destroy(&out_flush_sem)) - { - DEBUG_PRINT_ERROR("Error - sem_destroy failed %d\n", errno); - } - if (displayYuv) - close_display(); - return 0; -} - -int run_tests() -{ - int cmd_error = 0; - DEBUG_PRINT("Inside %s\n", __FUNCTION__); - waitForPortSettingsChanged = 1; - - if(file_type_option == FILE_TYPE_DAT_PER_AU) { - Read_Buffer = Read_Buffer_From_DAT_File; - } - else if(file_type_option == FILE_TYPE_ARBITRARY_BYTES) { - Read_Buffer = Read_Buffer_ArbitraryBytes; - } - else if(codec_format_option == CODEC_FORMAT_H264) { - if (file_type_option == FILE_TYPE_264_NAL_SIZE_LENGTH) { - Read_Buffer = Read_Buffer_From_Size_Nal; - } else if (file_type_option == FILE_TYPE_264_START_CODE_BASED) { - Read_Buffer = Read_Buffer_From_H264_Start_Code_File; - } else { - DEBUG_PRINT_ERROR("Invalid file_type_option(%d) for H264", file_type_option); - return -1; - } - } - else if((codec_format_option == CODEC_FORMAT_H263) || - (codec_format_option == CODEC_FORMAT_MP4)) { - Read_Buffer = Read_Buffer_From_Vop_Start_Code_File; - } - else if (codec_format_option == CODEC_FORMAT_MPEG2) { - Read_Buffer = Read_Buffer_From_Mpeg2_Start_Code; - } - else if(file_type_option == FILE_TYPE_DIVX_4_5_6) { - Read_Buffer = Read_Buffer_From_DivX_4_5_6_File; - } -#ifdef MAX_RES_1080P - else if(file_type_option == FILE_TYPE_DIVX_311) { - Read_Buffer = Read_Buffer_From_DivX_311_File; - } -#endif - else if(file_type_option == FILE_TYPE_RCV) { - Read_Buffer = Read_Buffer_From_RCV_File; - } -#ifdef _MSM8974_ - else if(file_type_option == FILE_TYPE_VP8) { - Read_Buffer = Read_Buffer_From_VP8_File; - } -#endif - else if(file_type_option == FILE_TYPE_VC1) { - Read_Buffer = Read_Buffer_From_VC1_File; - } - - DEBUG_PRINT("file_type_option %d!\n", file_type_option); - - switch(file_type_option) - { - case FILE_TYPE_DAT_PER_AU: - case FILE_TYPE_ARBITRARY_BYTES: - case FILE_TYPE_264_START_CODE_BASED: - case FILE_TYPE_264_NAL_SIZE_LENGTH: - case FILE_TYPE_PICTURE_START_CODE: - case FILE_TYPE_MPEG2_START_CODE: - case FILE_TYPE_RCV: - case FILE_TYPE_VC1: -#ifdef _MSM8974_ - case FILE_TYPE_VP8: -#endif - case FILE_TYPE_DIVX_4_5_6: -#ifdef MAX_RES_1080P - case FILE_TYPE_DIVX_311: -#endif - if(Init_Decoder()!= 0x00) - { - DEBUG_PRINT_ERROR("Error - Decoder Init failed\n"); - return -1; - } - if(Play_Decoder() != 0x00) - { - return -1; - } - break; - default: - DEBUG_PRINT_ERROR("Error - Invalid Entry...%d\n",file_type_option); - break; - } - - anti_flickering = true; - if(strlen(seq_file_name)) - { - seqFile = fopen (seq_file_name, "rb"); - if (seqFile == NULL) - { - DEBUG_PRINT_ERROR("Error - Seq file %s could NOT be opened\n", - seq_file_name); - return -1; - } - else - { - DEBUG_PRINT("Seq file %s is opened \n", seq_file_name); - seq_enabled = 1; - anti_flickering = false; - } - } - - pthread_mutex_lock(&eos_lock); - while (bOutputEosReached == false && cmd_error == 0) - { - if(seq_enabled) - { - pthread_mutex_unlock(&eos_lock); - if(!get_next_command(seqFile)) - cmd_error = process_current_command(curr_seq_command); - else - { - printf("\n Error in get_next_cmd or EOF"); - seq_enabled = 0; - } - pthread_mutex_lock(&eos_lock); - } - else - pthread_cond_wait(&eos_cond, &eos_lock); - - if (currentStatus == PORT_SETTING_CHANGE_STATE) - { - pthread_mutex_unlock(&eos_lock); - cmd_error = output_port_reconfig(); - pthread_mutex_lock(&eos_lock); - } - } - pthread_mutex_unlock(&eos_lock); - - // Wait till EOS is reached... - if(bOutputEosReached) - do_freeHandle_and_clean_up(currentStatus == ERROR_STATE); - return 0; -} - -int Init_Decoder() -{ - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - OMX_ERRORTYPE omxresult; - OMX_U32 total = 0; - char vdecCompNames[50]; - typedef OMX_U8* OMX_U8_PTR; - char *role ="video_decoder"; - - static OMX_CALLBACKTYPE call_back = {&EventHandler, &EmptyBufferDone, &FillBufferDone}; - - int i = 0; - long bufCnt = 0; - - /* Init. the OpenMAX Core */ - DEBUG_PRINT("\nInitializing OpenMAX Core....\n"); - omxresult = OMX_Init(); - - if(OMX_ErrorNone != omxresult) { - DEBUG_PRINT_ERROR("\n Failed to Init OpenMAX core"); - return -1; - } - else { - DEBUG_PRINT_ERROR("\nOpenMAX Core Init Done\n"); - } - - /* Query for video decoders*/ - OMX_GetComponentsOfRole(role, &total, 0); - DEBUG_PRINT("\nTotal components of role=%s :%d", role, total); - - if(total) - { - /* Allocate memory for pointers to component name */ - OMX_U8** vidCompNames = (OMX_U8**)malloc((sizeof(OMX_U8*))*total); - if (vidCompNames == NULL) { - DEBUG_PRINT_ERROR("\nFailed to allocate vidCompNames\n"); - return -1; - } - - for (i = 0; i < total; ++i) { - vidCompNames[i] = (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_MAX_STRINGNAME_SIZE); - if (vidCompNames[i] == NULL) { - DEBUG_PRINT_ERROR("\nFailed to allocate vidCompNames[%d]\n", i); - return -1; - } - } - OMX_GetComponentsOfRole(role, &total, vidCompNames); - DEBUG_PRINT("\nComponents of Role:%s\n", role); - for (i = 0; i < total; ++i) { - DEBUG_PRINT("\nComponent Name [%s]\n",vidCompNames[i]); - free(vidCompNames[i]); - } - free(vidCompNames); - } - else { - DEBUG_PRINT_ERROR("No components found with Role:%s", role); - } - - if (codec_format_option == CODEC_FORMAT_H264) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.avc", 27); - //strlcpy(vdecCompNames, "OMX.SEC.qcom.video.decoder.avc", 31); - } - else if (codec_format_option == CODEC_FORMAT_MP4) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg4", 29); - } - else if (codec_format_option == CODEC_FORMAT_H263) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.h263", 28); - } - else if (codec_format_option == CODEC_FORMAT_VC1) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.vc1", 27); - } - else if (codec_format_option == CODEC_FORMAT_MPEG2) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.mpeg2", 29); - } - else if (file_type_option == FILE_TYPE_RCV) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.wmv", 27); - } - else if (file_type_option == FILE_TYPE_DIVX_4_5_6) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.divx", 28); - } -#ifdef _MSM8974_ - else if (codec_format_option == CODEC_FORMAT_VP8) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.vp8", 27); - } -#endif - else if (codec_format_option == CODEC_FORMAT_HEVC) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.hevc", 28); - } -#ifdef MAX_RES_1080P - else if (file_type_option == FILE_TYPE_DIVX_311) - { - strlcpy(vdecCompNames, "OMX.qcom.video.decoder.divx311", 31); - } -#endif - else - { - DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option); - return -1; - } - - omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&dec_handle), - (OMX_STRING)vdecCompNames, NULL, &call_back); - if (FAILED(omxresult)) { - DEBUG_PRINT_ERROR("\nFailed to Load the component:%s\n", vdecCompNames); - return -1; - } - else - { - DEBUG_PRINT("\nComponent %s is in LOADED state\n", vdecCompNames); - } - - QOMX_VIDEO_QUERY_DECODER_INSTANCES decoder_instances; - omxresult = OMX_GetConfig(dec_handle, - (OMX_INDEXTYPE)OMX_QcomIndexQueryNumberOfVideoDecInstance, - &decoder_instances); - DEBUG_PRINT("\n Number of decoder instances %d", - decoder_instances.nNumOfInstances); - - /* Get the port information */ - CONFIG_VERSION_SIZE(portParam); - omxresult = OMX_GetParameter(dec_handle, OMX_IndexParamVideoInit, - (OMX_PTR)&portParam); - - if(FAILED(omxresult)) { - DEBUG_PRINT_ERROR("ERROR - Failed to get Port Param\n"); - return -1; - } - else - { - DEBUG_PRINT("portParam.nPorts:%d\n", portParam.nPorts); - DEBUG_PRINT("portParam.nStartPortNumber:%d\n", portParam.nStartPortNumber); - } - - /* Set the compression format on i/p port */ - if (codec_format_option == CODEC_FORMAT_H264) - { - portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - } - else if (codec_format_option == CODEC_FORMAT_MP4) - { - portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - } - else if (codec_format_option == CODEC_FORMAT_H263) - { - portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; - } - else if (codec_format_option == CODEC_FORMAT_VC1) - { - portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingWMV; - } - else if (codec_format_option == CODEC_FORMAT_DIVX) - { - portFmt.format.video.eCompressionFormat = - (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx; - } - else if (codec_format_option == CODEC_FORMAT_MPEG2) - { - portFmt.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG2; - } - else if (codec_format_option == CODEC_FORMAT_HEVC) - { - portFmt.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc; - } - else - { - DEBUG_PRINT_ERROR("Error: Unsupported codec %d\n", codec_format_option); - } - - if (thumbnailMode == 1) { - QOMX_ENABLETYPE thumbNailMode; - thumbNailMode.bEnable = OMX_TRUE; - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode, - (OMX_PTR)&thumbNailMode); - DEBUG_PRINT("Enabled Thumbnail mode\n"); - } - - return 0; -} - -int Play_Decoder() -{ - OMX_VIDEO_PARAM_PORTFORMATTYPE videoportFmt = {0}; - int i, bufCnt, index = 0; - int frameSize=0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE* pBuffer = NULL; - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - - /* open the i/p and o/p files based on the video file format passed */ - if(open_video_file()) { - DEBUG_PRINT_ERROR("Error in opening video file\n"); - return -1; - } - - OMX_QCOM_PARAM_PORTDEFINITIONTYPE inputPortFmt; - memset(&inputPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE)); - CONFIG_VERSION_SIZE(inputPortFmt); - inputPortFmt.nPortIndex = 0; // input port - switch (file_type_option) - { - case FILE_TYPE_DAT_PER_AU: - case FILE_TYPE_PICTURE_START_CODE: - case FILE_TYPE_MPEG2_START_CODE: - case FILE_TYPE_264_START_CODE_BASED: - case FILE_TYPE_RCV: - case FILE_TYPE_VC1: -#ifdef MAX_RES_1080P - case FILE_TYPE_DIVX_311: -#endif - { - inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame; - break; - } - - case FILE_TYPE_ARBITRARY_BYTES: - case FILE_TYPE_264_NAL_SIZE_LENGTH: - case FILE_TYPE_DIVX_4_5_6: - { - inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Arbitrary; - break; - } -#ifdef _MSM8974_ - case FILE_TYPE_VP8: - { - inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_OnlyOneCompleteFrame; - break; - } -#endif - default: - inputPortFmt.nFramePackingFormat = OMX_QCOM_FramePacking_Unspecified; - } - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn, - (OMX_PTR)&inputPortFmt); -#ifdef USE_EXTERN_PMEM_BUF - OMX_QCOM_PARAM_PORTDEFINITIONTYPE outPortFmt; - memset(&outPortFmt, 0, sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE)); - CONFIG_VERSION_SIZE(outPortFmt); - outPortFmt.nPortIndex = 1; // output port - outPortFmt.nCacheAttr = OMX_QCOM_CacheAttrNone; - outPortFmt.nMemRegion = OMX_QCOM_MemRegionSMI; - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPortDefn, - (OMX_PTR)&outPortFmt); - - OMX_QCOM_PLATFORMPRIVATE_EXTN outPltPvtExtn; - memset(&outPltPvtExtn, 0, sizeof(OMX_QCOM_PLATFORMPRIVATE_EXTN)); - CONFIG_VERSION_SIZE(outPltPvtExtn); - outPltPvtExtn.nPortIndex = 1; // output port - outPltPvtExtn.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexPlatformPvt, - (OMX_PTR)&outPltPvtExtn); - use_external_pmem_buf = OMX_TRUE; -#endif - QOMX_ENABLETYPE extra_data; - extra_data.bEnable = OMX_TRUE; -#if 0 - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamInterlaceExtraData, - (OMX_PTR)&extra_data); -#endif -#if 0 - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamConcealMBMapExtraData, - (OMX_PTR)&extra_data); -#endif -#if 1 - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamFrameInfoExtraData, - (OMX_PTR)&extra_data); -#endif -#ifdef TEST_TS_FROM_SEI - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamH264TimeInfo, - (OMX_PTR)&extra_data); -#endif -#if 0 - extra_data.bEnable = OMX_FALSE; - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexParamConcealMBMapExtraData, - (OMX_PTR)&extra_data); -#endif -#if 0 - extra_data.bEnable = OMX_TRUE; - OMX_SetParameter(dec_handle,(OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData, - (OMX_PTR)&extra_data); -#endif - /* Query the decoder outport's min buf requirements */ - CONFIG_VERSION_SIZE(portFmt); - - /* Port for which the Client needs to obtain info */ - portFmt.nPortIndex = portParam.nStartPortNumber; - - OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); - DEBUG_PRINT("\nDec: Min Buffer Count %d\n", portFmt.nBufferCountMin); - DEBUG_PRINT("\nDec: Buffer Size %d\n", portFmt.nBufferSize); - - if(OMX_DirInput != portFmt.eDir) { - printf ("\nDec: Expect Input Port\n"); - return -1; - } -#ifdef MAX_RES_1080P - if( (codec_format_option == CODEC_FORMAT_DIVX) && - (file_type_option == FILE_TYPE_DIVX_311) ) { - - int off; - - if ( read(inputBufferFileFd, &width, 4 ) == -1 ) { - DEBUG_PRINT_ERROR("\nFailed to read width for divx\n"); - return -1; - } - - DEBUG_PRINT("\nWidth for DIVX = %d\n", width); - - if ( read(inputBufferFileFd, &height, 4 ) == -1 ) { - DEBUG_PRINT_ERROR("\nFailed to read height for divx\n"); - return -1; - } - - DEBUG_PRINT("\nHeight for DIVX = %u\n", height); - sliceheight = height; - stride = width; - } -#endif -#ifdef _MSM8974_ - if( (codec_format_option == CODEC_FORMAT_VC1) && - (file_type_option == FILE_TYPE_RCV) ) { - //parse struct_A data to get height and width information - unsigned int temp; - lseek64(inputBufferFileFd, 0, SEEK_SET); - if (read(inputBufferFileFd, &temp, 4) < 0) { - DEBUG_PRINT_ERROR("\nFailed to read vc1 data\n"); - return -1; - } - //Refer to Annex L of SMPTE 421M-2006 VC1 decoding standard - //We need to skip 12 bytes after 0xC5 in sequence layer data - //structure to read struct_A, which includes height and - //width information. - if ((temp & 0xFF000000) == 0xC5000000) { - lseek64(inputBufferFileFd, 12, SEEK_SET); - - if ( read(inputBufferFileFd, &height, 4 ) < -1 ) { - DEBUG_PRINT_ERROR("\nFailed to read height for vc-1\n"); - return -1; - } - if ( read(inputBufferFileFd, &width, 4 ) == -1 ) { - DEBUG_PRINT_ERROR("\nFailed to read width for vc-1\n"); - return -1; - } - lseek64(inputBufferFileFd, 0, SEEK_SET); - } - if ((temp & 0xFF000000) == 0x85000000) { - lseek64(inputBufferFileFd, 0, SEEK_SET); - } - DEBUG_PRINT("\n RCV clip width = %u height = %u \n",width, height); - } -#endif - crop_rect.nWidth = width; - crop_rect.nHeight = height; - - bufCnt = 0; - portFmt.format.video.nFrameHeight = height; - portFmt.format.video.nFrameWidth = width; - portFmt.format.video.xFramerate = fps; - OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition, (OMX_PTR)&portFmt); - OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition, &portFmt); - DEBUG_PRINT("\nDec: New Min Buffer Count %d", portFmt.nBufferCountMin); - CONFIG_VERSION_SIZE(videoportFmt); -#ifdef MAX_RES_720P - if(color_fmt_type == 0) - { - color_fmt = OMX_COLOR_FormatYUV420SemiPlanar; - } - else - { - color_fmt = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; - } -#elif _MSM8974_ - color_fmt = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m; -#else - color_fmt = (OMX_COLOR_FORMATTYPE) - QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka; -#endif - - while (ret == OMX_ErrorNone) - { - videoportFmt.nPortIndex = 1; - videoportFmt.nIndex = index; - ret = OMX_GetParameter(dec_handle, OMX_IndexParamVideoPortFormat, - (OMX_PTR)&videoportFmt); - - if((ret == OMX_ErrorNone) && (videoportFmt.eColorFormat == - color_fmt)) - { - DEBUG_PRINT("\n Format[%u] supported by OMX Decoder", color_fmt); - break; - } - index++; - } - - if(ret == OMX_ErrorNone) - { - if(OMX_SetParameter(dec_handle, OMX_IndexParamVideoPortFormat, - (OMX_PTR)&videoportFmt) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\n Setting Tile format failed"); - return -1; - } - } - else - { - DEBUG_PRINT_ERROR("\n Error in retrieving supported color formats"); - return -1; - } - picture_order.nPortIndex = 1; - DEBUG_PRINT("\nSet picture order\n"); - if(OMX_SetParameter(dec_handle, - (OMX_INDEXTYPE)OMX_QcomIndexParamVideoDecoderPictureOrder, - (OMX_PTR)&picture_order) != OMX_ErrorNone) - { - printf("\n ERROR: Setting picture order!"); - return -1; - } - DEBUG_PRINT("\nVideo format: W x H (%d x %d)", - portFmt.format.video.nFrameWidth, - portFmt.format.video.nFrameHeight); - if(codec_format_option == CODEC_FORMAT_H264 || - codec_format_option == CODEC_FORMAT_HEVC) - { - OMX_VIDEO_CONFIG_NALSIZE naluSize; - naluSize.nNaluBytes = nalSize; - DEBUG_PRINT("\n Nal length is %d index %d",nalSize,OMX_IndexConfigVideoNalSize); - OMX_SetConfig(dec_handle,OMX_IndexConfigVideoNalSize,(OMX_PTR)&naluSize); - DEBUG_PRINT("SETTING THE NAL SIZE to %d\n",naluSize.nNaluBytes); - } - DEBUG_PRINT("\nOMX_SendCommand Decoder -> IDLE\n"); - OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle,0); - - input_buf_cnt = portFmt.nBufferCountActual; - DEBUG_PRINT("Transition to Idle State succesful...\n"); - -#if ALLOCATE_BUFFER - // Allocate buffer on decoder's i/p port - error = Allocate_Buffer(dec_handle, &pInputBufHdrs, portFmt.nPortIndex, - portFmt.nBufferCountActual, portFmt.nBufferSize); - if (error != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Input buffer error\n"); - return -1; - } - else { - DEBUG_PRINT("\nOMX_AllocateBuffer Input buffer success\n"); - } -#else - // Use buffer on decoder's i/p port - input_use_buffer = true; - DEBUG_PRINT_ERROR("\n before OMX_UseBuffer %p", &pInputBufHdrs); - error = use_input_buffer(dec_handle, - &pInputBufHdrs, - portFmt.nPortIndex, - portFmt.nBufferSize, - portFmt.nBufferCountActual); - if (error != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed"); - return -1; - } - else { - DEBUG_PRINT("OMX_UseBuffer Input buffer success\n"); - } -#endif - portFmt.nPortIndex = portParam.nStartPortNumber+1; - // Port for which the Client needs to obtain info - - OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); - DEBUG_PRINT("nMin Buffer Count=%d", portFmt.nBufferCountMin); - DEBUG_PRINT("nBuffer Size=%d", portFmt.nBufferSize); - if(OMX_DirOutput != portFmt.eDir) { - DEBUG_PRINT_ERROR("Error - Expect Output Port\n"); - return -1; - } - - if (anti_flickering) { - ret = OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); - if (ret != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("%s: OMX_GetParameter failed: %d",__FUNCTION__, ret); - return -1; - } - portFmt.nBufferCountActual += 1; - ret = OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); - if (ret != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("%s: OMX_SetParameter failed: %d",__FUNCTION__, ret); - return -1; - } - } - -#ifndef USE_EGL_IMAGE_TEST_APP - if (use_external_pmem_buf) - { - DEBUG_PRINT_ERROR("\n Use External pmem buf: OMX_UseBuffer %p", &pInputBufHdrs); - error = use_output_buffer_multiple_fd(dec_handle, - &pOutYUVBufHdrs, - portFmt.nPortIndex, - portFmt.nBufferSize, - portFmt.nBufferCountActual); - } - else - { - /* Allocate buffer on decoder's o/p port */ - error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex, - portFmt.nBufferCountActual, portFmt.nBufferSize); - } - free_op_buf_cnt = portFmt.nBufferCountActual; - if (error != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n"); - return -1; - } - else - { - DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n"); - } -#else - DEBUG_PRINT_ERROR("\n before OMX_UseBuffer %p", &pInputBufHdrs); - error = use_output_buffer(dec_handle, - &pOutYUVBufHdrs, - portFmt.nPortIndex, - portFmt.nBufferSize, - portFmt.nBufferCountActual); - free_op_buf_cnt = portFmt.nBufferCountActual; - if (error != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed"); - return -1; - } - else { - DEBUG_PRINT("OMX_UseBuffer Input buffer success\n"); - } -#endif - wait_for_event(); - if (currentStatus == ERROR_STATE) - { - do_freeHandle_and_clean_up(true); - return -1; - } - - if (freeHandle_option == FREE_HANDLE_AT_IDLE) - { - OMX_STATETYPE state = OMX_StateInvalid; - OMX_GetState(dec_handle, &state); - if (state == OMX_StateIdle) - { - DEBUG_PRINT("Decoder is in OMX_StateIdle and trying to call OMX_FreeHandle \n"); - do_freeHandle_and_clean_up(false); - } - else - { - DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state); - do_freeHandle_and_clean_up(true); - } - return -1; - } - - - DEBUG_PRINT("OMX_SendCommand Decoder -> Executing\n"); - OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateExecuting,0); - wait_for_event(); - if (currentStatus == ERROR_STATE) - { - do_freeHandle_and_clean_up(true); - return -1; - } - if (pOutYUVBufHdrs == NULL) - { - DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs is NULL\n"); - return -1; - } - for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) { - DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt); - if (pOutYUVBufHdrs[bufCnt] == NULL) - { - DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs[%d] is NULL\n", bufCnt); - return -1; - } - pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1; - pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS; - ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]); - if (OMX_ErrorNone != ret) - DEBUG_PRINT_ERROR("Error - OMX_FillThisBuffer failed with result %d\n", ret); - else - { - DEBUG_PRINT("OMX_FillThisBuffer success!\n"); - free_op_buf_cnt--; - } - } - - used_ip_buf_cnt = input_buf_cnt; - - rcv_v1 = 0; - - //QPERF_START(client_decode); - if (codec_format_option == CODEC_FORMAT_VC1) - { - pInputBufHdrs[0]->nOffset = 0; - if(file_type_option == FILE_TYPE_RCV) - { - frameSize = Read_Buffer_From_RCV_File_Seq_Layer(pInputBufHdrs[0]); - pInputBufHdrs[0]->nFilledLen = frameSize; - DEBUG_PRINT("After Read_Buffer_From_RCV_File_Seq_Layer, " - "frameSize %d\n", frameSize); - } - else if(file_type_option == FILE_TYPE_VC1) - { - bHdrflag = 1; - pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]); - bHdrflag = 0; - DEBUG_PRINT_ERROR("After 1st Read_Buffer for VC1, " - "pInputBufHdrs[0]->nFilledLen %d\n", pInputBufHdrs[0]->nFilledLen); - } - else - { - pInputBufHdrs[0]->nFilledLen = Read_Buffer(pInputBufHdrs[0]); - DEBUG_PRINT("After Read_Buffer pInputBufHdrs[0]->nFilledLen %d\n", - pInputBufHdrs[0]->nFilledLen); - } - - pInputBufHdrs[0]->nInputPortIndex = 0; - pInputBufHdrs[0]->nOffset = 0; -#ifndef _MSM8974_ - pInputBufHdrs[0]->nFlags = 0; -#endif - ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[0]); - if (ret != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret); - do_freeHandle_and_clean_up(true); - return -1; - } - else - { - etb_count++; - DEBUG_PRINT("OMX_EmptyThisBuffer success!\n"); - } - i = 1; -#ifdef _MSM8974_ - pInputBufHdrs[0]->nFlags = 0; -#endif - } - else - { - i = 0; - } - - for (i; i < used_ip_buf_cnt;i++) { - pInputBufHdrs[i]->nInputPortIndex = 0; - pInputBufHdrs[i]->nOffset = 0; - if((frameSize = Read_Buffer(pInputBufHdrs[i])) <= 0 ){ - DEBUG_PRINT("NO FRAME READ\n"); - pInputBufHdrs[i]->nFilledLen = frameSize; - pInputBufHdrs[i]->nInputPortIndex = 0; - pInputBufHdrs[i]->nFlags |= OMX_BUFFERFLAG_EOS;; - bInputEosReached = true; - - OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]); - etb_count++; - DEBUG_PRINT("File is small::Either EOS or Some Error while reading file\n"); - break; - } - pInputBufHdrs[i]->nFilledLen = frameSize; - pInputBufHdrs[i]->nInputPortIndex = 0; - pInputBufHdrs[i]->nFlags = 0; -//pBufHdr[bufCnt]->pAppPrivate = this; - DEBUG_PRINT("%s: Timestamp sent(%lld)", __FUNCTION__, pInputBufHdrs[i]->nTimeStamp); - ret = OMX_EmptyThisBuffer(dec_handle, pInputBufHdrs[i]); - if (OMX_ErrorNone != ret) { - DEBUG_PRINT_ERROR("ERROR - OMX_EmptyThisBuffer failed with result %d\n", ret); - do_freeHandle_and_clean_up(true); - return -1; - } - else { - DEBUG_PRINT("OMX_EmptyThisBuffer success!\n"); - etb_count++; - } - } - - if(0 != pthread_create(&ebd_thread_id, NULL, ebd_thread, NULL)) - { - printf("\n Error in Creating fbd_thread \n"); - free_queue(etb_queue); - free_queue(fbd_queue); - return -1; - } - - // wait for event port settings changed event - DEBUG_PRINT("wait_for_event: dyn reconfig"); - wait_for_event(); - DEBUG_PRINT("wait_for_event: dyn reconfig rcvd, currentStatus %d\n", - currentStatus); - if (currentStatus == ERROR_STATE) - { - printf("Error - ERROR_STATE\n"); - do_freeHandle_and_clean_up(true); - return -1; - } - else if (currentStatus == PORT_SETTING_CHANGE_STATE) - { - if (output_port_reconfig() != 0) - return -1; - } - - if (freeHandle_option == FREE_HANDLE_AT_EXECUTING) - { - OMX_STATETYPE state = OMX_StateInvalid; - OMX_GetState(dec_handle, &state); - if (state == OMX_StateExecuting) - { - DEBUG_PRINT("Decoder is in OMX_StateExecuting and trying to call OMX_FreeHandle \n"); - do_freeHandle_and_clean_up(false); - } - else - { - DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state); - do_freeHandle_and_clean_up(true); - } - return -1; - } - else if (freeHandle_option == FREE_HANDLE_AT_PAUSE) - { - OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StatePause,0); - wait_for_event(); - - OMX_STATETYPE state = OMX_StateInvalid; - OMX_GetState(dec_handle, &state); - if (state == OMX_StatePause) - { - DEBUG_PRINT("Decoder is in OMX_StatePause and trying to call OMX_FreeHandle \n"); - do_freeHandle_and_clean_up(false); - } - else - { - DEBUG_PRINT_ERROR("Error - Decoder is in state %d and trying to call OMX_FreeHandle \n", state); - do_freeHandle_and_clean_up(true); - } - return -1; - } - - return 0; -} - -static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***pBufHdrs, - OMX_U32 nPortIndex, - long bufCntMin, long bufSize) -{ - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - OMX_ERRORTYPE error=OMX_ErrorNone; - long bufCnt=0; - - DEBUG_PRINT("pBufHdrs = %x,bufCntMin = %d\n", pBufHdrs, bufCntMin); - *pBufHdrs= (OMX_BUFFERHEADERTYPE **) - malloc(sizeof(OMX_BUFFERHEADERTYPE)*bufCntMin); - - for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { - DEBUG_PRINT("OMX_AllocateBuffer No %d \n", bufCnt); - error = OMX_AllocateBuffer(dec_handle, &((*pBufHdrs)[bufCnt]), - nPortIndex, NULL, bufSize); - } - - return error; -} - -static OMX_ERRORTYPE use_input_buffer ( OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***pBufHdrs, - OMX_U32 nPortIndex, - OMX_U32 bufSize, - long bufCntMin) -{ - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - OMX_ERRORTYPE error=OMX_ErrorNone; - long bufCnt=0; - OMX_U8* pvirt = NULL; - - *pBufHdrs= (OMX_BUFFERHEADERTYPE **) - malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin); - if(*pBufHdrs == NULL){ - DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - - for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { - // allocate input buffers - DEBUG_PRINT("OMX_UseBuffer No %d %d \n", bufCnt, bufSize); - pvirt = (OMX_U8*) malloc (bufSize); - if(pvirt == NULL){ - DEBUG_PRINT_ERROR("\n pvirt Allocation failed "); - return OMX_ErrorInsufficientResources; - } - error = OMX_UseBuffer(dec_handle, &((*pBufHdrs)[bufCnt]), - nPortIndex, NULL, bufSize, pvirt); - } - return error; -} - -static OMX_ERRORTYPE use_output_buffer ( OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***pBufHdrs, - OMX_U32 nPortIndex, - OMX_U32 bufSize, - long bufCntMin) -{ - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - OMX_ERRORTYPE error=OMX_ErrorNone; - long bufCnt=0; - OMX_U8* pvirt = NULL; - - *pBufHdrs= (OMX_BUFFERHEADERTYPE **) - malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin); - if(*pBufHdrs == NULL){ - DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - output_use_buffer = true; - p_eglHeaders = (struct temp_egl **) - malloc(sizeof(struct temp_egl *)* bufCntMin); - if (!p_eglHeaders){ - DEBUG_PRINT_ERROR("\n EGL allocation failed"); - return OMX_ErrorInsufficientResources; - } - - for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { - // allocate input buffers - DEBUG_PRINT("OMX_UseBuffer No %d %d \n", bufCnt, bufSize); - p_eglHeaders[bufCnt] = (struct temp_egl*) - malloc(sizeof(struct temp_egl)); - if(!p_eglHeaders[bufCnt]) { - DEBUG_PRINT_ERROR("\n EGL allocation failed"); - return OMX_ErrorInsufficientResources; - } - p_eglHeaders[bufCnt]->pmem_fd = open(PMEM_DEVICE,O_RDWR); - p_eglHeaders[bufCnt]->offset = 0; - if(p_eglHeaders[bufCnt]->pmem_fd < 0) { - DEBUG_PRINT_ERROR("\n open failed %s",PMEM_DEVICE); - return OMX_ErrorInsufficientResources; - } - -#ifndef USE_ION - /* TBD - this commenting is dangerous */ - align_pmem_buffers(p_eglHeaders[bufCnt]->pmem_fd, bufSize, - 8192); -#endif - DEBUG_PRINT_ERROR("\n allocation size %d pmem fd %d",bufSize,p_eglHeaders[bufCnt]->pmem_fd); - pvirt = (unsigned char *)mmap(NULL,bufSize,PROT_READ|PROT_WRITE, - MAP_SHARED,p_eglHeaders[bufCnt]->pmem_fd,0); - DEBUG_PRINT_ERROR("\n Virtaul Address %p Size %d",pvirt,bufSize); - if (pvirt == MAP_FAILED) { - DEBUG_PRINT_ERROR("\n mmap failed for buffers"); - return OMX_ErrorInsufficientResources; - } - use_buf_virt_addr[bufCnt] = (unsigned)pvirt; - error = OMX_UseEGLImage(dec_handle, &((*pBufHdrs)[bufCnt]), - nPortIndex, pvirt,(void *)p_eglHeaders[bufCnt]); - } - return error; -} - -static OMX_ERRORTYPE use_output_buffer_multiple_fd ( OMX_COMPONENTTYPE *dec_handle, - OMX_BUFFERHEADERTYPE ***pBufHdrs, - OMX_U32 nPortIndex, - OMX_U32 bufSize, - long bufCntMin) -{ - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - OMX_ERRORTYPE error=OMX_ErrorNone; - long bufCnt=0; - OMX_U8* pvirt = NULL; - - *pBufHdrs= (OMX_BUFFERHEADERTYPE **) - malloc(sizeof(OMX_BUFFERHEADERTYPE)* bufCntMin); - if(*pBufHdrs == NULL){ - DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed "); - return OMX_ErrorInsufficientResources; - } - pPlatformList = (OMX_QCOM_PLATFORM_PRIVATE_LIST *) - malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST)* bufCntMin); - - if(pPlatformList == NULL){ - DEBUG_PRINT_ERROR("\n pPlatformList Allocation failed "); - return OMX_ErrorInsufficientResources; - } - - pPlatformEntry = (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *) - malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY)* bufCntMin); - - if(pPlatformEntry == NULL){ - DEBUG_PRINT_ERROR("\n pPlatformEntry Allocation failed "); - return OMX_ErrorInsufficientResources; - } - - pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - malloc(sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO)* bufCntMin); - - if(pPMEMInfo == NULL){ - DEBUG_PRINT_ERROR("\n pPMEMInfo Allocation failed "); - return OMX_ErrorInsufficientResources; - } - - //output_use_buffer = true; - for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) { - // allocate input buffers - DEBUG_PRINT("OMX_UseBuffer_multiple_fd No %d %d \n", bufCnt, bufSize); - - pPlatformEntry[bufCnt].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM; - pPlatformEntry[bufCnt].entry = &pPMEMInfo[bufCnt]; - // Initialize the Platform List - pPlatformList[bufCnt].nEntries = 1; - pPlatformList[bufCnt].entryList = &pPlatformEntry[bufCnt]; - pPMEMInfo[bufCnt].offset = 0; - pPMEMInfo[bufCnt].pmem_fd = open(PMEM_DEVICE,O_RDWR);; - if(pPMEMInfo[bufCnt].pmem_fd < 0) { - DEBUG_PRINT_ERROR("\n open failed %s",PMEM_DEVICE); - return OMX_ErrorInsufficientResources; - } -#ifndef USE_ION - /* TBD - this commenting is dangerous */ - align_pmem_buffers(pPMEMInfo[bufCnt].pmem_fd, bufSize, - 8192); -#endif - DEBUG_PRINT("\n allocation size %d pmem fd 0x%x",bufSize,pPMEMInfo[bufCnt].pmem_fd); - pvirt = (unsigned char *)mmap(NULL,bufSize,PROT_READ|PROT_WRITE, - MAP_SHARED,pPMEMInfo[bufCnt].pmem_fd,0); - getFreePmem(); - DEBUG_PRINT("\n Virtaul Address %p Size %d pmem_fd=0x%x",pvirt,bufSize,pPMEMInfo[bufCnt].pmem_fd); - if (pvirt == MAP_FAILED) { - DEBUG_PRINT_ERROR("\n mmap failed for buffers"); - return OMX_ErrorInsufficientResources; - } - use_buf_virt_addr[bufCnt] = (unsigned)pvirt; - error = OMX_UseBuffer(dec_handle, &((*pBufHdrs)[bufCnt]), - nPortIndex, &pPlatformList[bufCnt], bufSize, pvirt); - } - return error; -} -static void do_freeHandle_and_clean_up(bool isDueToError) -{ - int bufCnt = 0; - OMX_STATETYPE state = OMX_StateInvalid; - OMX_GetState(dec_handle, &state); - if (state == OMX_StateExecuting || state == OMX_StatePause) - { - DEBUG_PRINT("Requesting transition to Idle"); - OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateIdle, 0); - wait_for_event(); - } - OMX_GetState(dec_handle, &state); - if (state == OMX_StateIdle) - { - DEBUG_PRINT("Requesting transition to Loaded"); - OMX_SendCommand(dec_handle, OMX_CommandStateSet, OMX_StateLoaded, 0); - for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) - { - if (pInputBufHdrs[bufCnt]->pBuffer && input_use_buffer) - { - free(pInputBufHdrs[bufCnt]->pBuffer); - pInputBufHdrs[bufCnt]->pBuffer = NULL; - DEBUG_PRINT_ERROR("\nFree(pInputBufHdrs[%d]->pBuffer)",bufCnt); - } - OMX_FreeBuffer(dec_handle, 0, pInputBufHdrs[bufCnt]); - } - if (pInputBufHdrs) - { - free(pInputBufHdrs); - pInputBufHdrs = NULL; - } - for(bufCnt = 0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) { - if (output_use_buffer && p_eglHeaders) { - if(p_eglHeaders[bufCnt]) { - munmap (pOutYUVBufHdrs[bufCnt]->pBuffer, - pOutYUVBufHdrs[bufCnt]->nAllocLen); - close(p_eglHeaders[bufCnt]->pmem_fd); - p_eglHeaders[bufCnt]->pmem_fd = -1; - free(p_eglHeaders[bufCnt]); - p_eglHeaders[bufCnt] = NULL; - } - } - if (use_external_pmem_buf) - { - DEBUG_PRINT("Freeing in external pmem case: buffer=0x%x, pmem_fd=0x%d", - pOutYUVBufHdrs[bufCnt]->pBuffer, - pPMEMInfo[bufCnt].pmem_fd); - if (pOutYUVBufHdrs[bufCnt]->pBuffer) - { - munmap (pOutYUVBufHdrs[bufCnt]->pBuffer, - pOutYUVBufHdrs[bufCnt]->nAllocLen); - } - if (&pPMEMInfo[bufCnt]) - { - close(pPMEMInfo[bufCnt].pmem_fd); - pPMEMInfo[bufCnt].pmem_fd = -1; - } - } - OMX_FreeBuffer(dec_handle, 1, pOutYUVBufHdrs[bufCnt]); - } - if(p_eglHeaders) { - free(p_eglHeaders); - p_eglHeaders = NULL; - } - if (pPMEMInfo) - { - DEBUG_PRINT("Freeing in external pmem case:PMEM"); - free(pPMEMInfo); - pPMEMInfo = NULL; - } - if (pPlatformEntry) - { - DEBUG_PRINT("Freeing in external pmem case:ENTRY"); - free(pPlatformEntry); - pPlatformEntry = NULL; - } - if (pPlatformList) - { - DEBUG_PRINT("Freeing in external pmem case:LIST"); - free(pPlatformList); - pPlatformList = NULL; - } - wait_for_event(); - } - - DEBUG_PRINT("[OMX Vdec Test] - Free handle decoder\n"); - OMX_ERRORTYPE result = OMX_FreeHandle(dec_handle); - if (result != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("[OMX Vdec Test] - OMX_FreeHandle error. Error code: %d\n", result); - } - dec_handle = NULL; - - /* Deinit OpenMAX */ - DEBUG_PRINT("[OMX Vdec Test] - De-initializing OMX \n"); - OMX_Deinit(); - - DEBUG_PRINT("[OMX Vdec Test] - closing all files\n"); - if(inputBufferFileFd != -1) - { - close(inputBufferFileFd); - inputBufferFileFd = -1; - } - - DEBUG_PRINT("[OMX Vdec Test] - after free inputfile\n"); - - if (takeYuvLog && outputBufferFile) { - fclose(outputBufferFile); - outputBufferFile = NULL; - } -#ifdef _MSM8974_ - if (crcFile) { - fclose(crcFile); - crcFile = NULL; - } -#endif - DEBUG_PRINT("[OMX Vdec Test] - after free outputfile\n"); - - if(etb_queue) - { - free_queue(etb_queue); - etb_queue = NULL; - } - DEBUG_PRINT("[OMX Vdec Test] - after free etb_queue \n"); - if(fbd_queue) - { - free_queue(fbd_queue); - fbd_queue = NULL; - } - DEBUG_PRINT("[OMX Vdec Test] - after free iftb_queue\n"); - printf("*****************************************\n"); - if (isDueToError) - printf("************...TEST FAILED...************\n"); - else - printf("**********...TEST SUCCESSFULL...*********\n"); - printf("*****************************************\n"); -} - -static int Read_Buffer_From_DAT_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - long frameSize=0; - char temp_buffer[10]; - char temp_byte; - int bytes_read=0; - int i=0; - unsigned char *read_buffer=NULL; - char c = '1'; //initialize to anything except '\0'(0) - char inputFrameSize[12]; - int count =0; char cnt =0; - memset(temp_buffer, 0, sizeof(temp_buffer)); - - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - - while (cnt < 10) - /* Check the input file format, may result in infinite loop */ - { - DEBUG_PRINT("loop[%d] count[%d]\n",cnt,count); - count = read( inputBufferFileFd, &inputFrameSize[cnt], 1); - if(inputFrameSize[cnt] == '\0' ) - break; - cnt++; - } - inputFrameSize[cnt]='\0'; - frameSize = atoi(inputFrameSize); - pBufHdr->nFilledLen = 0; - - /* get the frame length */ - lseek64(inputBufferFileFd, -1, SEEK_CUR); - bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer, frameSize); - - DEBUG_PRINT("Actual frame Size [%d] bytes_read using fread[%d]\n", - frameSize, bytes_read); - - if(bytes_read == 0 || bytes_read < frameSize ) { - DEBUG_PRINT("Bytes read Zero After Read frame Size \n"); - DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n", - video_playback_count); - return 0; - } - pBufHdr->nTimeStamp = timeStampLfile; - timeStampLfile += timestampInterval; - return bytes_read; -} - -static int Read_Buffer_From_H264_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - int bytes_read = 0; - int cnt = 0; - unsigned int code = 0; - int naluType = 0; - int newFrame = 0; - char *dataptr = (char *)pBufHdr->pBuffer; - DEBUG_PRINT("Inside %s", __FUNCTION__); - do - { - newFrame = 0; - bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1); - if (!bytes_read) - { - DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__); - break; - } - code <<= 8; - code |= (0x000000FF & dataptr[cnt]); - cnt++; - if ((cnt == 4) && (code != H264_START_CODE)) - { - DEBUG_PRINT_ERROR("\n%s: ERROR: Invalid start code found 0x%x", __FUNCTION__, code); - cnt = 0; - break; - } - if ((cnt > 4) && (code == H264_START_CODE)) - { - DEBUG_PRINT("%s: Found H264_START_CODE", __FUNCTION__); - bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1); - if (!bytes_read) - { - DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__); - break; - } - DEBUG_PRINT("%s: READ Byte[%d] = 0x%x", __FUNCTION__, cnt, dataptr[cnt]); - naluType = dataptr[cnt] & 0x1F; - cnt++; - if ((naluType == 1) || (naluType == 5)) - { - DEBUG_PRINT("%s: Found AU", __FUNCTION__); - bytes_read = read(inputBufferFileFd, &dataptr[cnt], 1); - if (!bytes_read) - { - DEBUG_PRINT("\n%s: Bytes read Zero", __FUNCTION__); - break; - } - DEBUG_PRINT("%s: READ Byte[%d] = 0x%x", __FUNCTION__, cnt, dataptr[cnt]); - newFrame = (dataptr[cnt] & 0x80); - cnt++; - if (newFrame) - { - lseek64(inputBufferFileFd, -6, SEEK_CUR); - cnt -= 6; - DEBUG_PRINT("%s: Found a NAL unit (type 0x%x) of size = %d", __FUNCTION__, (dataptr[4] & 0x1F), cnt); - break; - } - else - { - DEBUG_PRINT("%s: Not a New Frame", __FUNCTION__); - } - } - else - { - lseek64(inputBufferFileFd, -5, SEEK_CUR); - cnt -= 5; - DEBUG_PRINT("%s: Found NAL unit (type 0x%x) of size = %d", __FUNCTION__, (dataptr[4] & 0x1F), cnt); - break; - } - } - } while (1); - -#ifdef TEST_TS_FROM_SEI - if (timeStampLfile == 0) - pBufHdr->nTimeStamp = 0; - else - pBufHdr->nTimeStamp = LLONG_MAX; -#else - pBufHdr->nTimeStamp = timeStampLfile; -#endif - timeStampLfile += timestampInterval; - - return cnt; -} - -static int Read_Buffer_ArbitraryBytes(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - int bytes_read=0; - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer, NUMBER_OF_ARBITRARYBYTES_READ); - if(bytes_read == 0) { - DEBUG_PRINT("Bytes read Zero After Read frame Size \n"); - DEBUG_PRINT("Checking VideoPlayback Count:video_playback_count is:%d\n", - video_playback_count); - return 0; - } -#ifdef TEST_TS_FROM_SEI - if (timeStampLfile == 0) - pBufHdr->nTimeStamp = 0; - else - pBufHdr->nTimeStamp = LLONG_MAX; -#else - pBufHdr->nTimeStamp = timeStampLfile; -#endif - timeStampLfile += timestampInterval; - return bytes_read; -} - -static int Read_Buffer_From_Vop_Start_Code_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - unsigned int readOffset = 0; - int bytes_read = 0; - unsigned int code = 0; - pBufHdr->nFilledLen = 0; - static unsigned int header_code = 0; - - DEBUG_PRINT("Inside %s", __FUNCTION__); - - do - { - //Start codes are always byte aligned. - bytes_read = read(inputBufferFileFd, &pBufHdr->pBuffer[readOffset], 1); - if(bytes_read == 0 || bytes_read == -1) - { - DEBUG_PRINT("Bytes read Zero \n"); - break; - } - code <<= 8; - code |= (0x000000FF & pBufHdr->pBuffer[readOffset]); - //VOP start code comparision - if (readOffset>3) - { - if(!header_code ){ - if( VOP_START_CODE == code) - { - header_code = VOP_START_CODE; - } - else if ( (0xFFFFFC00 & code) == SHORT_HEADER_START_CODE ) - { - header_code = SHORT_HEADER_START_CODE; - } - } - if ((header_code == VOP_START_CODE) && (code == VOP_START_CODE)) - { - //Seek backwards by 4 - lseek64(inputBufferFileFd, -4, SEEK_CUR); - readOffset-=3; - break; - } - else if (( header_code == SHORT_HEADER_START_CODE ) && ( SHORT_HEADER_START_CODE == (code & 0xFFFFFC00))) - { - //Seek backwards by 4 - lseek64(inputBufferFileFd, -4, SEEK_CUR); - readOffset-=3; - break; - } - } - readOffset++; - }while (1); - pBufHdr->nTimeStamp = timeStampLfile; - timeStampLfile += timestampInterval; - return readOffset; -} -static int Read_Buffer_From_Mpeg2_Start_Code(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - unsigned int readOffset = 0; - int bytesRead = 0; - unsigned int code = 0; - pBufHdr->nFilledLen = 0; - static unsigned int firstParse = true; - unsigned int seenFrame = false; - - DEBUG_PRINT("Inside %s", __FUNCTION__); - - /* Read one byte at a time. Construct the code every byte in order to - * compare to the start codes. Keep looping until we've read in a complete - * frame, which can be either just a picture start code + picture, or can - * include the sequence header as well - */ - while (1) { - bytesRead = read(inputBufferFileFd, &pBufHdr->pBuffer[readOffset], 1); - - /* Exit the loop if we can't read any more bytes */ - if (bytesRead == 0 || bytesRead == -1) { - break; - } - - /* Construct the code one byte at a time */ - code <<= 8; - code |= (0x000000FF & pBufHdr->pBuffer[readOffset]); - - /* Can't compare the code to MPEG2 start codes until we've read the - * first four bytes - */ - if (readOffset >= 3) { - - /* If this is the first time we're reading from the file, then we - * need to throw away the system start code information at the - * beginning. We can just look for the first sequence header. - */ - if (firstParse) { - if (code == MPEG2_SEQ_START_CODE) { - /* Seek back by 4 bytes and reset code so that we can skip - * down to the common case below. - */ - lseek(inputBufferFileFd, -4, SEEK_CUR); - code = 0; - readOffset -= 3; - firstParse = false; - continue; - } - } - - /* If we have already parsed a frame and we see a sequence header, then - * the sequence header is part of the next frame so we seek back and - * break. - */ - if (code == MPEG2_SEQ_START_CODE) { - if (seenFrame) { - lseek(inputBufferFileFd, -4, SEEK_CUR); - readOffset -= 3; - break; - } - /* If we haven't seen a frame yet, then read in all the data until we - * either see another frame start code or sequence header start code. - */ - } else if (code == MPEG2_FRAME_START_CODE) { - if (!seenFrame) { - seenFrame = true; - } else { - lseek(inputBufferFileFd, -4, SEEK_CUR); - readOffset -= 3; - break; - } - } - } - - readOffset++; - } - - pBufHdr->nTimeStamp = timeStampLfile; - timeStampLfile += timestampInterval; - return readOffset; -} - - -static int Read_Buffer_From_Size_Nal(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - // NAL unit stream processing - char temp_size[SIZE_NAL_FIELD_MAX]; - int i = 0; - int j = 0; - unsigned int size = 0; // Need to make sure that uint32 has SIZE_NAL_FIELD_MAX (4) bytes - int bytes_read = 0; - - // read the "size_nal_field"-byte size field - bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer + pBufHdr->nOffset, nalSize); - if (bytes_read == 0 || bytes_read == -1) - { - DEBUG_PRINT("Failed to read frame or it might be EOF\n"); - return 0; - } - - for (i=0; ipBuffer[pBufHdr->nOffset + j]; - } - size = (unsigned int)(*((unsigned int *)(temp_size))); - - // now read the data - bytes_read = read(inputBufferFileFd, pBufHdr->pBuffer + pBufHdr->nOffset + nalSize, size); - if (bytes_read != size) - { - DEBUG_PRINT_ERROR("Failed to read frame\n"); - } - - pBufHdr->nTimeStamp = timeStampLfile; - timeStampLfile += timestampInterval; - - return bytes_read + nalSize; -} - -static int Read_Buffer_From_RCV_File_Seq_Layer(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - unsigned int readOffset = 0, size_struct_C = 0; - unsigned int startcode = 0; - pBufHdr->nFilledLen = 0; -#ifdef _MSM8974_ - pBufHdr->nFlags |= OMX_BUFFERFLAG_CODECCONFIG; -#else - pBufHdr->nFlags = 0; -#endif - - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - - read(inputBufferFileFd, &startcode, 4); - - /* read size of struct C as it need not be 4 always*/ - read(inputBufferFileFd, &size_struct_C, 4); - -#ifndef _MSM8974_ - /* reseek to beginning of sequence header */ - lseek64(inputBufferFileFd, -8, SEEK_CUR); -#endif - if ((startcode & 0xFF000000) == 0xC5000000) - { - - DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C); -#ifdef _MSM8974_ - readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, size_struct_C); - lseek64(inputBufferFileFd, 24, SEEK_CUR); -#else - readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, VC1_SEQ_LAYER_SIZE_WITHOUT_STRUCTC + size_struct_C); -#endif - } - else if((startcode & 0xFF000000) == 0x85000000) - { - // .RCV V1 file - - rcv_v1 = 1; - - DEBUG_PRINT("Read_Buffer_From_RCV_File_Seq_Layer size_struct_C: %d\n", size_struct_C); -#ifdef _MSM8974_ - readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, size_struct_C); - lseek64(inputBufferFileFd, 8, SEEK_CUR); -#else - readOffset = read(inputBufferFileFd, pBufHdr->pBuffer, VC1_SEQ_LAYER_SIZE_V1_WITHOUT_STRUCTC + size_struct_C); -#endif - - } - else - { - DEBUG_PRINT_ERROR("Error: Unknown VC1 clip format %x\n", startcode); - } - -#if 0 - { - int i=0; - printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", readOffset, readOffset); - for (i=0; i<36; i++) - { - printf("0x%.2x ", pBufHdr->pBuffer[i]); - if (i%16 == 15) { - printf("\n"); - } - } - printf("\n"); - } -#endif - return readOffset; -} - -static int Read_Buffer_From_RCV_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - unsigned int readOffset = 0; - unsigned int len = 0; - unsigned int key = 0; - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - - DEBUG_PRINT("Read_Buffer_From_RCV_File - nOffset %d\n", pBufHdr->nOffset); - if(rcv_v1) - { - /* for the case of RCV V1 format, the frame header is only of 4 bytes and has - only the frame size information */ - readOffset = read(inputBufferFileFd, &len, 4); - DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len); - - } - else - { - /* for a regular RCV file, 3 bytes comprise the frame size and 1 byte for key*/ - readOffset = read(inputBufferFileFd, &len, 3); - DEBUG_PRINT("Read_Buffer_From_RCV_File - framesize %d %x\n", len, len); - - readOffset = read(inputBufferFileFd, &key, 1); - if ( (key & 0x80) == false) - { - DEBUG_PRINT("Read_Buffer_From_RCV_File - Non IDR frame key %x\n", key); - } - - } - - if(!rcv_v1) - { - /* There is timestamp field only for regular RCV format and not for RCV V1 format*/ - readOffset = read(inputBufferFileFd, &pBufHdr->nTimeStamp, 4); - DEBUG_PRINT("Read_Buffer_From_RCV_File - timeStamp %d\n", pBufHdr->nTimeStamp); - pBufHdr->nTimeStamp *= 1000; - } - else - { - pBufHdr->nTimeStamp = timeStampLfile; - timeStampLfile += timestampInterval; - } - - if(len > pBufHdr->nAllocLen) - { - DEBUG_PRINT_ERROR("Error in sufficient buffer framesize %d, allocalen %d noffset %d\n",len,pBufHdr->nAllocLen, pBufHdr->nOffset); - readOffset = read(inputBufferFileFd, pBufHdr->pBuffer+pBufHdr->nOffset, - pBufHdr->nAllocLen - pBufHdr->nOffset); - - loff_t off = (len - readOffset)*1LL; - lseek64(inputBufferFileFd, off ,SEEK_CUR); - return readOffset; - } - else { - readOffset = read(inputBufferFileFd, pBufHdr->pBuffer+pBufHdr->nOffset, len); - } - if (readOffset != len) - { - DEBUG_PRINT("EOS reach or Reading error %d, %s \n", readOffset, strerror( errno )); - return 0; - } - -#if 0 - { - int i=0; - printf("Read_Buffer_From_RCV_File, length %d readOffset %d\n", len, readOffset); - for (i=0; i<64; i++) - { - printf("0x%.2x ", pBufHdr->pBuffer[i]); - if (i%16 == 15) { - printf("\n"); - } - } - printf("\n"); - } -#endif - - return readOffset; -} - -static int Read_Buffer_From_VC1_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - static int timeStampLfile = 0; - OMX_U8 *pBuffer = pBufHdr->pBuffer + pBufHdr->nOffset; - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - unsigned int readOffset = 0; - int bytes_read = 0; - unsigned int code = 0, total_bytes = 0; - int startCode_cnt = 0; - int bSEQflag = 0; - int bEntryflag = 0; - unsigned int SEQbytes = 0; - int numStartcodes = 0; - - numStartcodes = bHdrflag?1:2; - - do - { - if (total_bytes == pBufHdr->nAllocLen) - { - DEBUG_PRINT_ERROR("Buffer overflow!"); - break; - } - //Start codes are always byte aligned. - bytes_read = read(inputBufferFileFd, &pBuffer[readOffset],1 ); - - if(!bytes_read) - { - DEBUG_PRINT("\n Bytes read Zero \n"); - break; - } - total_bytes++; - code <<= 8; - code |= (0x000000FF & pBufHdr->pBuffer[readOffset]); - - if(!bSEQflag && (code == VC1_SEQUENCE_START_CODE)) { - if(startCode_cnt) bSEQflag = 1; - } - - if(!bEntryflag && ( code == VC1_ENTRY_POINT_START_CODE)) { - if(startCode_cnt) bEntryflag = 1; - } - - if(code == VC1_FRAME_START_CODE || code == VC1_FRAME_FIELD_CODE) - { - startCode_cnt++ ; - } - - //VOP start code comparision - if(startCode_cnt == numStartcodes) - { - if (VC1_FRAME_START_CODE == (code & 0xFFFFFFFF) || - VC1_FRAME_FIELD_CODE == (code & 0xFFFFFFFF)) - { - previous_vc1_au = 0; - if(VC1_FRAME_FIELD_CODE == (code & 0xFFFFFFFF)) - { - previous_vc1_au = 1; - } - - if(!bHdrflag && (bSEQflag || bEntryflag)) { - lseek(inputBufferFileFd,-(SEQbytes+4),SEEK_CUR); - readOffset -= (SEQbytes+3); - } - else { - //Seek backwards by 4 - lseek64(inputBufferFileFd, -4, SEEK_CUR); - readOffset-=3; - } - - while(pBufHdr->pBuffer[readOffset-1] == 0) - readOffset--; - - break; - } - } - readOffset++; - if(bSEQflag || bEntryflag) { - SEQbytes++; - } - }while (1); - - pBufHdr->nTimeStamp = timeStampLfile; - timeStampLfile += timestampInterval; - -#if 0 - { - int i=0; - printf("Read_Buffer_From_VC1_File, readOffset %d\n", readOffset); - for (i=0; i<64; i++) - { - printf("0x%.2x ", pBufHdr->pBuffer[i]); - if (i%16 == 15) { - printf("\n"); - } - } - printf("\n"); - } -#endif - - return readOffset; -} - -static int Read_Buffer_From_DivX_4_5_6_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ -#define MAX_NO_B_FRMS 3 // Number of non-b-frames packed in each buffer -#define N_PREV_FRMS_B 1 // Number of previous non-b-frames packed - // with a set of consecutive b-frames -#define FRM_ARRAY_SIZE (MAX_NO_B_FRMS + N_PREV_FRMS_B) - char *p_buffer = NULL; - unsigned int offset_array[FRM_ARRAY_SIZE]; - int byte_cntr, pckt_end_idx; - unsigned int read_code = 0, bytes_read, byte_pos = 0, frame_type; - unsigned int i, b_frm_idx, b_frames_found = 0, vop_set_cntr = 0; - bool pckt_ready = false; -#ifdef __DEBUG_DIVX__ - char pckt_type[20]; - int pckd_frms = 0; - static unsigned long long int total_bytes = 0; - static unsigned long long int total_frames = 0; -#endif //__DEBUG_DIVX__ - - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - - do { - p_buffer = (char *)pBufHdr->pBuffer + byte_pos; - - bytes_read = read(inputBufferFileFd, p_buffer, NUMBER_OF_ARBITRARYBYTES_READ); - byte_pos += bytes_read; - for (byte_cntr = 0; byte_cntr < bytes_read && !pckt_ready; byte_cntr++) { - read_code <<= 8; - ((char*)&read_code)[0] = p_buffer[byte_cntr]; - if (read_code == VOP_START_CODE) { - if (++byte_cntr < bytes_read) { - frame_type = p_buffer[byte_cntr]; - frame_type &= 0x000000C0; -#ifdef __DEBUG_DIVX__ - switch (frame_type) { - case 0x00: pckt_type[pckd_frms] = 'I'; break; - case 0x40: pckt_type[pckd_frms] = 'P'; break; - case 0x80: pckt_type[pckd_frms] = 'B'; break; - default: pckt_type[pckd_frms] = 'X'; - } - pckd_frms++; -#endif // __DEBUG_DIVX__ - offset_array[vop_set_cntr] = byte_pos - bytes_read + byte_cntr - 4; - if (frame_type == 0x80) { // B Frame found! - if (!b_frames_found) { - // Try to packet N_PREV_FRMS_B previous frames - // with the next consecutive B frames - i = N_PREV_FRMS_B; - while ((vop_set_cntr - i) < 0 && i > 0) i--; - b_frm_idx = vop_set_cntr - i; - if (b_frm_idx > 0) { - pckt_end_idx = b_frm_idx; - pckt_ready = true; -#ifdef __DEBUG_DIVX__ - pckt_type[b_frm_idx] = '\0'; - total_frames += b_frm_idx; -#endif //__DEBUG_DIVX__ - } - } - b_frames_found++; - } else if (b_frames_found) { - pckt_end_idx = vop_set_cntr; - pckt_ready = true; -#ifdef __DEBUG_DIVX__ - pckt_type[pckd_frms - 1] = '\0'; - total_frames += pckd_frms - 1; -#endif //__DEBUG_DIVX__ - } else if (vop_set_cntr == (FRM_ARRAY_SIZE -1)) { - pckt_end_idx = MAX_NO_B_FRMS; - pckt_ready = true; -#ifdef __DEBUG_DIVX__ - pckt_type[pckt_end_idx] = '\0'; - total_frames += pckt_end_idx; -#endif //__DEBUG_DIVX__ - } else - vop_set_cntr++; - } else { - // The vop start code was found in the last 4 bytes, - // seek backwards by 4 to include this start code - // with the next buffer. - lseek64(inputBufferFileFd, -4, SEEK_CUR); - byte_pos -= 4; -#ifdef __DEBUG_DIVX__ - pckd_frms--; -#endif //__DEBUG_DIVX__ - } - } - } - if (pckt_ready) { - loff_t off = (byte_pos - offset_array[pckt_end_idx]); - if ( lseek64(inputBufferFileFd, -1LL*off , SEEK_CUR) == -1 ){ - DEBUG_PRINT_ERROR("lseek64 with offset = %lld failed with errno %d" - ", current position =0x%llx", -1LL*off, - errno, lseek64(inputBufferFileFd, 0, SEEK_CUR)); - } - } - else { - char eofByte; - int ret = read(inputBufferFileFd, &eofByte, 1 ); - if ( ret == 0 ) { - offset_array[vop_set_cntr] = byte_pos; - pckt_end_idx = vop_set_cntr; - pckt_ready = true; -#ifdef __DEBUG_DIVX__ - pckt_type[pckd_frms] = '\0'; - total_frames += pckd_frms; -#endif //__DEBUG_DIVX__ - } - else if (ret == 1){ - if ( lseek64(inputBufferFileFd, -1, SEEK_CUR ) == -1 ){ - DEBUG_PRINT_ERROR("lseek64 failed with errno = %d, " - "current fileposition = %llx", - errno, - lseek64(inputBufferFileFd, 0, SEEK_CUR)); - } - } - else { - DEBUG_PRINT_ERROR("Error when checking for EOF"); - } - } - } while (!pckt_ready); - pBufHdr->nFilledLen = offset_array[pckt_end_idx]; - pBufHdr->nTimeStamp = timeStampLfile; - timeStampLfile += timestampInterval; -#ifdef __DEBUG_DIVX__ - total_bytes += pBufHdr->nFilledLen; - ALOGE("[DivX] Packet: Type[%s] Size[%u] TS[%lld] TB[%llx] NFrms[%lld]\n", - pckt_type, pBufHdr->nFilledLen, pBufHdr->nTimeStamp, - total_bytes, total_frames); -#endif //__DEBUG_DIVX__ - return pBufHdr->nFilledLen; -} - -static int Read_Buffer_From_DivX_311_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - static OMX_S64 timeStampLfile = 0; - char *p_buffer = NULL; - bool pkt_ready = false; - unsigned int frame_type = 0; - unsigned int bytes_read = 0; - unsigned int frame_size = 0; - unsigned int num_bytes_size = 4; - unsigned int num_bytes_frame_type = 1; - unsigned int n_offset = pBufHdr->nOffset; - - DEBUG_PRINT("Inside %s \n", __FUNCTION__); - - pBufHdr->nTimeStamp = timeStampLfile; - - if (pBufHdr != NULL) - { - p_buffer = (char *)pBufHdr->pBuffer + pBufHdr->nOffset; - } - else - { - DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: pBufHdr is NULL\n"); - return 0; - } - - if (p_buffer == NULL) - { - DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: p_bufhdr is NULL\n"); - return 0; - } - - //Read first frame based on size - //DivX 311 frame - 4 byte header with size followed by the frame - - bytes_read = read(inputBufferFileFd, &frame_size, num_bytes_size); - - DEBUG_PRINT("Read_Buffer_From_DivX_311_File: Frame size = %d\n", frame_size); - n_offset += read(inputBufferFileFd, p_buffer, frame_size); - - pBufHdr->nTimeStamp = timeStampLfile; - - timeStampLfile += timestampInterval; - - //the packet is ready to be sent - DEBUG_PRINT("\nReturning Read Buffer from Divx 311: TS=[%ld], Offset=[%d]\n", - (long int)pBufHdr->nTimeStamp, - n_offset ); - - return n_offset; -} -#ifdef _MSM8974_ -static int Read_Buffer_From_VP8_File(OMX_BUFFERHEADERTYPE *pBufHdr) -{ - static OMX_S64 timeStampLfile = 0; - char *p_buffer = NULL; - bool pkt_ready = false; - unsigned int frame_type = 0; - unsigned int bytes_read = 0; - unsigned int frame_size = 0; - unsigned int num_bytes_size = 4; - unsigned int num_bytes_frame_type = 1; - unsigned long long time_stamp; - unsigned int n_offset = pBufHdr->nOffset; - static int ivf_header_read; - - if (pBufHdr != NULL) - { - p_buffer = (char *)pBufHdr->pBuffer + pBufHdr->nOffset; - } - else - { - DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: pBufHdr is NULL\n"); - return 0; - } - - if (p_buffer == NULL) - { - DEBUG_PRINT("\n ERROR:Read_Buffer_From_DivX_311_File: p_bufhdr is NULL\n"); - return 0; - } - - if(ivf_header_read == 0) { - bytes_read = read(inputBufferFileFd, p_buffer, 32); - ivf_header_read = 1; - if(p_buffer[0] == 'D' && p_buffer[1] == 'K' && p_buffer[2] == 'I' && p_buffer[3] == 'F') - { - printf(" \n IVF header found \n "); - } else - { - printf(" \n No IVF header found \n "); - lseek(inputBufferFileFd, -32, SEEK_CUR); - } - } - bytes_read = read(inputBufferFileFd, &frame_size, 4); - bytes_read = read(inputBufferFileFd, &time_stamp, 8); - n_offset += read(inputBufferFileFd, p_buffer, frame_size); - pBufHdr->nTimeStamp = time_stamp; - return n_offset; -} -#endif -static int open_video_file () -{ - int error_code = 0; - char outputfilename[512]; - DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename); - - if ( (inputBufferFileFd = open( in_filename, O_RDONLY | O_LARGEFILE) ) == -1 ){ - DEBUG_PRINT_ERROR("Error - i/p file %s could NOT be opened errno = %d\n", - in_filename, errno); - error_code = -1; - } - else { - DEBUG_PRINT_ERROR("i/p file %s is opened \n", in_filename); - } - - if (takeYuvLog) { - strlcpy(outputfilename, "yuvframes.yuv", 14); - outputBufferFile = fopen (outputfilename, "ab"); - if (outputBufferFile == NULL) - { - DEBUG_PRINT_ERROR("ERROR - o/p file %s could NOT be opened\n", outputfilename); - error_code = -1; - } - else - { - DEBUG_PRINT("O/p file %s is opened \n", outputfilename); - } - } -#ifdef _MSM8974_ - /*if (!crcFile) { - crcFile = fopen(crclogname, "ab"); - if (!crcFile) { - printf("Failed to open CRC file\n"); - error_code = -1; - } - }*/ -#endif - return error_code; -} - -void swap_byte(char *pByte, int nbyte) -{ - int i=0; - - for (i=0; isrc.width = stride; - overlayp->src.height = sliceheight; -#ifdef MAX_RES_720P - overlayp->src.format = MDP_Y_CRCB_H2V2; - if(color_fmt == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka) - { - overlayp->src.format = MDP_Y_CRCB_H2V2_TILE; - } -#endif -#ifdef MAX_RES_1080P - overlayp->src.format = MDP_Y_CBCR_H2V2_TILE; -#endif -#ifdef _MSM8974_ - overlayp->src.format = MDP_Y_CBCR_H2V2_VENUS; -#endif - overlayp->src_rect.x = 0; - overlayp->src_rect.y = 0; - overlayp->src_rect.w = width; - overlayp->src_rect.h = height; - - if(width >= vinfo.xres) - { - overlayp->dst_rect.x = 0; - overlayp->dst_rect.w = vinfo.xres; - } - else - { - overlayp->dst_rect.x = (vinfo.xres - width)/2; - overlayp->dst_rect.w = width; - } - - if(height >= vinfo.yres) - { - overlayp->dst_rect.h = (overlayp->dst_rect.w * height)/width; - overlayp->dst_rect.y = 0; - if (overlayp->dst_rect.h < vinfo.yres) - overlayp->dst_rect.y = (vinfo.yres - overlayp->dst_rect.h)/2; - else - overlayp->dst_rect.h = vinfo.yres; - } - else - { - overlayp->dst_rect.y = (vinfo.yres - height)/2; - overlayp->dst_rect.h = height; - } - - //Decimation + MDP Downscale - overlayp->horz_deci = 0; - overlayp->vert_deci = 0; - int minHorDeci = 0; - if(overlayp->src_rect.w > 2048) { - //If the client sends us something > what a layer mixer supports - //then it means it doesn't want to use split-pipe but wants us to - //decimate. A minimum decimation of 2 will ensure that the width is - //always within layer mixer limits. - minHorDeci = 2; - } - - float horDscale = ceilf((float)overlayp->src_rect.w / - (float)overlayp->dst_rect.w); - float verDscale = ceilf((float)overlayp->src_rect.h / - (float)overlayp->dst_rect.h); - - //Next power of 2, if not already - horDscale = powf(2.0f, ceilf(log2f(horDscale))); - verDscale = powf(2.0f, ceilf(log2f(verDscale))); - - //Since MDP can do 1/4 dscale and has better quality, split the task - //between decimator and MDP downscale - horDscale /= 4.0f; - verDscale /= 4.0f; - - if(horDscale < minHorDeci) - horDscale = minHorDeci; - if((int)horDscale) - overlayp->horz_deci = (int)log2f(horDscale); - - if((int)verDscale) - overlayp->vert_deci = (int)log2f(verDscale); - - printf("overlayp->src.width = %u \n", overlayp->src.width); - printf("overlayp->src.height = %u \n", overlayp->src.height); - printf("overlayp->src_rect.x = %u \n", overlayp->src_rect.x); - printf("overlayp->src_rect.y = %u \n", overlayp->src_rect.y); - printf("overlayp->src_rect.w = %u \n", overlayp->src_rect.w); - printf("overlayp->src_rect.h = %u \n", overlayp->src_rect.h); - printf("overlayp->dst_rect.x = %u \n", overlayp->dst_rect.x); - printf("overlayp->dst_rect.y = %u \n", overlayp->dst_rect.y); - printf("overlayp->dst_rect.w = %u \n", overlayp->dst_rect.w); - printf("overlayp->dst_rect.h = %u \n", overlayp->dst_rect.h); - printf("overlayp->vert_deci = %u \n", overlayp->vert_deci); - printf("overlayp->horz_deci = %u \n", overlayp->horz_deci); - - overlayp->z_order = 0; - overlayp->alpha = 0xff; - overlayp->transp_mask = 0xFFFFFFFF; - overlayp->flags = 0; - overlayp->is_fg = 0; - - overlayp->id = MSMFB_NEW_REQUEST; - - overlay_vsync_ctrl(OMX_TRUE); - drawBG(); - vid_buf_front_id = ioctl(fb_fd, MSMFB_OVERLAY_SET, overlayp); - if (vid_buf_front_id < 0) - { - printf("ERROR: MSMFB_OVERLAY_SET failed! line=%d\n", __LINE__); - } - vid_buf_front_id = overlayp->id; - DEBUG_PRINT("\n vid_buf_front_id = %u", vid_buf_front_id); - displayYuv = 2; -} - -int overlay_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr) -{ - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; - struct msmfb_overlay_data ov_front; - memset(&ov_front, 0, sizeof(struct msmfb_overlay_data)); -#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) - MemoryHeapBase *vheap = NULL; -#endif - - DEBUG_PRINT("overlay_fb:"); - ov_front.id = overlayp->id; - if (pBufHdr->pPlatformPrivate == NULL) - { - ALOGE("overlay_fb: pPlatformPrivate is null"); - return -1; - } - pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) - pBufHdr->pPlatformPrivate)->entryList->entry; - if (pPMEMInfo == NULL) - { - - ALOGE("overlay_fb: pmem_info is null"); - return -1; - } -#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) - vheap = (MemoryHeapBase*)pPMEMInfo->pmem_fd; -#endif - - -#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) && !defined(_MSM8974_) - ov_front.data.memory_id = vheap->getHeapID(); -#else - ov_front.data.memory_id = pPMEMInfo->pmem_fd; -#endif - - ov_front.data.offset = pPMEMInfo->offset; - - DEBUG_PRINT("\n ov_front.data.memory_id = %d", ov_front.data.memory_id); - DEBUG_PRINT("\n ov_front.data.offset = %u", ov_front.data.offset); - if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, (void*)&ov_front)) - { - printf("\nERROR! MSMFB_OVERLAY_PLAY failed at frame (Line %d)\n", - __LINE__); - return -1; - } - if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) - { - printf("ERROR: FBIOPAN_DISPLAY failed! line=%d\n", __LINE__); - return -1; - } - - DEBUG_PRINT("\nMSMFB_OVERLAY_PLAY successfull"); - return 0; -} - -void overlay_unset() -{ - if (ioctl(fb_fd, MSMFB_OVERLAY_UNSET, &vid_buf_front_id)) - { - printf("\nERROR! MSMFB_OVERLAY_UNSET failed! (Line %d)\n", __LINE__); - } -} - -void render_fb(struct OMX_BUFFERHEADERTYPE *pBufHdr) -{ - unsigned int addr = 0; - OMX_OTHER_EXTRADATATYPE *pExtraData = 0; - OMX_QCOM_EXTRADATA_FRAMEINFO *pExtraFrameInfo = 0; - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL; - unsigned int destx, desty,destW, destH; -#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) - MemoryHeapBase *vheap = NULL; -#endif - - unsigned int end = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nAllocLen); - - struct mdp_blit_req *e; - union { - char dummy[sizeof(struct mdp_blit_req_list) + - sizeof(struct mdp_blit_req) * 1]; - struct mdp_blit_req_list list; - } img; - - if (fb_fd < 0) - { - DEBUG_PRINT_ERROR("Warning: /dev/fb0 is not opened!\n"); - return; - } - - img.list.count = 1; - e = &img.list.req[0]; - - addr = (unsigned int)(pBufHdr->pBuffer + pBufHdr->nFilledLen); - // align to a 4 byte boundary - addr = (addr + 3) & (~3); - - // read to the end of existing extra data sections - pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr; - - while (addr < end && pExtraData->eType != OMX_ExtraDataFrameInfo) - { - addr += pExtraData->nSize; - pExtraData = (OMX_OTHER_EXTRADATATYPE*)addr; - } - - if (pExtraData->eType != OMX_ExtraDataFrameInfo) - { - DEBUG_PRINT_ERROR("pExtraData->eType %d pExtraData->nSize %d\n",pExtraData->eType,pExtraData->nSize); - } - pExtraFrameInfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)pExtraData->data; - - pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *) - ((OMX_QCOM_PLATFORM_PRIVATE_LIST *) - pBufHdr->pPlatformPrivate)->entryList->entry; -#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) - vheap = (MemoryHeapBase *)pPMEMInfo->pmem_fd; -#endif - - - DEBUG_PRINT_ERROR("DecWidth %d DecHeight %d\n",portFmt.format.video.nStride,portFmt.format.video.nSliceHeight); - DEBUG_PRINT_ERROR("DispWidth %d DispHeight %d\n",portFmt.format.video.nFrameWidth,portFmt.format.video.nFrameHeight); - - - - e->src.width = portFmt.format.video.nStride; - e->src.height = portFmt.format.video.nSliceHeight; - e->src.format = MDP_Y_CBCR_H2V2; - e->src.offset = pPMEMInfo->offset; -#if defined(_ANDROID_) && !defined(USE_EGL_IMAGE_TEST_APP) && !defined(USE_EXTERN_PMEM_BUF) - e->src.memory_id = vheap->getHeapID(); -#else - e->src.memory_id = pPMEMInfo->pmem_fd; -#endif - - DEBUG_PRINT_ERROR("pmemOffset %d pmemID %d\n",e->src.offset,e->src.memory_id); - - e->dst.width = vinfo.xres; - e->dst.height = vinfo.yres; - e->dst.format = MDP_RGB_565; - e->dst.offset = 0; - e->dst.memory_id = fb_fd; - - e->transp_mask = 0xffffffff; - DEBUG_PRINT("Frame interlace type %d!\n", pExtraFrameInfo->interlaceType); - if(pExtraFrameInfo->interlaceType != OMX_QCOM_InterlaceFrameProgressive) - { - DEBUG_PRINT("Interlaced Frame!\n"); - e->flags = MDP_DEINTERLACE; - } - else - e->flags = 0; - e->alpha = 0xff; - - switch(displayWindow) - { - case 1: destx = 0; - desty = 0; - destW = vinfo.xres/2; - destH = vinfo.yres/2; - break; - case 2: destx = vinfo.xres/2; - desty = 0; - destW = vinfo.xres/2; - destH = vinfo.yres/2; - break; - - case 3: destx = 0; - desty = vinfo.yres/2; - destW = vinfo.xres/2; - destH = vinfo.yres/2; - break; - case 4: destx = vinfo.xres/2; - desty = vinfo.yres/2; - destW = vinfo.xres/2; - destH = vinfo.yres/2; - break; - case 0: - default: - destx = 0; - desty = 0; - destW = vinfo.xres; - destH = vinfo.yres; - } - - - if(portFmt.format.video.nFrameWidth < destW) - destW = portFmt.format.video.nFrameWidth ; - - - if(portFmt.format.video.nFrameHeight < destH) - destH = portFmt.format.video.nFrameHeight; - - e->dst_rect.x = destx; - e->dst_rect.y = desty; - e->dst_rect.w = destW; - e->dst_rect.h = destH; - - //e->dst_rect.w = 800; - //e->dst_rect.h = 480; - - e->src_rect.x = 0; - e->src_rect.y = 0; - e->src_rect.w = portFmt.format.video.nFrameWidth; - e->src_rect.h = portFmt.format.video.nFrameHeight; - - //e->src_rect.w = portFmt.format.video.nStride; - //e->src_rect.h = portFmt.format.video.nSliceHeight; - - if (ioctl(fb_fd, MSMFB_BLIT, &img)) { - DEBUG_PRINT_ERROR("MSMFB_BLIT ioctl failed!\n"); - return; - } - - if (ioctl(fb_fd, FBIOPAN_DISPLAY, &vinfo) < 0) { - DEBUG_PRINT_ERROR("FBIOPAN_DISPLAY failed! line=%d\n", __LINE__); - return; - } - - DEBUG_PRINT("render_fb complete!\n"); -} - -int disable_output_port() -{ - DEBUG_PRINT("DISABLING OP PORT\n"); - pthread_mutex_lock(&enable_lock); - sent_disabled = 1; - // Send DISABLE command - OMX_SendCommand(dec_handle, OMX_CommandPortDisable, 1, 0); - pthread_mutex_unlock(&enable_lock); - // wait for Disable event to come back - wait_for_event(); - if(p_eglHeaders) { - free(p_eglHeaders); - p_eglHeaders = NULL; - } - if (pPMEMInfo) - { - DEBUG_PRINT("Freeing in external pmem case:PMEM"); - free(pPMEMInfo); - pPMEMInfo = NULL; - } - if (pPlatformEntry) - { - DEBUG_PRINT("Freeing in external pmem case:ENTRY"); - free(pPlatformEntry); - pPlatformEntry = NULL; - } - if (pPlatformList) - { - DEBUG_PRINT("Freeing in external pmem case:LIST"); - free(pPlatformList); - pPlatformList = NULL; - } - if (currentStatus == ERROR_STATE) - { - do_freeHandle_and_clean_up(true); - return -1; - } - DEBUG_PRINT("OP PORT DISABLED!\n"); - return 0; -} - -int enable_output_port() -{ - int bufCnt = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - DEBUG_PRINT("ENABLING OP PORT\n"); - // Send Enable command - OMX_SendCommand(dec_handle, OMX_CommandPortEnable, 1, 0); -#ifndef USE_EGL_IMAGE_TEST_APP - /* Allocate buffer on decoder's o/p port */ - portFmt.nPortIndex = 1; - - if (anti_flickering) { - ret = OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); - if (ret != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("%s: OMX_GetParameter failed: %d",__FUNCTION__, ret); - return -1; - } - portFmt.nBufferCountActual += 1; - ret = OMX_SetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); - if (ret != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("%s: OMX_SetParameter failed: %d",__FUNCTION__, ret); - return -1; - } - } - - if (use_external_pmem_buf) - { - DEBUG_PRINT("Enable op port: calling use_buffer_mult_fd\n"); - error = use_output_buffer_multiple_fd(dec_handle, - &pOutYUVBufHdrs, - portFmt.nPortIndex, - portFmt.nBufferSize, - portFmt.nBufferCountActual); - } - else - { - error = Allocate_Buffer(dec_handle, &pOutYUVBufHdrs, portFmt.nPortIndex, - portFmt.nBufferCountActual, portFmt.nBufferSize); - } - if (error != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("Error - OMX_AllocateBuffer Output buffer error\n"); - return -1; - } - else - { - DEBUG_PRINT("OMX_AllocateBuffer Output buffer success\n"); - free_op_buf_cnt = portFmt.nBufferCountActual; - } -#else - error = use_output_buffer(dec_handle, - &pOutYUVBufHdrs, - portFmt.nPortIndex, - portFmt.nBufferSize, - portFmt.nBufferCountActual); - free_op_buf_cnt = portFmt.nBufferCountActual; - if (error != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("ERROR - OMX_UseBuffer Input buffer failed"); - return -1; - } - else { - DEBUG_PRINT("OMX_UseBuffer Input buffer success\n"); - } - -#endif - // wait for enable event to come back - wait_for_event(); - if (currentStatus == ERROR_STATE) - { - do_freeHandle_and_clean_up(true); - return -1; - } - if (pOutYUVBufHdrs == NULL) - { - DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs is NULL\n"); - return -1; - } - for(bufCnt=0; bufCnt < portFmt.nBufferCountActual; ++bufCnt) { - DEBUG_PRINT("OMX_FillThisBuffer on output buf no.%d\n",bufCnt); - if (pOutYUVBufHdrs[bufCnt] == NULL) - { - DEBUG_PRINT_ERROR("Error - pOutYUVBufHdrs[%d] is NULL\n", bufCnt); - return -1; - } - pOutYUVBufHdrs[bufCnt]->nOutputPortIndex = 1; - pOutYUVBufHdrs[bufCnt]->nFlags &= ~OMX_BUFFERFLAG_EOS; - ret = OMX_FillThisBuffer(dec_handle, pOutYUVBufHdrs[bufCnt]); - if (OMX_ErrorNone != ret) { - DEBUG_PRINT_ERROR("ERROR - OMX_FillThisBuffer failed with result %d\n", ret); - } - else - { - DEBUG_PRINT("OMX_FillThisBuffer success!\n"); - free_op_buf_cnt--; - } - } - DEBUG_PRINT("OP PORT ENABLED!\n"); - return 0; -} - -int output_port_reconfig() -{ - DEBUG_PRINT("PORT_SETTING_CHANGE_STATE\n"); - if (disable_output_port() != 0) - return -1; - - /* Port for which the Client needs to obtain info */ - portFmt.nPortIndex = 1; - OMX_GetParameter(dec_handle,OMX_IndexParamPortDefinition,&portFmt); - DEBUG_PRINT("Min Buffer Count=%d", portFmt.nBufferCountMin); - DEBUG_PRINT("Buffer Size=%d", portFmt.nBufferSize); - if(OMX_DirOutput != portFmt.eDir) { - DEBUG_PRINT_ERROR("Error - Expect Output Port\n"); - return -1; - } - height = portFmt.format.video.nFrameHeight; - width = portFmt.format.video.nFrameWidth; - stride = portFmt.format.video.nStride; - sliceheight = portFmt.format.video.nSliceHeight; - - crop_rect.nWidth = width; - crop_rect.nHeight = height; - - if (displayYuv == 2) - { - DEBUG_PRINT("Reconfiguration at middle of playback..."); - close_display(); - if (open_display() != 0) - { - printf("\n Error opening display! Video won't be displayed..."); - displayYuv = 0; - } - } - - if (displayYuv) - overlay_set(); - - if (enable_output_port() != 0) - return -1; - DEBUG_PRINT("PORT_SETTING_CHANGE DONE!\n"); - return 0; -} - -void free_output_buffers() -{ - int index = 0; - OMX_BUFFERHEADERTYPE *pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue); - while (pBuffer) { - DEBUG_PRINT("\n pOutYUVBufHdrs %p p_eglHeaders %p output_use_buffer %d", - pOutYUVBufHdrs,p_eglHeaders,output_use_buffer); - if(pOutYUVBufHdrs && p_eglHeaders && output_use_buffer) - { - index = pBuffer - pOutYUVBufHdrs[0]; - DEBUG_PRINT("\n Index of free buffer %d",index); - DEBUG_PRINT("\n Address freed %p size freed %d",pBuffer->pBuffer, - pBuffer->nAllocLen); - munmap((void *)use_buf_virt_addr[index],pBuffer->nAllocLen); - if(p_eglHeaders[index]) - { - close(p_eglHeaders[index]->pmem_fd); - free(p_eglHeaders[index]); - p_eglHeaders[index] = NULL; - } - } - - if (pOutYUVBufHdrs && use_external_pmem_buf) - { - index = pBuffer - pOutYUVBufHdrs[0]; - DEBUG_PRINT("\n Address freed %p size freed %d,virt=0x%x,pmem_fd=0x%x", - pBuffer->pBuffer, - pBuffer->nAllocLen, - use_buf_virt_addr[index], - pPMEMInfo[index].pmem_fd); - munmap((void *)use_buf_virt_addr[index],pBuffer->nAllocLen); - getFreePmem(); - use_buf_virt_addr[index] = -1; - if (&pPMEMInfo[index]) - { - close(pPMEMInfo[index].pmem_fd); - pPMEMInfo[index].pmem_fd = -1; - } - } - DEBUG_PRINT("\n Free output buffer"); - OMX_FreeBuffer(dec_handle, 1, pBuffer); - pBuffer = (OMX_BUFFERHEADERTYPE *)pop(fbd_queue); - } -} - -#ifndef USE_ION -static bool align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size, - OMX_U32 alignment) -{ - struct pmem_allocation allocation; - allocation.size = buffer_size; - allocation.align = clip2(alignment); - - if (allocation.align < 4096) - { - allocation.align = 4096; - } - if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) - { - DEBUG_PRINT_ERROR("\n Aligment failed with pmem driver"); - return false; - } - return true; -} -#endif - -int open_display() -{ -#ifdef _ANDROID_ - DEBUG_PRINT("\n Opening /dev/graphics/fb0"); - fb_fd = open("/dev/graphics/fb0", O_RDWR); -#else - DEBUG_PRINT("\n Opening /dev/fb0"); - fb_fd = open("/dev/fb0", O_RDWR); -#endif - if (fb_fd < 0) { - printf("[omx_vdec_test] - ERROR - can't open framebuffer!\n"); - return -1; - } - - DEBUG_PRINT("\n fb_fd = %d", fb_fd); - if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) < 0) - { - printf("[omx_vdec_test] - ERROR - can't retrieve fscreenInfo!\n"); - close(fb_fd); - return -1; - } - if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo) < 0) - { - printf("[omx_vdec_test] - ERROR - can't retrieve vscreenInfo!\n"); - close(fb_fd); - return -1; - } - printf("Display xres = %d, yres = %d \n", vinfo.xres, vinfo.yres); - return 0; -} - -void close_display() -{ - overlay_unset(); - overlay_vsync_ctrl(OMX_FALSE); - close(fb_fd); - fb_fd = -1; -} - -void getFreePmem() -{ -#ifndef USE_ION - int ret = -1; - /*Open pmem device and query free pmem*/ - int pmem_fd = open (PMEM_DEVICE,O_RDWR); - - if(pmem_fd < 0) { - ALOGE("Unable to open pmem device"); - return; - } - struct pmem_freespace fs; - ret = ioctl(pmem_fd, PMEM_GET_FREE_SPACE, &fs); - if(ret) { - ALOGE("IOCTL to query pmem free space failed"); - goto freespace_query_failed; - } - ALOGE("Available free space %lx largest chunk %lx\n", fs.total, fs.largest); -freespace_query_failed: - close(pmem_fd); -#endif -} diff --git a/mm-video/vidc/venc/Android.mk b/mm-video/vidc/venc/Android.mk deleted file mode 100644 index cb3429ae..00000000 --- a/mm-video/vidc/venc/Android.mk +++ /dev/null @@ -1,172 +0,0 @@ -ifneq ($(BUILD_TINY_ANDROID),true) - -ROOT_DIR := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_PATH:= $(ROOT_DIR) - -# --------------------------------------------------------------------------------- -# Common definitons -# --------------------------------------------------------------------------------- - -libmm-venc-def := -g -O3 -Dlrintf=_ffix_r -libmm-venc-def += -D__align=__alignx -libmm-venc-def += -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\) -libmm-venc-def += -DT_ARM -libmm-venc-def += -Dinline=__inline -libmm-venc-def += -D_ANDROID_ -libmm-venc-def += -UENABLE_DEBUG_LOW -libmm-venc-def += -DENABLE_DEBUG_HIGH -libmm-venc-def += -DENABLE_DEBUG_ERROR -libmm-venc-def += -UINPUT_BUFFER_LOG -libmm-venc-def += -UOUTPUT_BUFFER_LOG -libmm-venc-def += -USINGLE_ENCODER_INSTANCE -ifeq ($(TARGET_BOARD_PLATFORM),msm8660) -libmm-venc-def += -DMAX_RES_1080P -libmm-venc-def += -UENABLE_GET_SYNTAX_HDR -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8960) -libmm-venc-def += -DMAX_RES_1080P -libmm-venc-def += -DMAX_RES_1080P_EBI -libmm-venc-def += -UENABLE_GET_SYNTAX_HDR -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8974) -libmm-venc-def += -DMAX_RES_1080P -libmm-venc-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libmm-venc-def += -D_MSM8974_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm7627a) -libmm-venc-def += -DMAX_RES_720P -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm7630_surf) -libmm-venc-def += -DMAX_RES_720P -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8610) -libmm-venc-def += -DMAX_RES_720P -libmm-venc-def += -D_MSM8974_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),msm8226) -libmm-venc-def += -DMAX_RES_1080P -libmm-venc-def += -D_MSM8974_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),apq8084) -libmm-venc-def += -DMAX_RES_1080P -libmm-venc-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libmm-venc-def += -D_MSM8974_ -endif -ifeq ($(TARGET_BOARD_PLATFORM),mpq8092) -libmm-venc-def += -DMAX_RES_1080P -libmm-venc-def += -DMAX_RES_1080P_EBI -libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT -libmm-venc-def += -D_MSM8974_ -endif - -ifeq ($(TARGET_USES_ION),true) -libmm-venc-def += -DUSE_ION -endif - -venc-inc = $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include - -libmm-venc-def += -D_ANDROID_ICS_ -# --------------------------------------------------------------------------------- -# Make the Shared library (libOmxVenc) -# --------------------------------------------------------------------------------- - -include $(CLEAR_VARS) - -libmm-venc-inc := bionic/libc/include -libmm-venc-inc += bionic/libstdc++/include -libmm-venc-inc += $(LOCAL_PATH)/inc -libmm-venc-inc += $(OMX_VIDEO_PATH)/vidc/common/inc -libmm-venc-inc += hardware/qcom/media/mm-core/inc -libmm-venc-inc += hardware/qcom/media/libstagefrighthw -libmm-venc-inc += hardware/qcom/display/libgralloc -libmm-venc-inc += frameworks/native/include/media/hardware -libmm-venc-inc += frameworks/native/include/media/openmax -libmm-venc-inc += hardware/qcom/media/libc2dcolorconvert -libmm-venc-inc += hardware/qcom/display/libcopybit -libmm-venc-inc += frameworks/av/include/media/stagefright -libmm-venc-inc += $(venc-inc) - -LOCAL_MODULE := libOmxVenc -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := $(libmm-venc-def) -LOCAL_C_INCLUDES := $(libmm-venc-inc) - -LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils \ - libc2dcolorconvert libdl - -LOCAL_SRC_FILES := src/omx_video_base.cpp -LOCAL_SRC_FILES += src/omx_video_encoder.cpp -ifeq ($(call is-board-platform-in-list,msm8974 msm8610 msm8226 apq8084 mpq8092),true) -LOCAL_SRC_FILES += src/video_encoder_device_v4l2.cpp -else -LOCAL_SRC_FILES += src/video_encoder_device.cpp -endif - -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr - -LOCAL_SRC_FILES += ../common/src/extra_data_handler.cpp - -include $(BUILD_SHARED_LIBRARY) - -# ----------------------------------------------------------------------------- -# # Make the apps-test (mm-venc-omx-test720p) -# ----------------------------------------------------------------------------- - -include $(CLEAR_VARS) - -mm-venc-test720p-inc := $(TARGET_OUT_HEADERS)/mm-core -mm-venc-test720p-inc += $(LOCAL_PATH)/inc -mm-venc-test720p-inc += $(OMX_VIDEO_PATH)/vidc/common/inc -mm-venc-test720p-inc += hardware/qcom/media/mm-core/inc -mm-venc-test720p-inc += hardware/qcom/display/libgralloc -mm-venc-test720p-inc += $(venc-inc) - -LOCAL_MODULE := mm-venc-omx-test720p -LOCAL_MODULE_TAGS := optional -LOCAL_CFLAGS := $(libmm-venc-def) -LOCAL_C_INCLUDES := $(mm-venc-test720p-inc) -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr -LOCAL_PRELINK_MODULE := false -LOCAL_SHARED_LIBRARIES := libmm-omxcore libOmxVenc libbinder liblog - -LOCAL_SRC_FILES := test/venc_test.cpp -LOCAL_SRC_FILES += test/camera_test.cpp -LOCAL_SRC_FILES += test/venc_util.c -LOCAL_SRC_FILES += test/fb_test.c - -include $(BUILD_EXECUTABLE) - -# ----------------------------------------------------------------------------- -# Make the apps-test (mm-video-driver-test) -# ----------------------------------------------------------------------------- - -include $(CLEAR_VARS) - -venc-test-inc += $(LOCAL_PATH)/inc -venc-test-inc += hardware/qcom/display/libgralloc -venc-test-inc += $(venc-inc) - -LOCAL_MODULE := mm-video-encdrv-test -LOCAL_MODULE_TAGS := optional -LOCAL_C_INCLUDES := $(venc-test-inc) -LOCAL_C_INCLUDES += hardware/qcom/media/mm-core/inc - -LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr -LOCAL_PRELINK_MODULE := false - -LOCAL_SRC_FILES := test/video_encoder_test.c -LOCAL_SRC_FILES += test/queue.c - -include $(BUILD_EXECUTABLE) - -endif #BUILD_TINY_ANDROID - -# --------------------------------------------------------------------------------- -# END -# --------------------------------------------------------------------------------- - diff --git a/mm-video/vidc/venc/inc/camera_test.h b/mm-video/vidc/venc/inc/camera_test.h deleted file mode 100755 index 53bc2da6..00000000 --- a/mm-video/vidc/venc/inc/camera_test.h +++ /dev/null @@ -1,58 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef _CAMERA_TEST_H -#define _CAMERA_TEST_H - -#define EXTERN_C_START extern "C" { -#define EXTERN_C_END } - -#ifdef __cplusplus -EXTERN_C_START -#endif - -typedef void (*CameraPreviewCallback)(int nFD, - int nOffset, - void* pPhys, - void* pVirt, - long long nTimeStamp); - - -int CameraTest_Initialize(int nFrameRate, - int nFrameWidth, - int nFrameHeight, - CameraPreviewCallback pfnPreviewCallback); -int CameraTest_Run(); -int CameraTest_ReleaseFrame(void* pPhys, void* pVirt); -int CameraTest_Exit(); - - -#ifdef __cplusplus -EXTERN_C_END -#endif - -#endif diff --git a/mm-video/vidc/venc/inc/fb_test.h b/mm-video/vidc/venc/inc/fb_test.h deleted file mode 100755 index 52a007f1..00000000 --- a/mm-video/vidc/venc/inc/fb_test.h +++ /dev/null @@ -1,48 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef _FB_TEST_H -#define _FB_TEST_H - -#ifdef __cplusplus -extern "C" { -#endif - - -int FBTest_Initialize(int nFrameWidth, - int nFrameHeight); -int FBTest_DisplayImage(int nPmemFd, int nOffset); -int FBTest_Exit(); - -int FBTest_RunTest(); - -#ifdef __cplusplus -} -#endif - - -#endif // _FB_TEST_H diff --git a/mm-video/vidc/venc/inc/omx_video_base.h b/mm-video/vidc/venc/inc/omx_video_base.h deleted file mode 100644 index 58b0d4fa..00000000 --- a/mm-video/vidc/venc/inc/omx_video_base.h +++ /dev/null @@ -1,621 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#ifndef __OMX_VIDEO_BASE_H__ -#define __OMX_VIDEO_BASE_H__ -/*============================================================================ - O p e n M A X Component - Video Encoder - -*//** @file comx_video_base.h - This module contains the class definition for openMAX decoder component. - -*//*========================================================================*/ - -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// - -#define LOG_TAG "OMX-VENC-720p" -#include -#include -#include -#ifdef _ANDROID_ - #include -#ifdef _ANDROID_ICS_ - #include "QComOMXMetadata.h" -#endif -#endif // _ANDROID_ -#include -#include -#include -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "qc_omx_component.h" -#include "omx_video_common.h" -#include "extra_data_handler.h" -#include -#include -#include "C2DColorConverter.h" - -#ifdef _ANDROID_ -using namespace android; -// local pmem heap object -class VideoHeap : public MemoryHeapBase -{ -public: - VideoHeap(int fd, size_t size, void* base); - virtual ~VideoHeap() {} -}; - -#include - -#else //_ANDROID_ -#define DEBUG_PRINT_LOW -#define DEBUG_PRINT_HIGH -#define DEBUG_PRINT_ERROR -#endif // _ANDROID_ - -#ifdef USE_ION - static const char* MEM_DEVICE = "/dev/ion"; - #if defined(MAX_RES_720P) && !defined(_MSM8974_) - #define MEM_HEAP_ID ION_CAMERA_HEAP_ID - #else - #ifdef _MSM8974_ - #define MEM_HEAP_ID ION_IOMMU_HEAP_ID - #else - #define MEM_HEAP_ID ION_CP_MM_HEAP_ID - #endif - #endif -#elif MAX_RES_720P -static const char* MEM_DEVICE = "/dev/pmem_adsp"; -#elif MAX_RES_1080P_EBI -static const char* MEM_DEVICE = "/dev/pmem_adsp"; -#elif MAX_RES_1080P -static const char* MEM_DEVICE = "/dev/pmem_smipool"; -#else -#error MEM_DEVICE cannot be determined. -#endif - -////////////////////////////////////////////////////////////////////////////// -// Module specific globals -////////////////////////////////////////////////////////////////////////////// - -#define OMX_SPEC_VERSION 0x00000101 - - -////////////////////////////////////////////////////////////////////////////// -// Macros -////////////////////////////////////////////////////////////////////////////// -#define PrintFrameHdr(bufHdr) DEBUG_PRINT("bufHdr %x buf %x size %d TS %d\n",\ - (unsigned) bufHdr,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\ - (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp) - -// BitMask Management logic -#define BITS_PER_BYTE 32 -#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE) -#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE) -#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE)) -#define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ - &= ~(BITMASK_FLAG(mIndex)) -#define BITMASK_SET(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \ - |= BITMASK_FLAG(mIndex) -#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) -#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) == 0x0) -#define BITMASK_PRESENT(mArray,mIndex) ((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) -#define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \ - & BITMASK_FLAG(mIndex)) == 0x0) -#ifdef _ANDROID_ICS_ -#define MAX_NUM_INPUT_BUFFERS 32 -#endif -void* message_thread(void *); -#ifdef USE_ION -int alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data,int flag); -void free_ion_memory(struct venc_ion *buf_ion_info); -#endif - -// OMX video class -class omx_video: public qc_omx_component -{ -protected: -#ifdef _ANDROID_ICS_ - bool meta_mode_enable; - bool c2d_opened; - encoder_media_buffer_type meta_buffers[MAX_NUM_INPUT_BUFFERS]; - OMX_BUFFERHEADERTYPE *opaque_buffer_hdr[MAX_NUM_INPUT_BUFFERS]; - bool mUseProxyColorFormat; - bool get_syntaxhdr_enable; - OMX_BUFFERHEADERTYPE *psource_frame; - OMX_BUFFERHEADERTYPE *pdest_frame; - - class omx_c2d_conv { - public: - omx_c2d_conv(); - ~omx_c2d_conv(); - bool init(); - bool open(unsigned int height,unsigned int width, - ColorConvertFormat src, - ColorConvertFormat dest,unsigned int src_stride); - bool convert(int src_fd, void *src_base, void *src_viraddr, - int dest_fd, void *dest_base, void *dest_viraddr); - bool get_buffer_size(int port,unsigned int &buf_size); - int get_src_format(); - void close(); - private: - C2DColorConverterBase *c2dcc; - pthread_mutex_t c_lock; - void *mLibHandle; - ColorConvertFormat src_format; - createC2DColorConverter_t *mConvertOpen; - destroyC2DColorConverter_t *mConvertClose; - }; - omx_c2d_conv c2d_conv; -#endif -public: - omx_video(); // constructor - virtual ~omx_video(); // destructor - - // virtual int async_message_process (void *context, void* message); - void process_event_cb(void *ctxt,unsigned char id); - - OMX_ERRORTYPE allocate_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes - ); - - - virtual OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp)= 0; - - virtual OMX_ERRORTYPE component_init(OMX_STRING role)= 0; - - virtual OMX_U32 dev_stop(void) = 0; - virtual OMX_U32 dev_pause(void) = 0; - virtual OMX_U32 dev_start(void) = 0; - virtual OMX_U32 dev_flush(unsigned) = 0; - virtual OMX_U32 dev_resume(void) = 0; - virtual OMX_U32 dev_start_done(void) = 0; - virtual OMX_U32 dev_set_message_thread_id(pthread_t) = 0; - virtual bool dev_use_buf(void *,unsigned,unsigned) = 0; - virtual bool dev_free_buf(void *,unsigned) = 0; - virtual bool dev_empty_buf(void *, void *,unsigned,unsigned) = 0; - virtual bool dev_fill_buf(void *buffer, void *,unsigned,unsigned) = 0; - virtual bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32) = 0; - virtual bool dev_get_seq_hdr(void *, unsigned, unsigned *) = 0; - virtual bool dev_loaded_start(void) = 0; - virtual bool dev_loaded_stop(void) = 0; - virtual bool dev_loaded_start_done(void) = 0; - virtual bool dev_loaded_stop_done(void) = 0; -#ifdef _MSM8974_ - virtual int dev_handle_extradata(void*, int) = 0; - virtual int dev_set_format(int) = 0; -#endif - virtual bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height) = 0; - virtual bool dev_get_capability_ltrcount(OMX_U32 *, OMX_U32 *, OMX_U32 *) = 0; -#ifdef _ANDROID_ICS_ - void omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer); -#endif - OMX_ERRORTYPE component_role_enum( - OMX_HANDLETYPE hComp, - OMX_U8 *role, - OMX_U32 index - ); - - OMX_ERRORTYPE component_tunnel_request( - OMX_HANDLETYPE hComp, - OMX_U32 port, - OMX_HANDLETYPE peerComponent, - OMX_U32 peerPort, - OMX_TUNNELSETUPTYPE *tunnelSetup - ); - - OMX_ERRORTYPE empty_this_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - - - OMX_ERRORTYPE fill_this_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer - ); - - - OMX_ERRORTYPE free_buffer( - OMX_HANDLETYPE hComp, - OMX_U32 port, - OMX_BUFFERHEADERTYPE *buffer - ); - - OMX_ERRORTYPE get_component_version( - OMX_HANDLETYPE hComp, - OMX_STRING componentName, - OMX_VERSIONTYPE *componentVersion, - OMX_VERSIONTYPE *specVersion, - OMX_UUIDTYPE *componentUUID - ); - - OMX_ERRORTYPE get_config( - OMX_HANDLETYPE hComp, - OMX_INDEXTYPE configIndex, - OMX_PTR configData - ); - - OMX_ERRORTYPE get_extension_index( - OMX_HANDLETYPE hComp, - OMX_STRING paramName, - OMX_INDEXTYPE *indexType - ); - - OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE paramIndex, - OMX_PTR paramData); - - OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp, - OMX_STATETYPE *state); - - - - OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp, - OMX_COMMANDTYPE cmd, - OMX_U32 param1, - OMX_PTR cmdData); - - - OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp, - OMX_CALLBACKTYPE *callbacks, - OMX_PTR appData); - - virtual OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE configIndex, - OMX_PTR configData) = 0; - - virtual OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE paramIndex, - OMX_PTR paramData) =0; - - OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8 *buffer); - - - OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - void * eglImage); - - - - int m_pipe_in; - int m_pipe_out; - - pthread_t msg_thread_id; - pthread_t async_thread_id; - bool async_thread_created; - bool msg_thread_created; - - OMX_U8 m_nkind[128]; - - - //int *input_pmem_fd; - //int *output_pmem_fd; - struct pmem *m_pInput_pmem; - struct pmem *m_pOutput_pmem; -#ifdef USE_ION - struct venc_ion *m_pInput_ion; - struct venc_ion *m_pOutput_ion; -#endif - - - -public: - // Bit Positions - enum flags_bit_positions - { - // Defer transition to IDLE - OMX_COMPONENT_IDLE_PENDING =0x1, - // Defer transition to LOADING - OMX_COMPONENT_LOADING_PENDING =0x2, - // First Buffer Pending - OMX_COMPONENT_FIRST_BUFFER_PENDING =0x3, - // Second Buffer Pending - OMX_COMPONENT_SECOND_BUFFER_PENDING =0x4, - // Defer transition to Enable - OMX_COMPONENT_INPUT_ENABLE_PENDING =0x5, - // Defer transition to Enable - OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x6, - // Defer transition to Disable - OMX_COMPONENT_INPUT_DISABLE_PENDING =0x7, - // Defer transition to Disable - OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x8, - //defer flush notification - OMX_COMPONENT_OUTPUT_FLUSH_PENDING =0x9, - OMX_COMPONENT_INPUT_FLUSH_PENDING =0xA, - OMX_COMPONENT_PAUSE_PENDING =0xB, - OMX_COMPONENT_EXECUTE_PENDING =0xC, - OMX_COMPONENT_LOADED_START_PENDING = 0xD, - OMX_COMPONENT_LOADED_STOP_PENDING = 0xF, - - }; - - // Deferred callback identifiers - enum - { - //Event Callbacks from the venc component thread context - OMX_COMPONENT_GENERATE_EVENT = 0x1, - //Buffer Done callbacks from the venc component thread context - OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2, - //Frame Done callbacks from the venc component thread context - OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3, - //Buffer Done callbacks from the venc component thread context - OMX_COMPONENT_GENERATE_FTB = 0x4, - //Frame Done callbacks from the venc component thread context - OMX_COMPONENT_GENERATE_ETB = 0x5, - //Command - OMX_COMPONENT_GENERATE_COMMAND = 0x6, - //Push-Pending Buffers - OMX_COMPONENT_PUSH_PENDING_BUFS = 0x7, - // Empty Buffer Done callbacks - OMX_COMPONENT_GENERATE_EBD = 0x8, - //Flush Event Callbacks from the venc component thread context - OMX_COMPONENT_GENERATE_EVENT_FLUSH = 0x9, - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH = 0x0A, - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH = 0x0B, - OMX_COMPONENT_GENERATE_FBD = 0xc, - OMX_COMPONENT_GENERATE_START_DONE = 0xD, - OMX_COMPONENT_GENERATE_PAUSE_DONE = 0xE, - OMX_COMPONENT_GENERATE_RESUME_DONE = 0xF, - OMX_COMPONENT_GENERATE_STOP_DONE = 0x10, - OMX_COMPONENT_GENERATE_HARDWARE_ERROR = 0x11, - OMX_COMPONENT_GENERATE_LTRUSE_FAILED = 0x12, - OMX_COMPONENT_GENERATE_ETB_OPQ = 0x13 - }; - - struct omx_event - { - unsigned param1; - unsigned param2; - unsigned id; - }; - - struct omx_cmd_queue - { - omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE]; - unsigned m_read; - unsigned m_write; - unsigned m_size; - - omx_cmd_queue(); - ~omx_cmd_queue(); - bool insert_entry(unsigned p1, unsigned p2, unsigned id); - bool pop_entry(unsigned *p1,unsigned *p2, unsigned *id); - // get msgtype of the first ele from the queue - unsigned get_q_msg_type(); - - }; - - bool allocate_done(void); - bool allocate_input_done(void); - bool allocate_output_done(void); - - OMX_ERRORTYPE free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr); - - OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes); -#ifdef _ANDROID_ICS_ - OMX_ERRORTYPE allocate_input_meta_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_PTR appData, - OMX_U32 bytes); -#endif - OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port,OMX_PTR appData, - OMX_U32 bytes); - - OMX_ERRORTYPE use_input_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8 *buffer); - - OMX_ERRORTYPE use_output_buffer(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_U32 port, - OMX_PTR appData, - OMX_U32 bytes, - OMX_U8 *buffer); - - bool execute_omx_flush(OMX_U32); - bool execute_output_flush(void); - bool execute_input_flush(void); -#ifdef _MSM8974_ - bool execute_flush_all(void); -#endif - OMX_ERRORTYPE empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE * buffer); - - OMX_ERRORTYPE fill_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE * buffer); - OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer); - OMX_ERRORTYPE empty_this_buffer_opaque(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer); - OMX_ERRORTYPE push_input_buffer(OMX_HANDLETYPE hComp); - OMX_ERRORTYPE convert_queue_buffer(OMX_HANDLETYPE hComp, - struct pmem &Input_pmem_info,unsigned &index); - OMX_ERRORTYPE queue_meta_buffer(OMX_HANDLETYPE hComp, - struct pmem &Input_pmem_info); - OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE *buffer); - bool release_done(); - - bool release_output_done(); - bool release_input_done(); - - OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp, - OMX_COMMANDTYPE cmd, - OMX_U32 param1, - OMX_PTR cmdData); - bool post_event( unsigned int p1, - unsigned int p2, - unsigned int id - ); - OMX_ERRORTYPE get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType); - inline void omx_report_error () - { - if(m_pCallbacks.EventHandler && !m_error_propogated) - { - m_error_propogated = true; - m_pCallbacks.EventHandler(&m_cmp,m_app_data, - OMX_EventError,OMX_ErrorHardware,0,NULL); - } - } - - inline void omx_report_unsupported_setting () - { - if(m_pCallbacks.EventHandler && !m_error_propogated) - { - m_error_propogated = true; - m_pCallbacks.EventHandler(&m_cmp,m_app_data, - OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL); - } - } - - void complete_pending_buffer_done_cbs(); - - //************************************************************* - //*******************MEMBER VARIABLES ************************* - //************************************************************* - - pthread_mutex_t m_lock; - sem_t m_cmd_lock; - bool m_error_propogated; - - //sem to handle the minimum procesing of commands - - - // compression format - //OMX_VIDEO_CODINGTYPE eCompressionFormat; - // OMX State - OMX_STATETYPE m_state; - // Application data - OMX_PTR m_app_data; - OMX_BOOL m_use_input_pmem; - OMX_BOOL m_use_output_pmem; - // Application callbacks - OMX_CALLBACKTYPE m_pCallbacks; - OMX_PORT_PARAM_TYPE m_sPortParam; - OMX_VIDEO_PARAM_PROFILELEVELTYPE m_sParamProfileLevel; - OMX_VIDEO_PARAM_PORTFORMATTYPE m_sInPortFormat; - OMX_VIDEO_PARAM_PORTFORMATTYPE m_sOutPortFormat; - OMX_PARAM_PORTDEFINITIONTYPE m_sInPortDef; - OMX_PARAM_PORTDEFINITIONTYPE m_sOutPortDef; - OMX_VIDEO_PARAM_MPEG4TYPE m_sParamMPEG4; - OMX_VIDEO_PARAM_H263TYPE m_sParamH263; - OMX_VIDEO_PARAM_AVCTYPE m_sParamAVC; - OMX_PORT_PARAM_TYPE m_sPortParam_img; - OMX_PORT_PARAM_TYPE m_sPortParam_audio; - OMX_VIDEO_CONFIG_BITRATETYPE m_sConfigBitrate; - OMX_CONFIG_FRAMERATETYPE m_sConfigFramerate; - OMX_VIDEO_PARAM_BITRATETYPE m_sParamBitrate; - OMX_PRIORITYMGMTTYPE m_sPriorityMgmt; - OMX_PARAM_BUFFERSUPPLIERTYPE m_sInBufSupplier; - OMX_PARAM_BUFFERSUPPLIERTYPE m_sOutBufSupplier; - OMX_CONFIG_ROTATIONTYPE m_sConfigFrameRotation; - OMX_CONFIG_INTRAREFRESHVOPTYPE m_sConfigIntraRefreshVOP; - OMX_VIDEO_PARAM_QUANTIZATIONTYPE m_sSessionQuantization; - OMX_QCOM_VIDEO_PARAM_QPRANGETYPE m_sSessionQPRange; - OMX_VIDEO_PARAM_AVCSLICEFMO m_sAVCSliceFMO; - QOMX_VIDEO_INTRAPERIODTYPE m_sIntraperiod; - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE m_sErrorCorrection; - OMX_VIDEO_PARAM_INTRAREFRESHTYPE m_sIntraRefresh; - QOMX_VIDEO_PARAM_LTRMODE_TYPE m_sParamLTRMode; - QOMX_VIDEO_PARAM_LTRCOUNT_TYPE m_sParamLTRCount; - QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE m_sConfigLTRPeriod; - QOMX_VIDEO_CONFIG_LTRUSE_TYPE m_sConfigLTRUse; - OMX_VIDEO_CONFIG_AVCINTRAPERIOD m_sConfigAVCIDRPeriod; - OMX_U32 m_sExtraData; - OMX_U32 m_input_msg_id; - - // fill this buffer queue - omx_cmd_queue m_ftb_q; - // Command Q for rest of the events - omx_cmd_queue m_cmd_q; - omx_cmd_queue m_etb_q; - // Input memory pointer - OMX_BUFFERHEADERTYPE *m_inp_mem_ptr; - // Output memory pointer - OMX_BUFFERHEADERTYPE *m_out_mem_ptr; - omx_cmd_queue m_opq_meta_q; - omx_cmd_queue m_opq_pmem_q; - OMX_BUFFERHEADERTYPE meta_buffer_hdr[MAX_NUM_INPUT_BUFFERS]; - - bool input_flush_progress; - bool output_flush_progress; - bool input_use_buffer; - bool output_use_buffer; - int pending_input_buffers; - int pending_output_buffers; - - unsigned int m_out_bm_count; - unsigned int m_inp_bm_count; - unsigned int m_flags; - unsigned int m_etb_count; - unsigned int m_fbd_count; -#ifdef _ANDROID_ - // Heap pointer to frame buffers - sp m_heap_ptr; -#endif //_ANDROID_ - // to know whether Event Port Settings change has been triggered or not. - bool m_event_port_settings_sent; - OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE]; - extra_data_handler extra_data_handle; - -}; - -#endif // __OMX_VIDEO_BASE_H__ diff --git a/mm-video/vidc/venc/inc/omx_video_common.h b/mm-video/vidc/venc/inc/omx_video_common.h deleted file mode 100755 index dc4be1d3..00000000 --- a/mm-video/vidc/venc/inc/omx_video_common.h +++ /dev/null @@ -1,85 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#ifndef __OMX_VIDEO_COMMON_H__ -#define __OMX_VIDEO_COMMON_H__ -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// - -#include -#include -#ifdef USE_ION -#include -#endif - -#define OMX_VIDEO_DEC_NUM_INPUT_BUFFERS 2 -#define OMX_VIDEO_DEC_NUM_OUTPUT_BUFFERS 2 - -#ifdef FEATURE_QTV_WVGA_ENABLE -#define OMX_VIDEO_DEC_INPUT_BUFFER_SIZE (256*1024) -#else -#define OMX_VIDEO_DEC_INPUT_BUFFER_SIZE (128*1024) -#endif - -#define OMX_CORE_CONTROL_CMDQ_SIZE 100 -#define OMX_CORE_QCIF_HEIGHT 144 -#define OMX_CORE_QCIF_WIDTH 176 -#define OMX_CORE_VGA_HEIGHT 480 -#define OMX_CORE_VGA_WIDTH 640 -#define OMX_CORE_WVGA_HEIGHT 480 -#define OMX_CORE_WVGA_WIDTH 800 - -enum PortIndexType -{ - PORT_INDEX_IN = 0, - PORT_INDEX_OUT = 1, - PORT_INDEX_BOTH = -1, - PORT_INDEX_NONE = -2 -}; - -struct pmem -{ - void *buffer; - int fd; - unsigned offset; - unsigned size; -}; -#ifdef USE_ION -struct venc_ion -{ - int ion_device_fd; - struct ion_fd_data fd_ion_data; - struct ion_allocation_data ion_alloc_data; -}; -#endif -#endif // __OMX_VIDEO_COMMON_H__ - - - - diff --git a/mm-video/vidc/venc/inc/omx_video_encoder.h b/mm-video/vidc/venc/inc/omx_video_encoder.h deleted file mode 100644 index f59c4ab8..00000000 --- a/mm-video/vidc/venc/inc/omx_video_encoder.h +++ /dev/null @@ -1,89 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef __OMX_VENC__H -#define __OMX_VENC__H - -#include -#include "omx_video_base.h" -#ifdef _MSM8974_ -#include "video_encoder_device_v4l2.h" -#else -#include "video_encoder_device.h" -#endif - -extern "C" { - OMX_API void * get_omx_component_factory_fn(void); -} - -class omx_venc: public omx_video -{ -public: - omx_venc(); //constructor - ~omx_venc(); //des - static int async_message_process (void *context, void* message); - OMX_ERRORTYPE component_init(OMX_STRING role); - OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE paramIndex, - OMX_PTR paramData); - OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp, - OMX_INDEXTYPE configIndex, - OMX_PTR configData); - OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp); - //OMX strucutres - OMX_U32 m_nVenc_format; - class venc_dev *handle; -#ifdef _MSM8974_ - int dev_handle_extradata(void *, int); - int dev_set_format(int); -#endif -private: - OMX_U32 dev_stop(void); - OMX_U32 dev_pause(void); - OMX_U32 dev_start(void); - OMX_U32 dev_flush(unsigned); - OMX_U32 dev_resume(void); - OMX_U32 dev_start_done(void); - OMX_U32 dev_set_message_thread_id(pthread_t); - bool dev_use_buf( void *,unsigned,unsigned); - bool dev_free_buf( void *,unsigned); - bool dev_empty_buf(void *, void *,unsigned,unsigned); - bool dev_fill_buf(void *, void *,unsigned,unsigned); - bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32); - bool dev_set_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32); - bool update_profile_level(); - bool dev_get_seq_hdr(void *, unsigned, unsigned *); - bool dev_loaded_start(void); - bool dev_loaded_stop(void); - bool dev_loaded_start_done(void); - bool dev_loaded_stop_done(void); - bool dev_get_capability_ltrcount(OMX_U32 *, OMX_U32 *, OMX_U32 *); - bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height); -}; - -#endif //__OMX_VENC__H diff --git a/mm-video/vidc/venc/inc/queue.h b/mm-video/vidc/venc/inc/queue.h deleted file mode 100755 index 530b087d..00000000 --- a/mm-video/vidc/venc/inc/queue.h +++ /dev/null @@ -1,80 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef QUEUE_H -#define QUEUE_H - -#include -#include -#include -#include - -/* Message Queue structure */ -struct video_msgq -{ - /* Command to be executed */ - unsigned int cmd; - - unsigned int status; - - /* Client-specific data */ - void *clientdata; -}; - - -/* Thread & Message Queue information */ -struct video_queue_context -{ - /* Message Queue related members */ - pthread_mutex_t mutex; - sem_t sem_message; - int commandq_size; - int dataq_size; - struct video_msgq *ptr_dataq; - struct video_msgq *ptr_cmdq; - int write_dataq ; - int read_dataq; - int write_comq ; - int read_comq ; - -}; - -int check_if_queue_empty ( unsigned int queuetocheck,void* queuecontext ); - -struct video_msgq * queue_get_cmd ( void* queuecontext ); - - - -int queue_post_cmdq ( void *queuecontext, - struct video_msgq *post_msg - ); - -int queue_post_dataq ( void *queuecontext, - struct video_msgq *post_msg - ); - -#endif /* QUEUE_H */ diff --git a/mm-video/vidc/venc/inc/venc_util.h b/mm-video/vidc/venc/inc/venc_util.h deleted file mode 100755 index cfa590ca..00000000 --- a/mm-video/vidc/venc/inc/venc_util.h +++ /dev/null @@ -1,53 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -/*============================================================================ - V E N C _ U T I L. H - -DESCRIPTION - - -REFERENCES - - -============================================================================*/ - -#ifndef _VENC_UTIL_H -#define _VENC_UTIL_H - -#ifdef __cplusplus -extern "C" { -#endif - -long long GetTimeStamp(); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/mm-video/vidc/venc/inc/video_encoder_device.h b/mm-video/vidc/venc/inc/video_encoder_device.h deleted file mode 100644 index fb24c767..00000000 --- a/mm-video/vidc/venc/inc/video_encoder_device.h +++ /dev/null @@ -1,172 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef __OMX_VENC_DEV__ -#define __OMX_VENC_DEV__ - -#include "OMX_Types.h" -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "qc_omx_component.h" -#include "omx_video_common.h" -#include -#include -#include -#include -#define TIMEOUT 5000 -#define MAX_RECON_BUFFERS 4 - -void* async_venc_message_thread (void *); - -class venc_dev -{ -public: - venc_dev(class omx_venc *venc_class); //constructor - ~venc_dev(); //des - - bool venc_open(OMX_U32); - void venc_close(); - unsigned venc_stop(void); - unsigned venc_pause(void); - unsigned venc_start(void); - unsigned venc_flush(unsigned); -#ifdef _ANDROID_ICS_ - bool venc_set_meta_mode(bool); -#endif - unsigned venc_resume(void); - unsigned venc_start_done(void); - unsigned venc_set_message_thread_id(pthread_t); - bool venc_use_buf(void*, unsigned,unsigned); - bool venc_free_buf(void*, unsigned); - bool venc_empty_buf(void *, void *,unsigned,unsigned); - bool venc_fill_buf(void *, void *,unsigned,unsigned); - - bool venc_get_buf_req(unsigned long *,unsigned long *, - unsigned long *,unsigned long); - bool venc_set_buf_req(unsigned long *,unsigned long *, - unsigned long *,unsigned long); - bool venc_set_param(void *,OMX_INDEXTYPE); - bool venc_set_config(void *configData, OMX_INDEXTYPE index); - bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel); - bool venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate); - bool venc_get_seq_hdr(void *, unsigned, unsigned *); - bool venc_loaded_start(void); - bool venc_loaded_stop(void); - bool venc_loaded_start_done(void); - bool venc_loaded_stop_done(void); - bool venc_get_capability_ltrcount(OMX_U32 *, OMX_U32 *, OMX_U32 *); - OMX_U32 m_nDriver_fd; - bool m_profile_set; - bool m_level_set; - pthread_mutex_t loaded_start_stop_mlock; - pthread_cond_t loaded_start_stop_cond; - - struct recon_buffer { - unsigned char* virtual_address; - int pmem_fd; - int size; - int alignment; - int offset; -#ifdef USE_ION - int ion_device_fd; - struct ion_allocation_data alloc_data; - struct ion_fd_data ion_alloc_fd; -#endif - }; - - recon_buffer recon_buff[MAX_RECON_BUFFERS]; - int recon_buffers_count; - bool m_max_allowed_bitrate_check; - int m_eProfile; - int m_eLevel; - int etb_count; -private: - struct venc_basecfg m_sVenc_cfg; - struct venc_ratectrlcfg rate_ctrl; - struct venc_targetbitrate bitrate; - struct venc_intraperiod intra_period; - struct venc_profile codec_profile; - struct ven_profilelevel profile_level; - struct venc_switch set_param; - struct venc_voptimingcfg time_inc; - struct venc_allocatorproperty m_sInput_buff_property; - struct venc_allocatorproperty m_sOutput_buff_property; - struct venc_sessionqp session_qp; - struct venc_qprange qp_range; - struct venc_multiclicecfg multislice; - struct venc_entropycfg entropy; - struct venc_dbcfg dbkfilter; - struct venc_intrarefresh intra_refresh; - struct venc_headerextension hec; - struct venc_voptimingcfg voptimecfg; - struct venc_seqheader seqhdr; - struct venc_ltrmode ltrmode; - struct venc_ltrcount ltrcount; - struct venc_ltrperiod ltrperiod; - - bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel); - bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames); - bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config); - bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate); - bool venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp); - bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp); - bool venc_set_extradata(OMX_U32 extra_data); - bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config); - bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh); - bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format); - bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel); - bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize); - bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level); - bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter); - bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs); - bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience); - bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes); - void venc_config_print(); - bool venc_set_slice_delivery_mode(OMX_BOOL enable); - bool venc_set_plusptype(OMX_BOOL enable); - bool venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode); - bool venc_set_ltrcount(OMX_U32 count); - bool venc_set_ltrperiod(OMX_U32 period); - bool venc_set_ltruse(OMX_U32 id, OMX_U32 frames); -#ifdef MAX_RES_1080P - OMX_U32 pmem_free(); - OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); - OMX_U32 venc_allocate_recon_buffers(); - inline int clip2(int x) - { - x = x -1; - x = x | x >> 1; - x = x | x >> 2; - x = x | x >> 4; - x = x | x >> 16; - x = x + 1; - return x; - } -#endif -}; - -#endif diff --git a/mm-video/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video/vidc/venc/inc/video_encoder_device_v4l2.h deleted file mode 100644 index 78729b69..00000000 --- a/mm-video/vidc/venc/inc/video_encoder_device_v4l2.h +++ /dev/null @@ -1,344 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - * Neither the name of The Linux Foundation nor the names of its - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#ifndef __OMX_VENC_DEV__ -#define __OMX_VENC_DEV__ - -#include "OMX_Types.h" -#include "OMX_Core.h" -#include "OMX_QCOMExtns.h" -#include "qc_omx_component.h" -#include "omx_video_common.h" -#include "omx_video_base.h" -#include "omx_video_encoder.h" -#include -#include - -#define TIMEOUT 5*60*1000 - - -struct msm_venc_switch{ - unsigned char status; -}; - -struct msm_venc_allocatorproperty{ - unsigned long mincount; - unsigned long actualcount; - unsigned long datasize; - unsigned long suffixsize; - unsigned long alignment; - unsigned long bufpoolid; -}; - -struct msm_venc_basecfg{ - unsigned long input_width; - unsigned long input_height; - unsigned long dvs_width; - unsigned long dvs_height; - unsigned long codectype; - unsigned long fps_num; - unsigned long fps_den; - unsigned long targetbitrate; - unsigned long inputformat; -}; - -struct msm_venc_profile{ - unsigned long profile; -}; -struct msm_venc_profilelevel{ - unsigned long level; -}; - -struct msm_venc_sessionqp{ - unsigned long iframeqp; - unsigned long pframqp; - unsigned long bframqp; -}; - -struct msm_venc_qprange{ - unsigned long maxqp; - unsigned long minqp; -}; -struct msm_venc_intraperiod{ - unsigned long num_pframes; - unsigned long num_bframes; -}; -struct msm_venc_seqheader{ - unsigned char *hdrbufptr; - unsigned long bufsize; - unsigned long hdrlen; -}; - -struct msm_venc_capability{ - unsigned long codec_types; - unsigned long maxframe_width; - unsigned long maxframe_height; - unsigned long maxtarget_bitrate; - unsigned long maxframe_rate; - unsigned long input_formats; - unsigned char dvs; -}; - -struct msm_venc_entropycfg{ - unsigned longentropysel; - unsigned long cabacmodel; -}; - -struct msm_venc_dbcfg{ - unsigned long db_mode; - unsigned long slicealpha_offset; - unsigned long slicebeta_offset; -}; - -struct msm_venc_intrarefresh{ - unsigned long irmode; - unsigned long mbcount; -}; - -struct msm_venc_multiclicecfg{ - unsigned long mslice_mode; - unsigned long mslice_size; -}; - -struct msm_venc_bufferflush{ - unsigned long flush_mode; -}; - -struct msm_venc_ratectrlcfg{ - unsigned long rcmode; -}; - -struct msm_venc_voptimingcfg{ - unsigned long voptime_resolution; -}; -struct msm_venc_framerate{ - unsigned long fps_denominator; - unsigned long fps_numerator; -}; - -struct msm_venc_targetbitrate{ - unsigned long target_bitrate; -}; - - -struct msm_venc_rotation{ - unsigned long rotation; -}; - -struct msm_venc_timeout{ - unsigned long millisec; -}; - -struct msm_venc_headerextension{ - unsigned long header_extension; -}; - -struct msm_venc_video_capability { - unsigned int min_width; - unsigned int max_width; - unsigned int min_height; - unsigned int max_height; -}; - -struct msm_venc_idrperiod { - unsigned long idrperiod; -}; - -struct msm_venc_slice_delivery { - unsigned long enable; -}; - -enum v4l2_ports { - CAPTURE_PORT, - OUTPUT_PORT, - MAX_PORT -}; - -struct extradata_buffer_info { - int buffer_size; - char* uaddr; - int count; - int size; - int allocated; -#ifdef USE_ION - struct venc_ion ion; -#endif -}; - -class venc_dev -{ -public: - venc_dev(class omx_venc *venc_class); //constructor - ~venc_dev(); //des - - static void* async_venc_message_thread (void *); - bool venc_open(OMX_U32); - void venc_close(); - unsigned venc_stop(void); - unsigned venc_pause(void); - unsigned venc_start(void); - unsigned venc_flush(unsigned); -#ifdef _ANDROID_ICS_ - bool venc_set_meta_mode(bool); -#endif - unsigned venc_resume(void); - unsigned venc_start_done(void); - unsigned venc_stop_done(void); - unsigned venc_set_message_thread_id(pthread_t); - bool venc_use_buf(void*, unsigned,unsigned); - bool venc_free_buf(void*, unsigned); - bool venc_empty_buf(void *, void *,unsigned,unsigned); - bool venc_fill_buf(void *, void *,unsigned,unsigned); - - bool venc_get_buf_req(unsigned long *,unsigned long *, - unsigned long *,unsigned long); - bool venc_set_buf_req(unsigned long *,unsigned long *, - unsigned long *,unsigned long); - bool venc_set_param(void *,OMX_INDEXTYPE); - bool venc_set_config(void *configData, OMX_INDEXTYPE index); - bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel); - bool venc_get_seq_hdr(void *, unsigned, unsigned *); - bool venc_loaded_start(void); - bool venc_loaded_stop(void); - bool venc_loaded_start_done(void); - bool venc_loaded_stop_done(void); - bool venc_is_video_session_supported(unsigned long width, unsigned long height); - OMX_U32 m_nDriver_fd; - bool m_profile_set; - bool m_level_set; - int num_planes; - int etb, ebd, ftb, fbd; - struct recon_buffer { - unsigned char* virtual_address; - int pmem_fd; - int size; - int alignment; - int offset; -#ifdef USE_ION - int ion_device_fd; - struct ion_allocation_data alloc_data; - struct ion_fd_data ion_alloc_fd; -#endif - }; - - int stopped; - bool m_max_allowed_bitrate_check; - pthread_t m_tid; - bool async_thread_created; - class omx_venc *venc_handle; - OMX_ERRORTYPE allocate_extradata(); - void free_extradata(); - bool handle_extradata(void *, int); - int venc_set_format(int); -private: - struct msm_venc_basecfg m_sVenc_cfg; - struct msm_venc_ratectrlcfg rate_ctrl; - struct msm_venc_targetbitrate bitrate; - struct msm_venc_intraperiod intra_period; - struct msm_venc_profile codec_profile; - struct msm_venc_profilelevel profile_level; - struct msm_venc_switch set_param; - struct msm_venc_voptimingcfg time_inc; - struct msm_venc_allocatorproperty m_sInput_buff_property; - struct msm_venc_allocatorproperty m_sOutput_buff_property; - struct msm_venc_sessionqp session_qp; - struct msm_venc_multiclicecfg multislice; - struct msm_venc_entropycfg entropy; - struct msm_venc_dbcfg dbkfilter; - struct msm_venc_intrarefresh intra_refresh; - struct msm_venc_headerextension hec; - struct msm_venc_voptimingcfg voptimecfg; - struct msm_venc_video_capability capability; - struct msm_venc_idrperiod idrperiod; - struct msm_venc_slice_delivery slice_mode; - - bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel); - bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames); - bool venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config); - bool venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate); - bool venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp); - bool venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config); - bool venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh); - bool venc_set_color_format(OMX_COLOR_FORMATTYPE color_format); - bool venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel); - bool venc_set_multislice_cfg(OMX_INDEXTYPE codec, OMX_U32 slicesize); - bool venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level); - bool venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loop_filter); - bool venc_set_intra_refresh (OMX_VIDEO_INTRAREFRESHTYPE intrarefresh, OMX_U32 nMBs); - bool venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience); - bool venc_set_voptiming_cfg(OMX_U32 nTimeIncRes); - void venc_config_print(); - bool venc_set_slice_delivery_mode(OMX_U32 enable); - bool venc_set_extradata(OMX_U32 extra_data); - bool venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod); -#ifdef MAX_RES_1080P - OMX_U32 pmem_free(); - OMX_U32 pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count); - OMX_U32 venc_allocate_recon_buffers(); - inline int clip2(int x) - { - x = x -1; - x = x | x >> 1; - x = x | x >> 2; - x = x | x >> 4; - x = x | x >> 16; - x = x + 1; - return x; - } -#endif - int metadatamode; - bool streaming[MAX_PORT]; - bool extradata; - struct extradata_buffer_info extradata_info; - - pthread_mutex_t pause_resume_mlock; - pthread_cond_t pause_resume_cond; - bool paused; - int color_format; -}; - -enum instance_state { - MSM_VIDC_CORE_UNINIT_DONE = 0x0001, - MSM_VIDC_CORE_INIT, - MSM_VIDC_CORE_INIT_DONE, - MSM_VIDC_OPEN, - MSM_VIDC_OPEN_DONE, - MSM_VIDC_LOAD_RESOURCES, - MSM_VIDC_LOAD_RESOURCES_DONE, - MSM_VIDC_START, - MSM_VIDC_START_DONE, - MSM_VIDC_STOP, - MSM_VIDC_STOP_DONE, - MSM_VIDC_RELEASE_RESOURCES, - MSM_VIDC_RELEASE_RESOURCES_DONE, - MSM_VIDC_CLOSE, - MSM_VIDC_CLOSE_DONE, - MSM_VIDC_CORE_UNINIT, -}; -#endif - diff --git a/mm-video/vidc/venc/inc/video_encoder_test.h b/mm-video/vidc/venc/inc/video_encoder_test.h deleted file mode 100755 index bf1082a5..00000000 --- a/mm-video/vidc/venc/inc/video_encoder_test.h +++ /dev/null @@ -1,76 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include -#include -#include "queue.h" -#include -#include -#include -#include -#include -#include -#include - -#define INPUT_BUFFER 0 -#define OUTPUT_BUFFER 1 - -struct video_encoder_context -{ - unsigned long input_width; - unsigned long input_height; - unsigned long codectype; - unsigned long fps_num; - unsigned long fps_den; - unsigned long targetbitrate; - unsigned long inputformat; - - struct venc_allocatorproperty input_buffer; - struct venc_allocatorproperty output_buffer; - struct venc_bufferpayload **ptr_inputbuffer; - struct venc_bufferpayload **ptr_outputbuffer; - struct video_queue_context queue_context; - int video_driver_fd; - - FILE * inputBufferFile; - FILE * outputBufferFile; - - pthread_t videothread_id; - pthread_t asyncthread_id; - sem_t sem_synchronize; -}; - -int init_encoder ( struct video_encoder_context *init_decode ); -int allocate_buffer ( unsigned int buffer_dir, - struct video_encoder_context *decode_context - ); -int free_buffer ( unsigned int buffer_dir, - struct video_encoder_context *decode_context - ); -int start_encoding (struct video_encoder_context *decode_context); -int stop_encoding (struct video_encoder_context *decode_context); -int deinit_encoder (struct video_encoder_context *init_decode); diff --git a/mm-video/vidc/venc/src/omx_video_base.cpp b/mm-video/vidc/venc/src/omx_video_base.cpp deleted file mode 100644 index b0e14038..00000000 --- a/mm-video/vidc/venc/src/omx_video_base.cpp +++ /dev/null @@ -1,4983 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -/*============================================================================ - O p e n M A X w r a p p e r s - O p e n M A X C o r e - -*//** @file omx_video_base.cpp - This module contains the implementation of the OpenMAX core & component. - -*//*========================================================================*/ - -////////////////////////////////////////////////////////////////////////////// -// Include Files -////////////////////////////////////////////////////////////////////////////// - -#include -#include "omx_video_base.h" -#include -#include -#include -#include -#include -#ifdef _ANDROID_ICS_ -#include -#include -#endif -#ifndef _ANDROID_ -#include -#define strlcpy g_strlcpy -#endif -#define H264_SUPPORTED_WIDTH (480) -#define H264_SUPPORTED_HEIGHT (368) - -#define MPEG4_SUPPORTED_WIDTH (480) -#define MPEG4_SUPPORTED_HEIGHT (368) - -#define VC1_SP_MP_START_CODE 0xC5000000 -#define VC1_SP_MP_START_CODE_MASK 0xFF000000 -#define VC1_AP_START_CODE 0x00000100 -#define VC1_AP_START_CODE_MASK 0xFFFFFF00 -#define VC1_STRUCT_C_PROFILE_MASK 0xF0 -#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 -#define VC1_SIMPLE_PROFILE 0 -#define VC1_MAIN_PROFILE 1 -#define VC1_ADVANCE_PROFILE 3 -#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 -#define VC1_SIMPLE_PROFILE_MED_LEVEL 2 -#define VC1_STRUCT_C_LEN 4 -#define VC1_STRUCT_C_POS 8 -#define VC1_STRUCT_A_POS 12 -#define VC1_STRUCT_B_POS 24 -#define VC1_SEQ_LAYER_SIZE 36 - -typedef struct OMXComponentCapabilityFlagsType -{ - ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS - OMX_BOOL iIsOMXComponentMultiThreaded; - OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; - OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; - OMX_BOOL iOMXComponentSupportsMovableInputBuffers; - OMX_BOOL iOMXComponentSupportsPartialFrames; - OMX_BOOL iOMXComponentUsesNALStartCodes; - OMX_BOOL iOMXComponentCanHandleIncompleteFrames; - OMX_BOOL iOMXComponentUsesFullAVCFrames; - -} OMXComponentCapabilityFlagsType; -#define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347 -#ifdef OUTPUT_BUFFER_LOG -extern FILE *outputBufferFile1; -#endif - -void* message_thread(void *input) -{ - omx_video* omx = reinterpret_cast(input); - unsigned char id; - int n; - - DEBUG_PRINT_LOW("omx_venc: message thread start\n"); - prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0); - while(1) - { - n = read(omx->m_pipe_in, &id, 1); - if(0 == n) - { - break; - } - - if(1 == n) - { - omx->process_event_cb(omx, id); - } -#ifdef QLE_BUILD - if(n < 0) break; -#else - if((n < 0) && (errno != EINTR)) break; -#endif - } - DEBUG_PRINT_LOW("omx_venc: message thread stop\n"); - return 0; -} - -void post_message(omx_video *omx, unsigned char id) -{ - DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id); - write(omx->m_pipe_out, &id, 1); -} - -// omx_cmd_queue destructor -omx_video::omx_cmd_queue::~omx_cmd_queue() -{ - // Nothing to do -} - -// omx cmd queue constructor -omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) -{ - memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); -} - -// omx cmd queue insert -bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) -{ - bool ret = true; - if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_q[m_write].id = id; - m_q[m_write].param1 = p1; - m_q[m_write].param2 = p2; - m_write++; - m_size ++; - if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_write = 0; - } - } - else - { - ret = false; - DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n"); - } - return ret; -} - -// omx cmd queue pop -bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) -{ - bool ret = true; - if(m_size > 0) - { - *id = m_q[m_read].id; - *p1 = m_q[m_read].param1; - *p2 = m_q[m_read].param2; - // Move the read pointer ahead - ++m_read; - --m_size; - if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) - { - m_read = 0; - } - } - else - { - ret = false; - } - return ret; -} - -// Retrieve the first mesg type in the queue -unsigned omx_video::omx_cmd_queue::get_q_msg_type() -{ - return m_q[m_read].id; -} - - - -#ifdef _ANDROID_ -VideoHeap::VideoHeap(int fd, size_t size, void* base) -{ - // dup file descriptor, map once, use pmem - init(dup(fd), base, size, 0 , MEM_DEVICE); -} -#endif // _ANDROID_ - -/* ====================================================================== -FUNCTION - omx_venc::omx_venc - -DESCRIPTION - Constructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_video::omx_video(): - m_pInput_pmem(NULL), - m_pOutput_pmem(NULL), -#ifdef USE_ION - m_pInput_ion(NULL), - m_pOutput_ion(NULL), -#endif - m_error_propogated(false), - m_state(OMX_StateInvalid), - m_app_data(NULL), - m_use_input_pmem(OMX_FALSE), - m_use_output_pmem(OMX_FALSE), - m_inp_mem_ptr(NULL), - m_out_mem_ptr(NULL), - input_flush_progress (false), - output_flush_progress (false), - input_use_buffer (false), - output_use_buffer (false), - pending_input_buffers(0), - pending_output_buffers(0), - m_out_bm_count(0), - m_inp_bm_count(0), - m_flags(0), - m_etb_count(0), - m_fbd_count(0), - m_event_port_settings_sent(false), - m_input_msg_id(OMX_COMPONENT_GENERATE_ETB), - psource_frame(NULL), - pdest_frame(NULL), - c2d_opened(false) -{ - DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()"); - memset(&m_cmp,0,sizeof(m_cmp)); - memset(&m_pCallbacks,0,sizeof(m_pCallbacks)); - async_thread_created = false; - msg_thread_created = false; - - pthread_mutex_init(&m_lock, NULL); - sem_init(&m_cmd_lock,0,0); -} - - -/* ====================================================================== -FUNCTION - omx_venc::~omx_venc - -DESCRIPTION - Destructor - -PARAMETERS - None - -RETURN VALUE - None. -========================================================================== */ -omx_video::~omx_video() -{ - DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()"); - if(m_pipe_in) close(m_pipe_in); - if(m_pipe_out) close(m_pipe_out); - DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n"); - if (msg_thread_created) - pthread_join(msg_thread_id,NULL); - DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n"); - /*For V4L2 based drivers, pthread_join is done in device_close - * so no need to do it here*/ -#ifndef _MSM8974_ - if (async_thread_created) - pthread_join(async_thread_id,NULL); -#endif - pthread_mutex_destroy(&m_lock); - sem_destroy(&m_cmd_lock); - DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count, - m_fbd_count); - DEBUG_PRINT_HIGH("omx_video: Destructor exit\n"); - DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n"); -} - -/* ====================================================================== -FUNCTION - omx_venc::OMXCntrlProcessMsgCb - -DESCRIPTION - IL Client callbacks are generated through this routine. The decoder - provides the thread context for this routine. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -void omx_video::process_event_cb(void *ctxt, unsigned char id) -{ - unsigned p1; // Parameter - 1 - unsigned p2; // Parameter - 2 - unsigned ident; - unsigned qsize=0; // qsize - omx_video *pThis = (omx_video *) ctxt; - - if(!pThis) - { - DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n"); - return; - } - - // Protect the shared queue data structure - do - { - /*Read the message id's from the queue*/ - - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size; - if(qsize) - { - pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); - } - - if(qsize == 0) - { - qsize = pThis->m_ftb_q.m_size; - if(qsize) - { - pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); - } - } - - if(qsize == 0) - { - qsize = pThis->m_etb_q.m_size; - if(qsize) - { - pThis->m_etb_q.pop_entry(&p1,&p2,&ident); - } - } - - pthread_mutex_unlock(&pThis->m_lock); - - /*process message if we have one*/ - if(qsize > 0) - { - id = ident; - switch(id) - { - case OMX_COMPONENT_GENERATE_EVENT: - if(pThis->m_pCallbacks.EventHandler) - { - switch(p1) - { - case OMX_CommandStateSet: - pThis->m_state = (OMX_STATETYPE) p2; - DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state); - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL); - break; - - case OMX_EventError: - DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2); - if(p2 == OMX_ErrorHardware) - { - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError,OMX_ErrorHardware,0,NULL); - } - else - { - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventError, p2, NULL, NULL ); - - } - break; - - case OMX_CommandPortDisable: - DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \ - "state \n", p2); - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - case OMX_CommandPortEnable: - DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \ - , p2); - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - default: - DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1); - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete, p1, p2, NULL ); - break; - - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n"); - } - break; - case OMX_COMPONENT_GENERATE_ETB_OPQ: - DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n"); - if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); - pThis->omx_report_error (); - } - break; - case OMX_COMPONENT_GENERATE_ETB: - DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n"); - if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FTB: - if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ - (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_COMMAND: - pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ - (OMX_U32)p2,(OMX_PTR)NULL); - break; - - case OMX_COMPONENT_GENERATE_EBD: - if( pThis->empty_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FBD: - if( pThis->fill_buffer_done(&pThis->m_cmp, - (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); - pThis->omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: - - pThis->input_flush_progress = false; - DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count); - m_etb_count = 0; - if(pThis->m_pCallbacks.EventHandler) - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_INPUT_FLUSH_PENDING)) - { - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - PORT_INDEX_IN,NULL ); - } - else if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_IDLE_PENDING)) - { - if(!pThis->output_flush_progress) - { - DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n"); - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n"); - pThis->omx_report_error (); - } - } - } - } - - break; - - case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: - - pThis->output_flush_progress = false; - DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count); - m_fbd_count = 0; - if(pThis->m_pCallbacks.EventHandler) - { - /*Check if we need generate event for Flush done*/ - if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) - { - BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandFlush, - PORT_INDEX_OUT,NULL ); - } - else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n"); - if(!pThis->input_flush_progress) - { - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n"); - pThis->omx_report_error (); - } - } - } - } - break; - - case OMX_COMPONENT_GENERATE_START_DONE: - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg"); - - if(pThis->m_pCallbacks.EventHandler) - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \ - executing"); - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting, NULL); - } - else if(BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_PAUSE_PENDING)) - { - if(dev_pause()) - { - DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n"); - pThis->omx_report_error (); - } - } - else if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_LOADED_START_PENDING)) - { - if(dev_loaded_start_done()) - { - DEBUG_PRINT_LOW("successful loaded Start Done!"); - } - else - { - DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!"); - pThis->omx_report_error (); - } - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING); - } - else - { - DEBUG_PRINT_LOW("\nERROR: unknown flags=%x\n",pThis->m_flags); - } - } - else - { - DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); - } - break; - - case OMX_COMPONENT_GENERATE_PAUSE_DONE: - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg"); - if(pThis->m_pCallbacks.EventHandler) - { - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) - { - //Send the callback now - pThis->complete_pending_buffer_done_cbs(); - DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n"); - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); - pThis->m_state = OMX_StatePause; - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StatePause, NULL); - } - } - - break; - - case OMX_COMPONENT_GENERATE_RESUME_DONE: - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg"); - if(pThis->m_pCallbacks.EventHandler) - { - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); - pThis->m_state = OMX_StateExecuting; - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateExecuting,NULL); - } - } - - break; - - case OMX_COMPONENT_GENERATE_STOP_DONE: - DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg"); - if(pThis->m_pCallbacks.EventHandler) - { - pThis->complete_pending_buffer_done_cbs(); - if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); - pThis->m_state = OMX_StateIdle; - pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data, - OMX_EventCmdComplete,OMX_CommandStateSet, - OMX_StateIdle,NULL); - } - else if (BITMASK_PRESENT(&pThis->m_flags, - OMX_COMPONENT_LOADED_STOP_PENDING)) - { - if(dev_loaded_stop_done()) - { - DEBUG_PRINT_LOW("successful loaded Stop Done!"); - } - else - { - DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!"); - pThis->omx_report_error (); - } - BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING); - } - else - { - DEBUG_PRINT_LOW("\nERROR: unknown flags=%x\n",pThis->m_flags); - } - } - - break; - - case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: - DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n"); - pThis->omx_report_error (); - break; -#ifndef _MSM8974_ - case OMX_COMPONENT_GENERATE_LTRUSE_FAILED: - DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_LTRUSE_FAILED!"); - if(pThis->m_pCallbacks.EventHandler) - { - DEBUG_PRINT_ERROR("Sending QOMX_ErrorLTRUseFailed, p2 = 0x%x", p2); - pThis->m_pCallbacks.EventHandler( - &pThis->m_cmp, pThis->m_app_data, - OMX_EventError, QOMX_ErrorLTRUseFailed, NULL, NULL); - } - break; -#endif - default: - DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id); - break; - } - } - - pthread_mutex_lock(&pThis->m_lock); - qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ - pThis->m_etb_q.m_size; - - pthread_mutex_unlock(&pThis->m_lock); - - } - while(qsize>0); - DEBUG_PRINT_LOW("\n exited the while loop\n"); - -} - - - - -/* ====================================================================== -FUNCTION - omx_venc::GetComponentVersion - -DESCRIPTION - Returns the component version. - -PARAMETERS - TBD. - -RETURN VALUE - OMX_ErrorNone. - -========================================================================== */ -OMX_ERRORTYPE omx_video::get_component_version -( -OMX_IN OMX_HANDLETYPE hComp, -OMX_OUT OMX_STRING componentName, -OMX_OUT OMX_VERSIONTYPE* componentVersion, -OMX_OUT OMX_VERSIONTYPE* specVersion, -OMX_OUT OMX_UUIDTYPE* componentUUID -) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n"); - return OMX_ErrorInvalidState; - } - /* TBD -- Return the proper version */ - if (specVersion) - { - specVersion->nVersion = OMX_SPEC_VERSION; - } - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_venc::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) - { - if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH)) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n"); - return OMX_ErrorBadPortIndex; - } - } - if(cmd == OMX_CommandMarkBuffer) - { - if(param1 != PORT_INDEX_IN) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n"); - return OMX_ErrorBadPortIndex; - } - if(!cmdData) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null"); - return OMX_ErrorBadParameter; - } - } - - post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); - sem_wait(&m_cmd_lock); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_venc::SendCommand - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_COMMANDTYPE cmd, - OMX_IN OMX_U32 param1, - OMX_IN OMX_PTR cmdData - ) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_STATETYPE eState = (OMX_STATETYPE) param1; - int bFlag = 1; - - if(cmd == OMX_CommandStateSet) - { - /***************************/ - /* Current State is Loaded */ - /***************************/ - if(m_state == OMX_StateLoaded) - { - if(eState == OMX_StateIdle) - { - //if all buffers are allocated or all ports disabled - if(allocate_done() || - ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) - { - DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n"); - } - else - { - DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Loaded to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Loaded to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n"); - } - /* Requesting transition from Loaded to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Loaded to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\ - eState); - eRet = OMX_ErrorBadParameter; - } - } - - /***************************/ - /* Current State is IDLE */ - /***************************/ - else if(m_state == OMX_StateIdle) - { - if(eState == OMX_StateLoaded) - { - if(release_done()) - { - /* - Since error is None , we will post an event at the end - of this function definition - */ - DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n"); - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded"); - eRet = OMX_ErrorHardware; - } - } - else - { - DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); - // Skip the event notification - bFlag = 0; - } - } - /* Requesting transition from Idle to Executing */ - else if(eState == OMX_StateExecuting) - { - if( dev_start() ) - { - DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); - DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); - bFlag = 0; - } - - dev_start_done(); - } - /* Requesting transition from Idle to Idle */ - else if(eState == OMX_StateIdle) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Idle to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Idle to Pause */ - else if(eState == OMX_StatePause) - { - /*To pause the Video core we need to start the driver*/ - if( dev_start() ) - { - DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n"); - omx_report_error (); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); - DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n"); - bFlag = 0; - } - } - /* Requesting transition from Idle to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - - /******************************/ - /* Current State is Executing */ - /******************************/ - else if(m_state == OMX_StateExecuting) - { - /* Requesting transition from Executing to Idle */ - if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition - */ - DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n"); - //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - execute_omx_flush(OMX_ALL); - bFlag = 0; - } - /* Requesting transition from Executing to Paused */ - else if(eState == OMX_StatePause) - { - - if(dev_pause()) - { - DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n"); - post_event(OMX_EventError,OMX_ErrorHardware,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); - DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n"); - bFlag = 0; - } - } - /* Requesting transition from Executing to Loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Executing to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Executing to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is Pause */ - /***************************/ - else if(m_state == OMX_StatePause) - { - /* Requesting transition from Pause to Executing */ - if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_LOW("\n Pause --> Executing \n"); - if( dev_resume() ) - { - post_event(OMX_EventError,OMX_ErrorHardware,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorHardware; - } - else - { - BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); - DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n"); - post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE); - bFlag = 0; - } - } - /* Requesting transition from Pause to Idle */ - else if(eState == OMX_StateIdle) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("\n Pause --> Idle \n"); - BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); - execute_omx_flush(OMX_ALL); - bFlag = 0; - } - /* Requesting transition from Pause to loaded */ - else if(eState == OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from Pause to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n"); - post_event(OMX_EventError,OMX_ErrorSameState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from Pause to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState); - eRet = OMX_ErrorBadParameter; - } - } - /***************************/ - /* Current State is WaitForResources */ - /***************************/ - else if(m_state == OMX_StateWaitForResources) - { - /* Requesting transition from WaitForResources to Loaded */ - if(eState == OMX_StateLoaded) - { - /* Since error is None , we will post an event - at the end of this function definition */ - DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n"); - } - /* Requesting transition from WaitForResources to WaitForResources */ - else if(eState == OMX_StateWaitForResources) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n"); - post_event(OMX_EventError,OMX_ErrorSameState, - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorSameState; - } - /* Requesting transition from WaitForResources to Executing */ - else if(eState == OMX_StateExecuting) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Pause */ - else if(eState == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n"); - post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorIncorrectStateTransition; - } - /* Requesting transition from WaitForResources to Invalid */ - else if(eState == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n"); - post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - /* Requesting transition from WaitForResources to Loaded - - is NOT tested by Khronos TS */ - - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState); - eRet = OMX_ErrorBadParameter; - } - } - /********************************/ - /* Current State is Invalid */ - /*******************************/ - else if(m_state == OMX_StateInvalid) - { - /* State Transition from Inavlid to any state */ - if(eState == (OMX_StateLoaded || OMX_StateWaitForResources - || OMX_StateIdle || OMX_StateExecuting - || OMX_StatePause || OMX_StateInvalid)) - { - DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n"); - post_event(OMX_EventError,OMX_ErrorInvalidState,\ - OMX_COMPONENT_GENERATE_EVENT); - eRet = OMX_ErrorInvalidState; - } - } - else if(cmd == OMX_CommandFlush) - { - if(0 == param1 || OMX_ALL == param1) - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); - } - if(1 == param1 || OMX_ALL == param1) - { - //generate output flush event only. - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); - } - - execute_omx_flush(param1); - bFlag = 0; - } - else if( cmd == OMX_CommandPortEnable) - { - if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) - { - m_sInPortDef.bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || allocate_input_done()) - { - post_event(OMX_CommandPortEnable,PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) - { - m_sOutPortDef.bEnabled = OMX_TRUE; - - if( (m_state == OMX_StateLoaded && - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - || (allocate_output_done())) - { - post_event(OMX_CommandPortEnable,PORT_INDEX_OUT, - OMX_COMPONENT_GENERATE_EVENT); - - } - else - { - DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - // Skip the event notification - bFlag = 0; - } - } - } - else if(cmd == OMX_CommandPortDisable) - { - if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) - { - m_sInPortDef.bEnabled = OMX_FALSE; - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_input_done()) - { - post_event(OMX_CommandPortDisable,PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - execute_omx_flush(PORT_INDEX_IN); - } - - // Skip the event notification - bFlag = 0; - } - } - if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) - { - m_sOutPortDef.bEnabled = OMX_FALSE; - - if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) - && release_output_done()) - { - post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\ - OMX_COMPONENT_GENERATE_EVENT); - } - else - { - BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); - if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) - { - execute_omx_flush(PORT_INDEX_OUT); - } - // Skip the event notification - bFlag = 0; - - } - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd); - eRet = OMX_ErrorNotImplemented; - } - if(eRet == OMX_ErrorNone && bFlag) - { - post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); - } - sem_post(&m_cmd_lock); - return eRet; -} - -/* ====================================================================== -FUNCTION - omx_venc::ExecuteOmxFlush - -DESCRIPTION - Executes the OMX flush. - -PARAMETERS - flushtype - input flush(1)/output flush(0)/ both. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_video::execute_omx_flush(OMX_U32 flushType) -{ - bool bRet = false; - DEBUG_PRINT_LOW("\n execute_omx_flush - %d\n", flushType); -#ifdef _MSM8974_ - /* XXX: The driver/hardware does not support flushing of individual ports - * in all states. So we pretty much need to flush both ports internally, - * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it - * requested. Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set, - * we automatically omit sending the FLUSH done for the "opposite" port. */ - - input_flush_progress = true; - output_flush_progress = true; - bRet = execute_flush_all(); -#else - if(flushType == 0 || flushType == OMX_ALL) - { - input_flush_progress = true; - //flush input only - bRet = execute_input_flush(); - } - if(flushType == 1 || flushType == OMX_ALL) - { - //flush output only - output_flush_progress = true; - bRet = execute_output_flush(); - } -#endif - return bRet; -} -/*========================================================================= -FUNCTION : execute_output_flush - -DESCRIPTION - Executes the OMX flush at OUTPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_video::execute_output_flush(void) -{ - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate FBD for all Buffers in the FTBq*/ - DEBUG_PRINT_LOW("\n execute_output_flush\n"); - pthread_mutex_lock(&m_lock); - while(m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - - if(ident == OMX_COMPONENT_GENERATE_FTB ) - { - pending_output_buffers++; - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_FBD) - { - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - - pthread_mutex_unlock(&m_lock); - /*Check if there are buffers with the Driver*/ - if(dev_flush(PORT_INDEX_OUT)) - { - DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed"); - return false; - } - - return bRet; -} -/*========================================================================= -FUNCTION : execute_input_flush - -DESCRIPTION - Executes the OMX flush at INPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -bool omx_video::execute_input_flush(void) -{ - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - /*Generate EBD for all Buffers in the ETBq*/ - DEBUG_PRINT_LOW("\n execute_input_flush\n"); - - pthread_mutex_lock(&m_lock); - while(m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_ETB) - { - pending_input_buffers++; - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_EBD) - { - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) - { - m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2); - } - } - if(mUseProxyColorFormat) { - if(psource_frame) { - m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame); - psource_frame = NULL; - } - while(m_opq_meta_q.m_size) { - unsigned p1,p2,id; - m_opq_meta_q.pop_entry(&p1,&p2,&id); - m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data, - (OMX_BUFFERHEADERTYPE *)p1); - } - if(pdest_frame){ - m_opq_pmem_q.insert_entry((unsigned int)pdest_frame,0,0); - pdest_frame = NULL; - } - } - pthread_mutex_unlock(&m_lock); - /*Check if there are buffers with the Driver*/ - if(dev_flush(PORT_INDEX_IN)) - { - DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed"); - return false; - } - - return bRet; -} - - -/*========================================================================= -FUNCTION : execute_flush - -DESCRIPTION - Executes the OMX flush at INPUT & OUTPUT PORT. - -PARAMETERS - None. - -RETURN VALUE - true/false -==========================================================================*/ -#ifdef _MSM8974_ -bool omx_video::execute_flush_all(void) -{ - unsigned p1 = 0; // Parameter - 1 - unsigned p2 = 0; // Parameter - 2 - unsigned ident = 0; - bool bRet = true; - - DEBUG_PRINT_LOW("\n execute_flush_all\n"); - - /*Generate EBD for all Buffers in the ETBq*/ - pthread_mutex_lock(&m_lock); - while(m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_ETB) - { - pending_input_buffers++; - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_EBD) - { - empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - - /*Generate FBD for all Buffers in the FTBq*/ - DEBUG_PRINT_LOW("\n execute_output_flush\n"); - while(m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - - if(ident == OMX_COMPONENT_GENERATE_FTB ) - { - pending_output_buffers++; - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); - } - else if(ident == OMX_COMPONENT_GENERATE_FBD) - { - fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); - } - } - - pthread_mutex_unlock(&m_lock); - - /*Check if there are buffers with the Driver*/ - if(dev_flush(PORT_INDEX_BOTH)) - { - DEBUG_PRINT_ERROR("\nERROR: dev_flush() Failed"); - return false; - } - return bRet; -} - -#endif - -/* ====================================================================== -FUNCTION - omx_venc::SendCommandEvent - -DESCRIPTION - Send the event to decoder pipe. This is needed to generate the callbacks - in decoder thread context. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -bool omx_video::post_event(unsigned int p1, - unsigned int p2, - unsigned int id) -{ - bool bRet = false; - - - pthread_mutex_lock(&m_lock); - - if ((id == OMX_COMPONENT_GENERATE_FTB) || - (id == OMX_COMPONENT_GENERATE_FBD) || - (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH)) - { - m_ftb_q.insert_entry(p1,p2,id); - } - else if ((id == OMX_COMPONENT_GENERATE_ETB) || - (id == OMX_COMPONENT_GENERATE_EBD) || - (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH)) - { - m_etb_q.insert_entry(p1,p2,id); - } - else - { - m_cmd_q.insert_entry(p1,p2,id); - } - - bRet = true; - DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); - post_message(this, id); - pthread_mutex_unlock(&m_lock); - - return bRet; -} - -/* ====================================================================== -FUNCTION - omx_venc::GetParameter - -DESCRIPTION - OMX Get Parameter method implementation - -PARAMETERS - . - -RETURN VALUE - Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_INOUT OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int height=0,width = 0; - - DEBUG_PRINT_LOW("get_parameter: \n"); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - switch(paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); - if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) - { - DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d", - m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin, - m_sInPortDef.nBufferCountActual); - memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); -#ifdef _ANDROID_ICS_ - if(meta_mode_enable) - { - portDefn->nBufferSize = sizeof(encoder_media_buffer_type); - } - if (mUseProxyColorFormat) { - portDefn->format.video.eColorFormat = - (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; - } -#endif - } - else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d", - m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin, - m_sOutPortDef.nBufferCountActual); - memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); - } - else - { - DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - case OMX_IndexParamVideoInit: - { - OMX_PORT_PARAM_TYPE *portParamType = - (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); - - memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam)); - break; - } - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); - - if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) - { - int index = portFmt->nIndex; - if(index > 1) - eRet = OMX_ErrorNoMore; - else { - memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); -#ifdef _ANDROID_ICS_ - if (index == 1) { - //we support two formats - //index 0 - YUV420SP - //index 1 - opaque which internally maps to YUV420SP. - //this can be extended in the future - portFmt->nIndex = index; //restore index set from client - portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; - } -#endif - } - } - else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat)); - } - else - { - DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - case OMX_IndexParamVideoBitrate: - { - OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n"); - - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate)); - } - else - { - DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); - eRet = OMX_ErrorBadPortIndex; - } - - break; - } - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n"); - memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); - break; - } - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n"); - memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); - break; - } - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n"); - memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); - break; - } - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n"); - eRet = get_supported_profile_level(pParam); - if(eRet) - DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %lu, %lu", - pParam->eProfile, pParam->eLevel); - break; - } - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n"); - memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamAudioInit: - { - OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); - memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); - break; - } - /*Component should support this port definition*/ - case OMX_IndexParamImageInit: - { - OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); - memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img)); - break; - - } - /*Component should support this port definition*/ - case OMX_IndexParamOtherInit: - { - DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - break; - } - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - comp_role->nVersion.nVersion = OMX_SPEC_VERSION; - comp_role->nSize = sizeof(*comp_role); - - DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex); - if(NULL != comp_role->cRole) - { - strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex); - eRet =OMX_ErrorBadParameter; - } - break; - } - /* Added for parameter test */ - case OMX_IndexParamPriorityMgmt: - { - - OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); - memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); - break; - } - /* Added for parameter test */ - case OMX_IndexParamCompBufferSupplier: - { - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); - if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) - { - memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier)); - } - else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) - { - memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier)); - } - else - { - DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - - case OMX_IndexParamVideoQuantization: - { - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n"); - memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); - break; - } - - case OMX_QcomIndexParamVideoQPRange: - { - OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; - DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange\n"); - memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange)); - break; - } - - case OMX_IndexParamVideoErrorCorrection: - { - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; - DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); - errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC; - errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync; - errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing; - break; - } - case OMX_IndexParamVideoIntraRefresh: - { - OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; - DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n"); - DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n"); - intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode; - intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs; - break; - } - case OMX_QcomIndexPortDefn: - //TODO - break; - case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: - { - OMXComponentCapabilityFlagsType *pParam = reinterpret_cast(paramData); - DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n"); - pParam->iIsOMXComponentMultiThreaded = OMX_TRUE; - pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE; - pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; - pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE; - pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE; - pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE; - pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE; - pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE; - m_use_input_pmem = OMX_TRUE; - DEBUG_PRINT_LOW("Supporting capability index in encoder node"); - break; - } -#if !defined(MAX_RES_720P) || defined(_MSM8974_) - case OMX_QcomIndexParamIndexExtraDataType: - { - DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType"); - QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; - if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) - { - if (pParam->nPortIndex == PORT_INDEX_OUT) - { - pParam->bEnabled = - (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0); - DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled); - } - else - { - DEBUG_PRINT_ERROR("get_parameter: slice information is " - "valid for output port only"); - eRet =OMX_ErrorUnsupportedIndex; - } - } -#ifndef _MSM8974_ - else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) - { - if (pParam->nPortIndex == PORT_INDEX_OUT) - { - pParam->bEnabled = - (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_LTRINFO) ? 1 : 0); - DEBUG_PRINT_HIGH("LTR Info extradata %d", pParam->bEnabled); - } - else - { - DEBUG_PRINT_ERROR("get_parameter: LTR information is " - "valid for output port only"); - eRet = OMX_ErrorUnsupportedIndex; - } - } -#endif - else - { - DEBUG_PRINT_ERROR("get_parameter: unsupported extradata index (0x%x)", - pParam->nIndex); - eRet = OMX_ErrorUnsupportedIndex; - } - break; - } - case QOMX_IndexParamVideoLTRCountRangeSupported: - { - DEBUG_PRINT_HIGH("get_parameter: QOMX_IndexParamVideoLTRCountRangeSupported"); - QOMX_EXTNINDEX_RANGETYPE *pParam = (QOMX_EXTNINDEX_RANGETYPE *)paramData; - if (pParam->nPortIndex == PORT_INDEX_OUT) - { - OMX_U32 min = 0, max = 0, step_size = 0; - if (dev_get_capability_ltrcount(&min, &max, &step_size)) - { - pParam->nMin = min; - pParam->nMax = max; - pParam->nStepSize = step_size; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: get_capability_ltrcount failed"); - eRet = OMX_ErrorUndefined; - } - } - else - { - DEBUG_PRINT_ERROR("LTR count range is valid for output port only"); - eRet = OMX_ErrorUnsupportedIndex; - } - } - break; -#endif - case QOMX_IndexParamVideoSyntaxHdr: - { - DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr"); - QOMX_EXTNINDEX_PARAMTYPE* pParam = - reinterpret_cast(paramData); - if (pParam->pData == NULL) - { - DEBUG_PRINT_ERROR("Error: Data buffer is NULL"); - eRet = OMX_ErrorBadParameter; - break; - } - if (get_syntaxhdr_enable == false) - { - DEBUG_PRINT_ERROR("ERROR: get_parameter: Get syntax header disabled"); - eRet = OMX_ErrorUnsupportedIndex; - break; - } - BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); - if(dev_loaded_start()) - { - DEBUG_PRINT_LOW("device start successful"); - } - else - { - DEBUG_PRINT_ERROR("device start failed"); - BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); - return OMX_ErrorHardware; - } - if(dev_get_seq_hdr(pParam->pData, - (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)), - (unsigned *)&pParam->nDataSize)) - { - DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %lu)", - pParam->nDataSize); - for (unsigned i = 0; i < pParam->nDataSize; i++) { - DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i)); - } - } - else - { - DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()"); - eRet = OMX_ErrorHardware; - } - BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); - if(dev_loaded_stop()) - { - DEBUG_PRINT_LOW("device stop successful"); - } - else - { - DEBUG_PRINT_ERROR("device stop failed"); - BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); - eRet = OMX_ErrorHardware; - } - break; - } - case OMX_IndexParamVideoSliceFMO: - default: - { - DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x\n", paramIndex); - eRet =OMX_ErrorUnsupportedIndex; - break; - } - - } - - return eRet; - -} -/* ====================================================================== -FUNCTION - omx_video::GetConfig - -DESCRIPTION - OMX Get Config Method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_INOUT OMX_PTR configData) -{ - //////////////////////////////////////////////////////////////// - // Supported Config Index Type - // ============================================================= - // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE - // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE - // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE - //////////////////////////////////////////////////////////////// - - if(configData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: param is null"); - return OMX_ErrorBadParameter; - } - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); - return OMX_ErrorIncorrectStateOperation; - } - - //@todo need to validate params - switch(configIndex) - { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); - break; - } - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); - break; - } - case OMX_IndexConfigCommonRotate: - { - OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); - break; - } - case QOMX_IndexConfigVideoIntraperiod: - { - DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n"); - QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast(configData); - memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); - break; - } - case OMX_IndexConfigVideoAVCIntraPeriod: - { - OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam = - reinterpret_cast(configData); - DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod"); - memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod)); - break; - } - default: - DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); - return OMX_ErrorUnsupportedIndex; - } - return OMX_ErrorNone; - -} - -/* ====================================================================== -FUNCTION - omx_video::GetExtensionIndex - -DESCRIPTION - OMX GetExtensionIndex method implementaion. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_STRING paramName, - OMX_OUT OMX_INDEXTYPE* indexType) -{ - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n"); - return OMX_ErrorInvalidState; - } -#ifdef MAX_RES_1080P - if (!strncmp(paramName, "OMX.QCOM.index.param.SliceDeliveryMode", - sizeof("OMX.QCOM.index.param.SliceDeliveryMode") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; - return OMX_ErrorNone; - } -#endif -#ifdef _ANDROID_ICS_ - if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers",sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) { - *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoEncodeMetaBufferMode; - return OMX_ErrorNone; - } -#endif - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_video::GetState - -DESCRIPTION - Returns the state information back to the caller. - -PARAMETERS - . - -RETURN VALUE - Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_STATETYPE* state) -{ - *state = m_state; - DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_video::ComponentTunnelRequest - -DESCRIPTION - OMX Component Tunnel Request method implementation. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_HANDLETYPE peerComponent, - OMX_IN OMX_U32 peerPort, - OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) -{ - DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n"); - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_video::UseInputBuffer - -DESCRIPTION - Helper function for Use buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::use_input_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - unsigned i = 0; - unsigned char *buf_addr = NULL; - - DEBUG_PRINT_HIGH("use_input_buffer: port = %lu appData = %p bytes = %lu buffer = %p",port,appData,bytes,buffer); - if(bytes != m_sInPortDef.nBufferSize) - { - DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! " - "bytes[%lu] != Port.nBufferSize[%lu]", bytes, m_sInPortDef.nBufferSize); - return OMX_ErrorBadParameter; - } - - if(!m_inp_mem_ptr) - { - input_use_buffer = true; - m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); - if(m_inp_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); - return OMX_ErrorInsufficientResources; - } - - - m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); - if(m_pInput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); - return OMX_ErrorInsufficientResources; - } -#ifdef USE_ION - m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); - if(m_pInput_ion == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion"); - return OMX_ErrorInsufficientResources; - } -#endif - - for(i=0; i< m_sInPortDef.nBufferCountActual; i++) - { - m_pInput_pmem[i].fd = -1; -#ifdef USE_ION - m_pInput_ion[i].ion_device_fd =-1; - m_pInput_ion[i].fd_ion_data.fd =-1; - m_pInput_ion[i].ion_alloc_data.handle=NULL; -#endif - } - - } - - for(i=0; i< m_sInPortDef.nBufferCountActual; i++) - { - if(BITMASK_ABSENT(&m_inp_bm_count,i)) - { - break; - } - } - - if(i < m_sInPortDef.nBufferCountActual) - { - - *bufferHdr = (m_inp_mem_ptr + i); - BITMASK_SET(&m_inp_bm_count,i); - - (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; - (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); - (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; - (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; - (*bufferHdr)->pAppPrivate = appData; - (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; - - if(!m_use_input_pmem) - { -#ifdef USE_ION -#ifdef _MSM8974_ - m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, - &m_pInput_ion[i].ion_alloc_data, - &m_pInput_ion[i].fd_ion_data,0); -#else - m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, - &m_pInput_ion[i].ion_alloc_data, - &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); -#endif - if(m_pInput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); - return OMX_ErrorInsufficientResources; - } - m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; -#else - m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - if(m_pInput_pmem[i].fd == 0) - { - m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - } - - if(m_pInput_pmem[i] .fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; - m_pInput_pmem[i].offset = 0; - m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pInput_pmem[i].fd,0); - - if(m_pInput_pmem[i].buffer == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); - close(m_pInput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - else - { - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); - DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); - - if(pParam) - { - m_pInput_pmem[i].fd = pParam->pmem_fd; - m_pInput_pmem[i].offset = pParam->offset; - m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; - m_pInput_pmem[i].buffer = (unsigned char *)buffer; - DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u", - pParam->pmem_fd, pParam->offset); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); - return OMX_ErrorBadParameter; - } - } - - DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", - (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); - if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for " - "index = %u", i); - eRet = OMX_ErrorInsufficientResources; - } - - return eRet; -} - - - -/* ====================================================================== -FUNCTION - omx_video::UseOutputBuffer - -DESCRIPTION - Helper function for Use buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::use_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter - unsigned char *buf_addr = NULL; -#ifdef _MSM8974_ - int align_size; -#endif - - DEBUG_PRINT_HIGH("\n Inside use_output_buffer()"); - if(bytes != m_sOutPortDef.nBufferSize) - { - DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! " - "bytes[%lu] != Port.nBufferSize[%lu]", bytes, m_sOutPortDef.nBufferSize); - return OMX_ErrorBadParameter; - } - - if(!m_out_mem_ptr) - { - output_use_buffer = true; - int nBufHdrSize = 0; - - DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual); - nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); - /* - * Memory for output side involves the following: - * 1. Array of Buffer Headers - * 2. Bitmask array to hold the buffer allocation details - * In order to minimize the memory management entire allocation - * is done in one step. - */ - //OMX Buffer header - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - if(m_out_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr"); - return OMX_ErrorInsufficientResources; - } - - m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); - return OMX_ErrorInsufficientResources; - } -#ifdef USE_ION - m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_ion == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); - return OMX_ErrorInsufficientResources; - } -#endif - if(m_out_mem_ptr) - { - bufHdr = m_out_mem_ptr; - DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); - // Settting the entire storage nicely - for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - bufHdr->nAllocLen = bytes; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = appData; - bufHdr->nOutputPortIndex = PORT_INDEX_OUT; - bufHdr->pBuffer = NULL; - bufHdr++; - m_pOutput_pmem[i].fd = -1; -#ifdef USE_ION - m_pOutput_ion[i].ion_device_fd =-1; - m_pOutput_ion[i].fd_ion_data.fd=-1; - m_pOutput_ion[i].ion_alloc_data.handle =NULL; -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]\n",m_out_mem_ptr); - eRet = OMX_ErrorInsufficientResources; - } - } - - for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) - { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - break; - } - } - - if(eRet == OMX_ErrorNone) - { - if(i < m_sOutPortDef.nBufferCountActual) - { - *bufferHdr = (m_out_mem_ptr + i ); - (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; - (*bufferHdr)->pAppPrivate = appData; - BITMASK_SET(&m_out_bm_count,i); - - if(!m_use_output_pmem) - { -#ifdef USE_ION -#ifdef _MSM8974_ - align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,0); -#else - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory( - m_sOutPortDef.nBufferSize, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); -#endif - if(m_pOutput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); - return OMX_ErrorInsufficientResources; - } - m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; -#else - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - - if(m_pOutput_pmem[i].fd == 0) - { - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - } - - if(m_pOutput_pmem[i].fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; - m_pOutput_pmem[i].offset = 0; -#ifdef _MSM8974_ - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,align_size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#else - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#endif - if(m_pOutput_pmem[i].buffer == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); - close(m_pOutput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - } - else - { - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast((*bufferHdr)->pAppPrivate); - DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam); - - if(pParam) - { - DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); - m_pOutput_pmem[i].fd = pParam->pmem_fd; - m_pOutput_pmem[i].offset = pParam->offset; - m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; - m_pOutput_pmem[i].buffer = (unsigned char *)buffer; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); - return OMX_ErrorBadParameter; - } - buf_addr = (unsigned char *)buffer; - } - - DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", - (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); - if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) - { - DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " - "index = %u", i); - eRet = OMX_ErrorInsufficientResources; - } - } - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_video::UseBuffer - -DESCRIPTION - OMX Use Buffer method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None , if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::use_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes, - OMX_IN OMX_U8* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(port == PORT_INDEX_IN) - { - eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); - } - else if(port == PORT_INDEX_OUT) - { - eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); - eRet = OMX_ErrorBadPortIndex; - } - - if(eRet == OMX_ErrorNone) - { - if(allocate_done()) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - - } - else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_OUT, - OMX_COMPONENT_GENERATE_EVENT); - m_event_port_settings_sent = false; - } - } - } - return eRet; -} - -OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - OMX_U8 *temp_buff ; - - if(bufferHdr == NULL || m_inp_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", - bufferHdr, m_inp_mem_ptr); - return OMX_ErrorBadParameter; - } - - index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); -#ifdef _ANDROID_ICS_ - if(meta_mode_enable) - { - if(index < m_sInPortDef.nBufferCountActual) - { - memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); - memset(&meta_buffers[index], 0, sizeof(meta_buffers[index])); - } - if(!mUseProxyColorFormat) - return OMX_ErrorNone; - else - c2d_conv.close(); - } -#endif - if(index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat && - dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) - { - DEBUG_PRINT_LOW("\nERROR: dev_free_buf() Failed for i/p buf"); - } - - if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) - { - if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case"); - munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); - close (m_pInput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[index]); -#endif - m_pInput_pmem[index].fd = -1; - } - else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && - m_use_input_pmem == OMX_FALSE)) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case"); - if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); - } - munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); - close (m_pInput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[index]); -#endif - m_pInput_pmem[index].fd = -1; - } - else - { - DEBUG_PRINT_ERROR("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); - } - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) -{ - unsigned int index = 0; - OMX_U8 *temp_buff ; - - if(bufferHdr == NULL || m_out_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", - bufferHdr, m_out_mem_ptr); - return OMX_ErrorBadParameter; - } - index = bufferHdr - m_out_mem_ptr; - - if(index < m_sOutPortDef.nBufferCountActual && - dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) - { - DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); - } - - if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) - { - if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case"); - munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); - close (m_pOutput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[index]); -#endif - m_pOutput_pmem[index].fd = -1; - } - else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true - && m_use_output_pmem == OMX_FALSE)) - { - DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case"); - if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) - { - DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); - } - munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); - close (m_pOutput_pmem[index].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[index]); -#endif - m_pOutput_pmem[index].fd = -1; - } - else - { - DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); - } - } - return OMX_ErrorNone; -} -#ifdef _ANDROID_ICS_ -OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( - OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE **bufferHdr, - OMX_PTR appData, - OMX_U32 bytes) -{ - unsigned index = 0; - if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type)) - { - DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %lu", - bufferHdr,bytes); - return OMX_ErrorBadParameter; - } - - if(!m_inp_mem_ptr && !mUseProxyColorFormat) - m_inp_mem_ptr = meta_buffer_hdr; - for(index = 0;((index < m_sInPortDef.nBufferCountActual) && - meta_buffer_hdr[index].pBuffer); index++); - if(index == m_sInPortDef.nBufferCountActual) - { - DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer"); - return OMX_ErrorBadParameter; - } - if(mUseProxyColorFormat){ - if(opaque_buffer_hdr[index]){ - DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); - return OMX_ErrorBadParameter; - } - if(allocate_input_buffer(hComp,&opaque_buffer_hdr[index], - PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) { - DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); - return OMX_ErrorBadParameter; - } - } - BITMASK_SET(&m_inp_bm_count,index); - *bufferHdr = &meta_buffer_hdr[index]; - memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); - meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]); - meta_buffer_hdr[index].nAllocLen = bytes; - meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION; - meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN; - meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index]; - meta_buffer_hdr[index].pAppPrivate = appData; - if(mUseProxyColorFormat) { - m_opq_pmem_q.insert_entry((unsigned int)opaque_buffer_hdr[index],0,0); - DEBUG_PRINT_HIGH("\n opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]); - } - return OMX_ErrorNone; -} -#endif -/* ====================================================================== -FUNCTION - omx_venc::AllocateInputBuffer - -DESCRIPTION - Helper function for allocate buffer in the input pin - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::allocate_input_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned i = 0; - - DEBUG_PRINT_HIGH("\n allocate_input_buffer()::"); - if(bytes != m_sInPortDef.nBufferSize) - { - DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%lu] != nBufferSize[%lu]\n", - bytes, m_sInPortDef.nBufferSize); - return OMX_ErrorBadParameter; - } - - if(!m_inp_mem_ptr) - { - DEBUG_PRINT_HIGH("%s: size = %lu, actual cnt %lu", __FUNCTION__, - m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual); - m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ - calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); - if(m_inp_mem_ptr == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); - return OMX_ErrorInsufficientResources; - } - - m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); - - if(m_pInput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); - return OMX_ErrorInsufficientResources; - } -#ifdef USE_ION - m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); - if(m_pInput_ion == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion"); - return OMX_ErrorInsufficientResources; - } -#endif - for(i=0; i< m_sInPortDef.nBufferCountActual; i++) - { - m_pInput_pmem[i].fd = -1; -#ifdef USE_ION - m_pInput_ion[i].ion_device_fd =-1; - m_pInput_ion[i].fd_ion_data.fd =-1; - m_pInput_ion[i].ion_alloc_data.handle=NULL; -#endif - } - } - - for(i=0; i< m_sInPortDef.nBufferCountActual; i++) - { - if(BITMASK_ABSENT(&m_inp_bm_count,i)) - { - break; - } - } - if(i < m_sInPortDef.nBufferCountActual) - { - - *bufferHdr = (m_inp_mem_ptr + i); - (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); - (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; - (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; - (*bufferHdr)->pAppPrivate = appData; - (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; - -#ifdef USE_ION -#ifdef _MSM8974_ - m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, - &m_pInput_ion[i].ion_alloc_data, - &m_pInput_ion[i].fd_ion_data,0); -#else - m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, - &m_pInput_ion[i].ion_alloc_data, - &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); -#endif - if(m_pInput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); - return OMX_ErrorInsufficientResources; - } - - m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; -#else - m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - - if(m_pInput_pmem[i].fd == 0) - { - m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - } - - if(m_pInput_pmem[i].fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; - m_pInput_pmem[i].offset = 0; - - m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pInput_pmem[i].fd,0); - if(m_pInput_pmem[i].buffer == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\nERROR: mmap FAILED= %d\n", errno); - close(m_pInput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pInput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - - (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; - DEBUG_PRINT_LOW("\n Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer); - BITMASK_SET(&m_inp_bm_count,i); - //here change the I/P param here from buf_adr to pmem - if(!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) - { - DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call" - "for index [%d]\n", i); - eRet = OMX_ErrorInsufficientResources; - } - - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_venc::AllocateOutputBuffer - -DESCRIPTION - Helper fn for AllocateBuffer in the output pin - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything went well. - -========================================================================== */ -OMX_ERRORTYPE omx_video::allocate_output_buffer( - OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header - unsigned i= 0; // Temporary counter -#ifdef _MSM8974_ - int align_size; -#endif - DEBUG_PRINT_HIGH("\n allocate_output_buffer()for %lu bytes", bytes); - if(!m_out_mem_ptr) - { - int nBufHdrSize = 0; - DEBUG_PRINT_HIGH("%s: size = %lu, actual cnt %lu", __FUNCTION__, - m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual); - nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); - - /* - * Memory for output side involves the following: - * 1. Array of Buffer Headers - * 2. Bitmask array to hold the buffer allocation details - * In order to minimize the memory management entire allocation - * is done in one step. - */ - m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); - -#ifdef USE_ION - m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_ion == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual); - if(m_pOutput_pmem == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); - return OMX_ErrorInsufficientResources; - } - if(m_out_mem_ptr && m_pOutput_pmem) - { - bufHdr = m_out_mem_ptr; - - for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) - { - bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); - bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; - // Set the values when we determine the right HxW param - bufHdr->nAllocLen = bytes; - bufHdr->nFilledLen = 0; - bufHdr->pAppPrivate = appData; - bufHdr->nOutputPortIndex = PORT_INDEX_OUT; - bufHdr->pBuffer = NULL; - bufHdr++; - m_pOutput_pmem[i].fd = -1; -#ifdef USE_ION - m_pOutput_ion[i].ion_device_fd =-1; - m_pOutput_ion[i].fd_ion_data.fd=-1; - m_pOutput_ion[i].ion_alloc_data.handle =NULL; -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem"); - eRet = OMX_ErrorInsufficientResources; - } - } - - DEBUG_PRINT_HIGH("\n actual cnt = %lu", m_sOutPortDef.nBufferCountActual); - for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) - { - if(BITMASK_ABSENT(&m_out_bm_count,i)) - { - DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); - break; - } - } - if(eRet == OMX_ErrorNone) - { - if(i < m_sOutPortDef.nBufferCountActual) - { -#ifdef USE_ION -#ifdef _MSM8974_ - align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,0); -#else - m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize, - &m_pOutput_ion[i].ion_alloc_data, - &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); -#endif - if(m_pOutput_ion[i].ion_device_fd < 0) { - DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); - return OMX_ErrorInsufficientResources; - } - - m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; -#else - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - if(m_pOutput_pmem[i].fd == 0) - { - m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); - } - - if(m_pOutput_pmem[i].fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed"); - return OMX_ErrorInsufficientResources; - } -#endif - m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; - m_pOutput_pmem[i].offset = 0; -#ifdef _MSM8974_ - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,align_size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#else - m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, - MAP_SHARED,m_pOutput_pmem[i].fd,0); -#endif - if(m_pOutput_pmem[i].buffer == MAP_FAILED) - { - DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer"); - close (m_pOutput_pmem[i].fd); -#ifdef USE_ION - free_ion_memory(&m_pOutput_ion[i]); -#endif - return OMX_ErrorInsufficientResources; - } - - *bufferHdr = (m_out_mem_ptr + i ); - (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer; - (*bufferHdr)->pAppPrivate = appData; - - BITMASK_SET(&m_out_bm_count,i); - - if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf"); - return OMX_ErrorInsufficientResources; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call" - "for index [%d] actual: %lu\n", i, m_sOutPortDef.nBufferCountActual); - } - } - - return eRet; -} - - -// AllocateBuffer -- API Call -/* ====================================================================== -FUNCTION - omx_video::AllocateBuffer - -DESCRIPTION - Returns zero if all the buffers released.. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN OMX_U32 bytes) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type - - DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - // What if the client calls again. - if(port == PORT_INDEX_IN) - { -#ifdef _ANDROID_ICS_ - if(meta_mode_enable) - eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes); - else -#endif - eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); - } - else if(port == PORT_INDEX_OUT) - { - eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); - if(eRet == OMX_ErrorNone) - { - if(allocate_done()) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); - post_event(OMX_CommandStateSet,OMX_StateIdle, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - } - if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) - { - if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) - { - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); - post_event(OMX_CommandPortEnable, - PORT_INDEX_OUT, - OMX_COMPONENT_GENERATE_EVENT); - m_event_port_settings_sent = false; - } - } - } - DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); - return eRet; -} - - -// Free Buffer - API call -/* ====================================================================== -FUNCTION - omx_video::FreeBuffer - -DESCRIPTION - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_U32 port, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - unsigned int nPortIndex; - - DEBUG_PRINT_LOW("In for encoder free_buffer \n"); - - if(m_state == OMX_StateIdle && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); - } - else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)|| - (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) - { - DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); - } - else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) - { - DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - return eRet; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n"); - post_event(OMX_EventError, - OMX_ErrorPortUnpopulated, - OMX_COMPONENT_GENERATE_EVENT); - } - - if(port == PORT_INDEX_IN) - { - // check if the buffer is valid - nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); - - DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n", - nPortIndex, m_sInPortDef.nBufferCountActual); - if(nPortIndex < m_sInPortDef.nBufferCountActual) - { - // Clear the bit associated with it. - BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); - free_input_buffer (buffer); - m_sInPortDef.bPopulated = OMX_FALSE; - - /*Free the Buffer Header*/ - if(release_input_done() -#ifdef _ANDROID_ICS_ - && !meta_mode_enable -#endif - ) - { - input_use_buffer = false; - if(m_inp_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n"); - free (m_inp_mem_ptr); - m_inp_mem_ptr = NULL; - } - if(m_pInput_pmem) - { - DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n"); - free(m_pInput_pmem); - m_pInput_pmem = NULL; - } -#ifdef USE_ION - if(m_pInput_ion) - { - DEBUG_PRINT_LOW("Freeing m_pInput_ion\n"); - free(m_pInput_ion); - m_pInput_ion = NULL; - } -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) - && release_input_done()) - { - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); - post_event(OMX_CommandPortDisable, - PORT_INDEX_IN, - OMX_COMPONENT_GENERATE_EVENT); - } - } - else if(port == PORT_INDEX_OUT) - { - // check if the buffer is valid - nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; - - DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n", - nPortIndex, m_sOutPortDef.nBufferCountActual); - if(nPortIndex < m_sOutPortDef.nBufferCountActual) - { - // Clear the bit associated with it. - BITMASK_CLEAR(&m_out_bm_count,nPortIndex); - m_sOutPortDef.bPopulated = OMX_FALSE; - free_output_buffer (buffer); - - if(release_output_done()) - { - output_use_buffer = false; - if(m_out_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n"); - free (m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - if(m_pOutput_pmem) - { - DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n"); - free(m_pOutput_pmem); - m_pOutput_pmem = NULL; - } -#ifdef USE_ION - if(m_pOutput_ion) - { - DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n"); - free(m_pOutput_ion); - m_pOutput_ion = NULL; - } -#endif - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n"); - eRet = OMX_ErrorBadPortIndex; - } - if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) - && release_output_done() ) - { - DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); - - DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); - post_event(OMX_CommandPortDisable, - PORT_INDEX_OUT, - OMX_COMPONENT_GENERATE_EVENT); - - } - } - else - { - eRet = OMX_ErrorBadPortIndex; - } - if((eRet == OMX_ErrorNone) && - (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) - { - if(release_done()) - { - if(dev_stop() != 0) - { - DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n"); - eRet = OMX_ErrorHardware; - } - // Send the callback now - BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); - post_event(OMX_CommandStateSet, OMX_StateLoaded, - OMX_COMPONENT_GENERATE_EVENT); - } else { - DEBUG_PRINT_ERROR("in free buffer, release not done, need to free more buffers input 0x%x output 0x%x", - m_out_bm_count, m_inp_bm_count); - } - } - - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_video::EmptyThisBuffer - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_ERRORTYPE ret1 = OMX_ErrorNone; - unsigned int nBufferIndex ; - - DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) - { - DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid"); - return OMX_ErrorBadParameter; - } - - if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) - { - DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid"); - return OMX_ErrorVersionMismatch; - } - - if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) - { - DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer"); - return OMX_ErrorBadPortIndex; - } - if(!m_sInPortDef.bEnabled) - { - DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled"); - return OMX_ErrorIncorrectStateOperation; - } - - nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); - - if(nBufferIndex > m_sInPortDef.nBufferCountActual ) - { - DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex); - return OMX_ErrorBadParameter; - } - - m_etb_count++; - DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp); - post_event ((unsigned)hComp,(unsigned)buffer,m_input_msg_id); - return OMX_ErrorNone; -} -/* ====================================================================== -FUNCTION - omx_video::empty_this_buffer_proxy - -DESCRIPTION - This routine is used to push the encoded video frames to - the video decoder. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything went successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - OMX_U8 *pmem_data_buf = NULL; - int push_cnt = 0; - unsigned nBufIndex = 0, nBufIndex_meta = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - encoder_media_buffer_type *media_buffer; - -#ifdef _MSM8974_ - int fd = 0; -#endif - DEBUG_PRINT_LOW("\n ETBProxy: buffer->pBuffer[%p]\n", buffer->pBuffer); - if(buffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer); - return OMX_ErrorBadParameter; - } - nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); - nBufIndex_meta = buffer - meta_buffer_hdr; - media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer; - if(nBufIndex >= m_sInPortDef.nBufferCountActual && - nBufIndex_meta >= m_sInPortDef.nBufferCountActual) - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex); - return OMX_ErrorBadParameter; - } - pending_input_buffers++; - if(input_flush_progress == true) - { - post_event ((unsigned int)buffer,0, - OMX_COMPONENT_GENERATE_EBD); - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress"); - return OMX_ErrorNone; - } -#ifdef _MSM8974_ - if(!meta_mode_enable || - (media_buffer && media_buffer->buffer_type == kMetadataBufferTypeGrallocSource)) { - fd = m_pInput_pmem[nBufIndex].fd; - } -#endif -#ifdef _ANDROID_ICS_ - if(meta_mode_enable && !mUseProxyColorFormat) - { - bool met_error = false; - if(media_buffer) - { - if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource && - media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) - met_error = true; - else { - if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) - { - if(media_buffer->meta_handle == NULL) - met_error = true; - else if((media_buffer->meta_handle->numFds != 1 && - media_buffer->meta_handle->numInts != 2)) - met_error = true; - } - } - } else - met_error = true; - if(met_error) - { - DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call"); - post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorBadParameter; - } - struct pmem Input_pmem_info; - if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) - { - Input_pmem_info.buffer = media_buffer; - Input_pmem_info.fd = media_buffer->meta_handle->data[0]; -#ifdef _MSM8974_ - fd = Input_pmem_info.fd; -#endif - Input_pmem_info.offset = media_buffer->meta_handle->data[1]; - Input_pmem_info.size = media_buffer->meta_handle->data[2]; - DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, - Input_pmem_info.offset, - Input_pmem_info.size); - } else { - private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; - Input_pmem_info.buffer = media_buffer; - Input_pmem_info.fd = handle->fd; -#ifdef _MSM8974_ - fd = Input_pmem_info.fd; -#endif - Input_pmem_info.offset = 0; - Input_pmem_info.size = handle->size; - } - if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { - DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); - post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); - return OMX_ErrorBadParameter; - } - } - else if(input_use_buffer && !m_use_input_pmem) -#else - if(input_use_buffer && !m_use_input_pmem) -#endif - { - DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data"); - pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; - memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), - buffer->nFilledLen); - DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); - } -#ifdef _MSM8974_ - if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true) -#else - if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true) -#endif - { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed"); -#ifdef _ANDROID_ICS_ - omx_release_meta_buffer(buffer); -#endif - post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); - /*Generate an async error and move to invalid state*/ - pending_input_buffers--; - return OMX_ErrorBadParameter; - } - return ret; -} - -/* ====================================================================== -FUNCTION - omx_video::FillThisBuffer - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer); - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n"); - return OMX_ErrorInvalidState; - } - - if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n"); - return OMX_ErrorBadParameter; - } - - if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n"); - return OMX_ErrorVersionMismatch; - } - - if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n"); - return OMX_ErrorBadPortIndex; - } - - if(!m_sOutPortDef.bEnabled) - { - DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n"); - return OMX_ErrorIncorrectStateOperation; - } - - post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB); - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_video::fill_this_buffer_proxy - -DESCRIPTION - IL client uses this method to release the frame buffer - after displaying them. - -PARAMETERS - None. - -RETURN VALUE - true/false - -========================================================================== */ -OMX_ERRORTYPE omx_video::fill_this_buffer_proxy( - OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) -{ - OMX_U8 *pmem_data_buf = NULL; - OMX_ERRORTYPE nRet = OMX_ErrorNone; - - DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer); - - if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) ) - { - DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n"); - return OMX_ErrorBadParameter; - } - - pending_output_buffers++; - /*Return back the output buffer to client*/ - if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) - { - DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress"); - post_event ((unsigned int)bufferAdd,0, - OMX_COMPONENT_GENERATE_FBD); - return OMX_ErrorNone; - } - - if(output_use_buffer && !m_use_output_pmem) - { - DEBUG_PRINT_LOW("\n Heap UseBuffer case"); - pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer; - } - - if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) - { - DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed"); - post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD); - pending_output_buffers--; - return OMX_ErrorBadParameter; - } - - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_video::SetCallbacks - -DESCRIPTION - Set the callbacks. - -PARAMETERS - None. - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_CALLBACKTYPE* callbacks, - OMX_IN OMX_PTR appData) -{ - - m_pCallbacks = *callbacks; - DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\ - m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone); - m_app_data = appData; - return OMX_ErrorNotImplemented; -} - - -/* ====================================================================== -FUNCTION - omx_venc::UseEGLImage - -DESCRIPTION - OMX Use EGL Image method implementation . - -PARAMETERS - . - -RETURN VALUE - Not Implemented error. - -========================================================================== */ -OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, - OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, - OMX_IN OMX_U32 port, - OMX_IN OMX_PTR appData, - OMX_IN void* eglImage) -{ - DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n"); - return OMX_ErrorNotImplemented; -} - -/* ====================================================================== -FUNCTION - omx_venc::ComponentRoleEnum - -DESCRIPTION - OMX Component Role Enum method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything is successful. -========================================================================== */ -OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, - OMX_OUT OMX_U8* role, - OMX_IN OMX_U32 index) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } -#ifdef _MSM8974_ - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if((0 == index) && role) - { - strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); - DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); - eRet = OMX_ErrorNoMore; - } - } -#endif - else - { - DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } - return eRet; -} - - - - -/* ====================================================================== -FUNCTION - omx_venc::AllocateDone - -DESCRIPTION - Checks if entire buffer pool is allocated by IL Client or not. - Need this to move to IDLE state. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_video::allocate_done(void) -{ - bool bRet = false; - bool bRet_In = false; - bool bRet_Out = false; - - bRet_In = allocate_input_done(); - bRet_Out = allocate_output_done(); - - if(bRet_In && bRet_Out) - { - bRet = true; - } - - return bRet; -} -/* ====================================================================== -FUNCTION - omx_venc::AllocateInputDone - -DESCRIPTION - Checks if I/P buffer pool is allocated by IL Client or not. - -PARAMETERS - None. - -RETURN VALUE - true/false. - -========================================================================== */ -bool omx_video::allocate_input_done(void) -{ - bool bRet = false; - unsigned i=0; - - if(m_inp_mem_ptr == NULL) - { - return bRet; - } - if(m_inp_mem_ptr ) - { - for(;ipBuffer[%p], flags=0x%x size = %d", - buffer->pBuffer, buffer->nFlags,buffer->nFilledLen); - if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual)) - { - return OMX_ErrorBadParameter; - } - - pending_output_buffers--; - - extra_data_handle.create_extra_data(buffer); -#ifndef _MSM8974_ - if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { - DEBUG_PRINT_LOW("parsing extradata"); - extra_data_handle.parse_extra_data(buffer); - } -#endif - /* For use buffer we need to copy the data */ - if(m_pCallbacks.FillBufferDone) - { - if(buffer->nFilledLen > 0) - { - m_fbd_count++; - -#ifdef OUTPUT_BUFFER_LOG - if(outputBufferFile1) - { - fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1); - } -#endif - } -#ifdef _MSM8974_ - if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { - if(!dev_handle_extradata((void *)buffer, index)) - DEBUG_PRINT_ERROR("Failed to parse extradata\n"); - } -#endif - m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer); - } - else - { - return OMX_ErrorBadParameter; - } - return OMX_ErrorNone; -} - -OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, - OMX_BUFFERHEADERTYPE* buffer) -{ - int buffer_index = -1; - int buffer_index_meta = -1; - - buffer_index = (buffer - m_inp_mem_ptr); - buffer_index_meta = (buffer - meta_buffer_hdr); - DEBUG_PRINT_LOW("\n empty_buffer_done: buffer[%p]", buffer); - if(buffer == NULL || - ((buffer_index > m_sInPortDef.nBufferCountActual) && - (buffer_index_meta > m_sInPortDef.nBufferCountActual))) - { - DEBUG_PRINT_ERROR("\n ERROR in empty_buffer_done due to index buffer"); - return OMX_ErrorBadParameter; - } - - pending_input_buffers--; - - if(mUseProxyColorFormat && (buffer_index < m_sInPortDef.nBufferCountActual)) { - if(!pdest_frame) { - pdest_frame = buffer; - DEBUG_PRINT_LOW("\n empty_buffer_done pdest_frame address is %p",pdest_frame); - return push_input_buffer(hComp); - - } else { - DEBUG_PRINT_LOW("\n empty_buffer_done insert address is %p",buffer); - if (!m_opq_pmem_q.insert_entry((unsigned int)buffer, 0, 0)) { - DEBUG_PRINT_ERROR("\n empty_buffer_done: pmem queue is full"); - return OMX_ErrorBadParameter; - } - } - } else if(m_pCallbacks.EmptyBufferDone) { - m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer); - } - return OMX_ErrorNone; -} - -void omx_video::complete_pending_buffer_done_cbs() -{ - unsigned p1; - unsigned p2; - unsigned ident; - omx_cmd_queue tmp_q, pending_bd_q; - pthread_mutex_lock(&m_lock); - // pop all pending GENERATE FDB from ftb queue - while (m_ftb_q.m_size) - { - m_ftb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_FBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to ftb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_ftb_q.insert_entry(p1,p2,ident); - } - // pop all pending GENERATE EDB from etb queue - while (m_etb_q.m_size) - { - m_etb_q.pop_entry(&p1,&p2,&ident); - if(ident == OMX_COMPONENT_GENERATE_EBD) - { - pending_bd_q.insert_entry(p1,p2,ident); - } - else - { - tmp_q.insert_entry(p1,p2,ident); - } - } - //return all non GENERATE FDB to etb queue - while(tmp_q.m_size) - { - tmp_q.pop_entry(&p1,&p2,&ident); - m_etb_q.insert_entry(p1,p2,ident); - } - pthread_mutex_unlock(&m_lock); - // process all pending buffer dones - while(pending_bd_q.m_size) - { - pending_bd_q.pop_entry(&p1,&p2,&ident); - switch(ident) - { - case OMX_COMPONENT_GENERATE_EBD: - if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) - { - DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); - omx_report_error (); - } - break; - - case OMX_COMPONENT_GENERATE_FBD: - if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) - { - DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); - omx_report_error (); - } - break; - } - } -} - -#ifdef MAX_RES_720P -OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 1) { - if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", - profileLevelType->eProfile,profileLevelType->eLevel); - return eRet; -} -#endif - -#ifdef MAX_RES_1080P -OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - if(!profileLevelType) - return OMX_ErrorBadParameter; - - if(profileLevelType->nPortIndex == 1) { - if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) - { -#ifdef _MSM8974_ - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; - - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel51; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } -#else - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - - } - else if (profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else if(profileLevelType->nProfileIndex == 2) - { - profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; - profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; - } - else - { - DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", - profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } -#endif - } - else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; - profileLevelType->eLevel = OMX_VIDEO_H263Level70; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) - { - if (profileLevelType->nProfileIndex == 0) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else if(profileLevelType->nProfileIndex == 1) - { - profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore\n"); - eRet = OMX_ErrorNoMore; - } - } - else - { - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%lu, Level:%lu\n", - profileLevelType->eProfile,profileLevelType->eLevel); - return eRet; -} -#endif - -#ifdef USE_ION -int alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data, - struct ion_fd_data *fd_data,int flag) -{ - struct venc_ion buf_ion_info; - int ion_device_fd =-1,rc=0,ion_dev_flags = 0; - if (size <=0 || !alloc_data || !fd_data) { - DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory"); - return -EINVAL; - } - - ion_dev_flags = O_RDONLY; - ion_device_fd = open (MEM_DEVICE,ion_dev_flags); - if(ion_device_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed"); - return ion_device_fd; - } - alloc_data->len = size; - alloc_data->align = 4096; - alloc_data->flags = flag; -#ifdef MAX_RES_720P - alloc_data->len = (size + (alloc_data->align - 1)) & ~(alloc_data->align - 1); - alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID); -#else - alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | - ION_HEAP(ION_IOMMU_HEAP_ID)); -#endif - rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data); - if(rc || !alloc_data->handle) { - DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); - alloc_data->handle =NULL; - close(ion_device_fd); - ion_device_fd = -1; - return ion_device_fd; - } - fd_data->handle = alloc_data->handle; - rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data); - if(rc) { - DEBUG_PRINT_ERROR("\n ION MAP failed "); - buf_ion_info.ion_alloc_data = *alloc_data; - buf_ion_info.ion_device_fd = ion_device_fd; - buf_ion_info.fd_ion_data = *fd_data; - free_ion_memory(&buf_ion_info); - fd_data->fd =-1; - ion_device_fd =-1; - } - return ion_device_fd; -} - -void free_ion_memory(struct venc_ion *buf_ion_info) -{ - if (!buf_ion_info) { - DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory"); - return; - } - if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, - &buf_ion_info->ion_alloc_data.handle)) { - DEBUG_PRINT_ERROR("\n ION free failed "); - return; - } - close(buf_ion_info->ion_device_fd); - buf_ion_info->ion_alloc_data.handle = NULL; - buf_ion_info->ion_device_fd = -1; - buf_ion_info->fd_ion_data.fd = -1; -} -#endif - -#ifdef _ANDROID_ICS_ -void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer) -{ - if(buffer && meta_mode_enable) - { - encoder_media_buffer_type *media_ptr; - struct pmem Input_pmem; - unsigned int index_pmem = 0; - bool meta_error = false; - - index_pmem = (buffer - m_inp_mem_ptr); - if(mUseProxyColorFormat && - (index_pmem < m_sInPortDef.nBufferCountActual)) { - if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){ - DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed"); - } - } else { - media_ptr = (encoder_media_buffer_type *) buffer->pBuffer; - if(media_ptr && media_ptr->meta_handle) - { - if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource && - media_ptr->meta_handle->numFds == 1 && - media_ptr->meta_handle->numInts == 2) { - Input_pmem.fd = media_ptr->meta_handle->data[0]; - Input_pmem.buffer = media_ptr; - Input_pmem.size = media_ptr->meta_handle->data[2]; - Input_pmem.offset = media_ptr->meta_handle->data[1]; - DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd, - Input_pmem.offset, - Input_pmem.size); - } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) { - private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle; - Input_pmem.buffer = media_ptr; - Input_pmem.fd = handle->fd; - Input_pmem.offset = 0; - Input_pmem.size = handle->size; - } else { - meta_error = true; - DEBUG_PRINT_ERROR(" Meta Error set in EBD"); - } - if(!meta_error) - meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN); - if(meta_error) - { - DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d", - input_flush_progress); - } - } - } - } -} -#endif -omx_video::omx_c2d_conv::omx_c2d_conv() -{ - c2dcc = NULL; - mLibHandle = NULL; - mConvertOpen = NULL; - mConvertClose = NULL; - src_format = NV12_128m; - pthread_mutex_init(&c_lock, NULL); -} - -bool omx_video::omx_c2d_conv::init() { - bool status = true; - if(mLibHandle || mConvertOpen || mConvertClose) { - DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice"); - status = false; - } - if(status) { - mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); - if(mLibHandle){ - mConvertOpen = (createC2DColorConverter_t *) - dlsym(mLibHandle,"createC2DColorConverter"); - mConvertClose = (destroyC2DColorConverter_t *) - dlsym(mLibHandle,"destroyC2DColorConverter"); - if(!mConvertOpen || !mConvertClose) - status = false; - } else - status = false; - } - if(!status && mLibHandle){ - dlclose(mLibHandle); - mLibHandle = NULL; - mConvertOpen = NULL; - mConvertClose = NULL; - } - return status; -} - -bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, - int dest_fd, void *dest_base, void *dest_viraddr) -{ - int result; - if(!src_viraddr || !dest_viraddr || !c2dcc || !src_base || !dest_base){ - DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); - return false; - } - pthread_mutex_lock(&c_lock); - result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, - dest_fd, dest_base, dest_viraddr); - pthread_mutex_unlock(&c_lock); - DEBUG_PRINT_LOW("\n Color convert status %d",result); - return ((result < 0)?false:true); -} - -bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width, - ColorConvertFormat src, ColorConvertFormat dest,unsigned int src_stride) -{ - bool status = false; - pthread_mutex_lock(&c_lock); - if(!c2dcc) { - c2dcc = mConvertOpen(width, height, width, height, - src,dest,0,src_stride); - if(c2dcc) { - src_format = src; - status = true; - } else - DEBUG_PRINT_ERROR("\n mConvertOpen failed"); - } - pthread_mutex_unlock(&c_lock); - return status; -} - -void omx_video::omx_c2d_conv::close() -{ - if(mLibHandle) { - pthread_mutex_lock(&c_lock); - if(mConvertClose && c2dcc) - mConvertClose(c2dcc); - pthread_mutex_unlock(&c_lock); - c2dcc = NULL; - } -} -omx_video::omx_c2d_conv::~omx_c2d_conv() -{ - DEBUG_PRINT_ERROR("\n Destroy C2D instance"); - if(mLibHandle) { - if(mConvertClose && c2dcc) { - pthread_mutex_lock(&c_lock); - mConvertClose(c2dcc); - pthread_mutex_unlock(&c_lock); - } - dlclose(mLibHandle); - } - c2dcc = NULL; - mLibHandle = NULL; - mConvertOpen = NULL; - mConvertClose = NULL; - pthread_mutex_destroy(&c_lock); -} - -int omx_video::omx_c2d_conv::get_src_format() -{ - int format = -1; - if(src_format == NV12_128m) { - format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; - } else if(src_format == RGBA8888) { - format = HAL_PIXEL_FORMAT_RGBA_8888; - } - return format; -} - -bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) -{ - int cret = 0; - bool ret = false; - C2DBuffReq bufferreq; - if(c2dcc){ - bufferreq.size = 0; - pthread_mutex_lock(&c_lock); - cret = c2dcc->getBuffReq(port,&bufferreq); - pthread_mutex_unlock(&c_lock); - DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret); - ret = (cret)?false:true; - buf_size = bufferreq.size; - } - return ret; -} - -OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_BUFFERHEADERTYPE* buffer) -{ - unsigned nBufIndex = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - encoder_media_buffer_type *media_buffer; - DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer); - - if(buffer == NULL) { - DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer); - return OMX_ErrorBadParameter; - } - nBufIndex = buffer - meta_buffer_hdr; - if(nBufIndex >= m_sInPortDef.nBufferCountActual) { - DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n", - nBufIndex); - return OMX_ErrorBadParameter; - } - media_buffer = (encoder_media_buffer_type *)buffer->pBuffer; - private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; - /*Enable following code once private handle color format is - updated correctly*/ - - if(c2d_opened && handle->format != c2d_conv.get_src_format()) { - c2d_conv.close(); - c2d_opened = false; - } - if (!c2d_opened) { - if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) { - DEBUG_PRINT_ERROR("\n open Color conv for RGBA888 W: %d, H: %d\n", - m_sInPortDef.format.video.nFrameWidth, - m_sInPortDef.format.video.nFrameHeight); - if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight, - m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_128m,handle->width)){ - m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); - DEBUG_PRINT_ERROR("\n Color conv open failed"); - return OMX_ErrorBadParameter; - } - c2d_opened = true; -#ifdef _MSM8974_ - if(!dev_set_format(handle->format)) - DEBUG_PRINT_ERROR("cannot set color format for RGBA8888\n"); -#endif - } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { - DEBUG_PRINT_ERROR("\n Incorrect color format"); - m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); - return OMX_ErrorBadParameter; - } - } - if(input_flush_progress == true) - { - m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); - DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress"); - return OMX_ErrorNone; - } - - if(!psource_frame) { - psource_frame = buffer; - ret = push_input_buffer(hComp); - } else { - if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) { - DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full"); - ret = OMX_ErrorBadParameter; - } - } - if(ret != OMX_ErrorNone) { - m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); - DEBUG_PRINT_LOW("\nERROR: ETBOpaque failed:"); - } - return ret; -} - -OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp, - struct pmem &Input_pmem_info) { - - OMX_ERRORTYPE ret = OMX_ErrorNone; - unsigned address = 0,p2,id; - - DEBUG_PRINT_LOW("\n In queue Meta Buffer"); - if(!psource_frame || !pdest_frame) { - DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); - return OMX_ErrorBadParameter; - } - - if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { - DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); - post_event ((unsigned int)psource_frame,0,OMX_COMPONENT_GENERATE_EBD); - ret = OMX_ErrorBadParameter; - } - - if(ret == OMX_ErrorNone) - ret = empty_this_buffer_proxy(hComp,psource_frame); - - if(ret == OMX_ErrorNone) { - psource_frame = NULL; - if(!psource_frame && m_opq_meta_q.m_size) { - m_opq_meta_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE* ) address; - } - } - return ret; -} - -OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp, - struct pmem &Input_pmem_info,unsigned &index){ - - unsigned char *uva; - OMX_ERRORTYPE ret = OMX_ErrorNone; - unsigned address = 0,p2,id; - - DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer"); - if(!psource_frame || !pdest_frame) { - DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); - return OMX_ErrorBadParameter; - } - - if(!psource_frame->nFilledLen){ - pdest_frame->nOffset = 0; - pdest_frame->nFilledLen = 0; - pdest_frame->nTimeStamp = psource_frame->nTimeStamp; - pdest_frame->nFlags = psource_frame->nFlags; - DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", - pdest_frame,pdest_frame->nFilledLen); - } else { - uva = (unsigned char *)mmap(NULL, Input_pmem_info.size, - PROT_READ|PROT_WRITE, - MAP_SHARED,Input_pmem_info.fd,0); - if(uva == MAP_FAILED) { - ret = OMX_ErrorBadParameter; - } else { - if(!c2d_conv.convert(Input_pmem_info.fd, uva, uva, - m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) { - DEBUG_PRINT_ERROR("\n Color Conversion failed"); - ret = OMX_ErrorBadParameter; - } else { - unsigned int buf_size = 0; - if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size)) - ret = OMX_ErrorBadParameter; - else { - pdest_frame->nOffset = 0; - pdest_frame->nFilledLen = buf_size; - pdest_frame->nTimeStamp = psource_frame->nTimeStamp; - pdest_frame->nFlags = psource_frame->nFlags; - DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", - pdest_frame,pdest_frame->nFilledLen); - } - } - munmap(uva,Input_pmem_info.size); - } - } - if(dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) { - DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); - post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD); - ret = OMX_ErrorBadParameter; - } - if(ret == OMX_ErrorNone) - ret = empty_this_buffer_proxy(hComp,pdest_frame); - if(ret == OMX_ErrorNone) { - m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame); - psource_frame = NULL; - pdest_frame = NULL; - if(!psource_frame && m_opq_meta_q.m_size) { - m_opq_meta_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE* ) address; - } - if(!pdest_frame && m_opq_pmem_q.m_size) { - m_opq_pmem_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; - DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame); - } - } - return ret; -} - -OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp) -{ - unsigned address = 0,p2,id, index = 0; - OMX_ERRORTYPE ret = OMX_ErrorNone; - - if(!psource_frame && m_opq_meta_q.m_size) { - m_opq_meta_q.pop_entry(&address,&p2,&id); - psource_frame = (OMX_BUFFERHEADERTYPE* ) address; - } - if(!pdest_frame && m_opq_pmem_q.m_size) { - m_opq_pmem_q.pop_entry(&address,&p2,&id); - pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; - } - while(psource_frame != NULL && pdest_frame != NULL && - ret == OMX_ErrorNone) { - struct pmem Input_pmem_info; - encoder_media_buffer_type *media_buffer; - index = pdest_frame - m_inp_mem_ptr; - if(index >= m_sInPortDef.nBufferCountActual){ - DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d", - index,m_sInPortDef.nBufferCountActual); - return OMX_ErrorBadParameter; - } - media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer; - /*Will enable to verify camcorder in current TIPS can be removed*/ - if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { - Input_pmem_info.buffer = media_buffer; - Input_pmem_info.fd = media_buffer->meta_handle->data[0]; - Input_pmem_info.offset = media_buffer->meta_handle->data[1]; - Input_pmem_info.size = media_buffer->meta_handle->data[2]; - DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, - Input_pmem_info.offset, - Input_pmem_info.size); - ret = queue_meta_buffer(hComp,Input_pmem_info); - } else { - private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; - Input_pmem_info.buffer = media_buffer; - Input_pmem_info.fd = handle->fd; - Input_pmem_info.offset = 0; - Input_pmem_info.size = handle->size; - if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888) - ret = convert_queue_buffer(hComp,Input_pmem_info,index); - else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) - ret = queue_meta_buffer(hComp,Input_pmem_info); - else - ret = OMX_ErrorBadParameter; - } - } - return ret; -} diff --git a/mm-video/vidc/venc/src/omx_video_encoder.cpp b/mm-video/vidc/venc/src/omx_video_encoder.cpp deleted file mode 100644 index e47db8f3..00000000 --- a/mm-video/vidc/venc/src/omx_video_encoder.cpp +++ /dev/null @@ -1,1933 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "omx_video_encoder.h" -#include -#include "video_encoder_device.h" -#include -#ifdef _ANDROID_ICS_ -#include -#endif -#ifdef _ANDROID_ -#include -#endif -#ifndef _ANDROID_ -#include -#define strlcpy g_strlcpy -#endif -/*---------------------------------------------------------------------------- -* Preprocessor Definitions and Constants -* -------------------------------------------------------------------------*/ - -#define OMX_SPEC_VERSION 0x00000101 -#define OMX_INIT_STRUCT(_s_, _name_) \ - memset((_s_), 0x0, sizeof(_name_)); \ - (_s_)->nSize = sizeof(_name_); \ - (_s_)->nVersion.nVersion = OMX_SPEC_VERSION - -extern int m_pipe; - -// factory function executed by the core to create instances -void *get_omx_component_factory_fn(void) -{ - return(new omx_venc); -} - -//constructor - -omx_venc::omx_venc() -{ -#ifdef _ANDROID_ICS_ - meta_mode_enable = false; - memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr)); - memset(meta_buffers,0,sizeof(meta_buffers)); - memset(opaque_buffer_hdr,0,sizeof(opaque_buffer_hdr)); - mUseProxyColorFormat = false; - get_syntaxhdr_enable = false; -#endif -} - -omx_venc::~omx_venc() -{ - get_syntaxhdr_enable = false; - //nothing to do -} - -/* ====================================================================== -FUNCTION - omx_venc::ComponentInit - -DESCRIPTION - Initialize the component. - -PARAMETERS - ctxt -- Context information related to the self. - id -- Event identifier. This could be any of the following: - 1. Command completion event - 2. Buffer done callback event - 3. Frame done callback event - -RETURN VALUE - None. - -========================================================================== */ -OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role) -{ - - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - int fds[2]; - int r; - - OMX_VIDEO_CODINGTYPE codec_type; - - DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_init()"); - // Copy the role information which provides the decoder m_nkind - strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE); - - if(!strncmp((char *)m_nkind,"OMX.qcom.video.encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingMPEG4; - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingH263; - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingAVC; - } -#ifdef _MSM8974_ - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.vp8", \ - OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char *)m_cRole, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); - codec_type = OMX_VIDEO_CodingVPX; - } -#endif - else - { - DEBUG_PRINT_ERROR("\nERROR: Unknown Component\n"); - eRet = OMX_ErrorInvalidComponentName; - } - - - if(eRet != OMX_ErrorNone) - { - return eRet; - } -#ifdef ENABLE_GET_SYNTAX_HDR - get_syntaxhdr_enable = true; - DEBUG_PRINT_HIGH("Get syntax header enabled"); -#endif - - handle = new venc_dev(this); - - if(handle == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: handle is NULL"); - return OMX_ErrorInsufficientResources; - } - - if(handle->venc_open(codec_type) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_open failed"); - return OMX_ErrorInsufficientResources; - } - - //Intialise the OMX layer variables - memset(&m_pCallbacks,0,sizeof(OMX_CALLBACKTYPE)); - - OMX_INIT_STRUCT(&m_sPortParam, OMX_PORT_PARAM_TYPE); - m_sPortParam.nPorts = 0x2; - m_sPortParam.nStartPortNumber = (OMX_U32) PORT_INDEX_IN; - - OMX_INIT_STRUCT(&m_sPortParam_audio, OMX_PORT_PARAM_TYPE); - m_sPortParam_audio.nPorts = 0; - m_sPortParam_audio.nStartPortNumber = 0; - - OMX_INIT_STRUCT(&m_sPortParam_img, OMX_PORT_PARAM_TYPE); - m_sPortParam_img.nPorts = 0; - m_sPortParam_img.nStartPortNumber = 0; - - OMX_INIT_STRUCT(&m_sParamBitrate, OMX_VIDEO_PARAM_BITRATETYPE); - m_sParamBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamBitrate.eControlRate = OMX_Video_ControlRateVariableSkipFrames; - m_sParamBitrate.nTargetBitrate = 64000; - - OMX_INIT_STRUCT(&m_sConfigBitrate, OMX_VIDEO_CONFIG_BITRATETYPE); - m_sConfigBitrate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sConfigBitrate.nEncodeBitrate = 64000; - - OMX_INIT_STRUCT(&m_sConfigFramerate, OMX_CONFIG_FRAMERATETYPE); - m_sConfigFramerate.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sConfigFramerate.xEncodeFramerate = 30 << 16; - - OMX_INIT_STRUCT(&m_sConfigIntraRefreshVOP, OMX_CONFIG_INTRAREFRESHVOPTYPE); - m_sConfigIntraRefreshVOP.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE; - - OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE); - m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN; - m_sConfigFrameRotation.nRotation = 0; - - OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE); - m_sSessionQuantization.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sSessionQuantization.nQpI = 9; - m_sSessionQuantization.nQpP = 6; - m_sSessionQuantization.nQpB = 2; - - OMX_INIT_STRUCT(&m_sSessionQPRange, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE); - m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sSessionQPRange.minQP = 2; - if(codec_type == OMX_VIDEO_CodingAVC) - m_sSessionQPRange.maxQP = 51; - else - m_sSessionQPRange.maxQP = 31; - - OMX_INIT_STRUCT(&m_sAVCSliceFMO, OMX_VIDEO_PARAM_AVCSLICEFMO); - m_sAVCSliceFMO.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sAVCSliceFMO.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; - m_sAVCSliceFMO.nNumSliceGroups = 0; - m_sAVCSliceFMO.nSliceGroupMapType = 0; - OMX_INIT_STRUCT(&m_sParamProfileLevel, OMX_VIDEO_PARAM_PROFILELEVELTYPE); - m_sParamProfileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - - OMX_INIT_STRUCT(&m_sIntraperiod, QOMX_VIDEO_INTRAPERIODTYPE); - m_sIntraperiod.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sIntraperiod.nPFrames = (m_sConfigFramerate.xEncodeFramerate * 2) - 1; - - OMX_INIT_STRUCT(&m_sErrorCorrection, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE); - m_sErrorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sErrorCorrection.bEnableDataPartitioning = OMX_FALSE; - m_sErrorCorrection.bEnableHEC = OMX_FALSE; - m_sErrorCorrection.bEnableResync = OMX_FALSE; - m_sErrorCorrection.bEnableRVLC = OMX_FALSE; - m_sErrorCorrection.nResynchMarkerSpacing = 0; - - OMX_INIT_STRUCT(&m_sIntraRefresh, OMX_VIDEO_PARAM_INTRAREFRESHTYPE); - m_sIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sIntraRefresh.eRefreshMode = OMX_VIDEO_IntraRefreshMax; - - if(codec_type == OMX_VIDEO_CodingMPEG4) - { - m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple; - m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_MPEG4Level0; - } - else if(codec_type == OMX_VIDEO_CodingH263) - { - m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_H263ProfileBaseline; - m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_H263Level10; - } - else if(codec_type == OMX_VIDEO_CodingAVC) - { - m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_AVCProfileBaseline; - m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_AVCLevel1; - } - - // Initialize the video parameters for input port - OMX_INIT_STRUCT(&m_sInPortDef, OMX_PARAM_PORTDEFINITIONTYPE); - m_sInPortDef.nPortIndex= (OMX_U32) PORT_INDEX_IN; - m_sInPortDef.bEnabled = OMX_TRUE; - m_sInPortDef.bPopulated = OMX_FALSE; - m_sInPortDef.eDomain = OMX_PortDomainVideo; - m_sInPortDef.eDir = OMX_DirInput; - m_sInPortDef.format.video.cMIMEType = "YUV420"; - m_sInPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; - m_sInPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; - m_sInPortDef.format.video.nStride = OMX_CORE_QCIF_WIDTH; - m_sInPortDef.format.video.nSliceHeight = OMX_CORE_QCIF_HEIGHT; - m_sInPortDef.format.video.nBitrate = 64000; - m_sInPortDef.format.video.xFramerate = 15 << 16; - m_sInPortDef.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - m_sInPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - - if(dev_get_buf_req(&m_sInPortDef.nBufferCountMin, - &m_sInPortDef.nBufferCountActual, - &m_sInPortDef.nBufferSize, - m_sInPortDef.nPortIndex) != true) - { - eRet = OMX_ErrorUndefined; - - } - - // Initialize the video parameters for output port - OMX_INIT_STRUCT(&m_sOutPortDef, OMX_PARAM_PORTDEFINITIONTYPE); - m_sOutPortDef.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sOutPortDef.bEnabled = OMX_TRUE; - m_sOutPortDef.bPopulated = OMX_FALSE; - m_sOutPortDef.eDomain = OMX_PortDomainVideo; - m_sOutPortDef.eDir = OMX_DirOutput; - m_sOutPortDef.format.video.nFrameWidth = OMX_CORE_QCIF_WIDTH; - m_sOutPortDef.format.video.nFrameHeight = OMX_CORE_QCIF_HEIGHT; - m_sOutPortDef.format.video.nBitrate = 64000; - m_sOutPortDef.format.video.xFramerate = 15 << 16; - m_sOutPortDef.format.video.eColorFormat = OMX_COLOR_FormatUnused; - if(codec_type == OMX_VIDEO_CodingMPEG4) - { - m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - } - else if(codec_type == OMX_VIDEO_CodingH263) - { - m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingH263; - } - else - { - m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - } - if(dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex) != true) - { - eRet = OMX_ErrorUndefined; - } - - // Initialize the video color format for input port - OMX_INIT_STRUCT(&m_sInPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); - m_sInPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_IN; - m_sInPortFormat.nIndex = 0; - m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - m_sInPortFormat.eCompressionFormat = OMX_VIDEO_CodingUnused; - - - // Initialize the compression format for output port - OMX_INIT_STRUCT(&m_sOutPortFormat, OMX_VIDEO_PARAM_PORTFORMATTYPE); - m_sOutPortFormat.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sOutPortFormat.nIndex = 0; - m_sOutPortFormat.eColorFormat = OMX_COLOR_FormatUnused; - if(codec_type == OMX_VIDEO_CodingMPEG4) - { - m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingMPEG4; - } - else if(codec_type == OMX_VIDEO_CodingH263) - { - m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingH263; - } - else - { - m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC; - } - - // mandatory Indices for kronos test suite - OMX_INIT_STRUCT(&m_sPriorityMgmt, OMX_PRIORITYMGMTTYPE); - - OMX_INIT_STRUCT(&m_sInBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); - m_sInBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_IN; - - OMX_INIT_STRUCT(&m_sOutBufSupplier, OMX_PARAM_BUFFERSUPPLIERTYPE); - m_sOutBufSupplier.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - - - // mp4 specific init - OMX_INIT_STRUCT(&m_sParamMPEG4, OMX_VIDEO_PARAM_MPEG4TYPE); - m_sParamMPEG4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamMPEG4.eProfile = OMX_VIDEO_MPEG4ProfileSimple; - m_sParamMPEG4.eLevel = OMX_VIDEO_MPEG4Level0; - m_sParamMPEG4.nSliceHeaderSpacing = 0; - m_sParamMPEG4.bSVH = OMX_FALSE; - m_sParamMPEG4.bGov = OMX_FALSE; - m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps - m_sParamMPEG4.bACPred = OMX_TRUE; - m_sParamMPEG4.nTimeIncRes = 30; // delta = 2 @ 15 fps - m_sParamMPEG4.nAllowedPictureTypes = 2; // pframe and iframe - m_sParamMPEG4.nHeaderExtension = 1; // number of video packet headers per vop - m_sParamMPEG4.bReversibleVLC = OMX_FALSE; - - // h263 specific init - OMX_INIT_STRUCT(&m_sParamH263, OMX_VIDEO_PARAM_H263TYPE); - m_sParamH263.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps - m_sParamH263.nBFrames = 0; - m_sParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline; - m_sParamH263.eLevel = OMX_VIDEO_H263Level10; - m_sParamH263.bPLUSPTYPEAllowed = OMX_FALSE; - m_sParamH263.nAllowedPictureTypes = 2; - m_sParamH263.bForceRoundingTypeToZero = OMX_TRUE; - m_sParamH263.nPictureHeaderRepetition = 0; - m_sParamH263.nGOBHeaderInterval = 1; - - // h264 specific init - OMX_INIT_STRUCT(&m_sParamAVC, OMX_VIDEO_PARAM_AVCTYPE); - m_sParamAVC.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamAVC.nSliceHeaderSpacing = 0; - m_sParamAVC.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1); // 2 second intra period for default outport fps - m_sParamAVC.nBFrames = 0; - m_sParamAVC.bUseHadamard = OMX_FALSE; - m_sParamAVC.nRefFrames = 1; - m_sParamAVC.nRefIdx10ActiveMinus1 = 1; - m_sParamAVC.nRefIdx11ActiveMinus1 = 0; - m_sParamAVC.bEnableUEP = OMX_FALSE; - m_sParamAVC.bEnableFMO = OMX_FALSE; - m_sParamAVC.bEnableASO = OMX_FALSE; - m_sParamAVC.bEnableRS = OMX_FALSE; - m_sParamAVC.eProfile = OMX_VIDEO_AVCProfileBaseline; - m_sParamAVC.eLevel = OMX_VIDEO_AVCLevel1; - m_sParamAVC.nAllowedPictureTypes = 2; - m_sParamAVC.bFrameMBsOnly = OMX_FALSE; - m_sParamAVC.bMBAFF = OMX_FALSE; - m_sParamAVC.bEntropyCodingCABAC = OMX_FALSE; - m_sParamAVC.bWeightedPPrediction = OMX_FALSE; - m_sParamAVC.nWeightedBipredicitonMode = 0; - m_sParamAVC.bconstIpred = OMX_FALSE; - m_sParamAVC.bDirect8x8Inference = OMX_FALSE; - m_sParamAVC.bDirectSpatialTemporal = OMX_FALSE; - m_sParamAVC.nCabacInitIdc = 0; - m_sParamAVC.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; - - OMX_INIT_STRUCT(&m_sParamLTRMode, QOMX_VIDEO_PARAM_LTRMODE_TYPE); - m_sParamLTRMode.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - m_sParamLTRMode.eLTRMode = QOMX_VIDEO_LTRMode_Disable; - - m_state = OMX_StateLoaded; - m_sExtraData = 0; - - if(eRet == OMX_ErrorNone) - { - if(pipe(fds)) - { - DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); - eRet = OMX_ErrorInsufficientResources; - } - else - { - if(fds[0] == 0 || fds[1] == 0) - { - if(pipe(fds)) - { - DEBUG_PRINT_ERROR("ERROR: pipe creation failed\n"); - eRet = OMX_ErrorInsufficientResources; - } - } - if(eRet == OMX_ErrorNone) - { - m_pipe_in = fds[0]; - m_pipe_out = fds[1]; - } - } - msg_thread_created = true; - r = pthread_create(&msg_thread_id,0, message_thread, this); - if(r < 0) - { - eRet = OMX_ErrorInsufficientResources; - msg_thread_created = false; - } - else - { - async_thread_created = true; - r = pthread_create(&async_thread_id,0, venc_dev::async_venc_message_thread, this); - if(r < 0) - { - eRet = OMX_ErrorInsufficientResources; - async_thread_created = false; - } else - dev_set_message_thread_id(async_thread_id); - } - } - - DEBUG_PRINT_HIGH("\n Component_init return value = 0x%x", eRet); - return eRet; -} - - -/* ====================================================================== -FUNCTION - omx_venc::Setparameter - -DESCRIPTION - OMX Set Parameter method implementation. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. - -========================================================================== */ -OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE paramIndex, - OMX_IN OMX_PTR paramData) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State\n"); - return OMX_ErrorInvalidState; - } - if(paramData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); - return OMX_ErrorBadParameter; - } - - /*set_parameter can be called in loaded state - or disabled port */ - if(m_state == OMX_StateLoaded - || m_sInPortDef.bEnabled == OMX_FALSE - || m_sOutPortDef.bEnabled == OMX_FALSE) - { - DEBUG_PRINT_LOW("Set Parameter called in valid state"); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - - switch(paramIndex) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n", - (int)portDefn->format.video.nFrameHeight, - (int)portDefn->format.video.nFrameWidth); - - if(PORT_INDEX_IN == portDefn->nPortIndex) - { - if (!dev_is_video_session_supported(portDefn->format.video.nFrameWidth, - portDefn->format.video.nFrameHeight)) { - DEBUG_PRINT_ERROR("video session not supported\n"); - omx_report_unsupported_setting(); - return OMX_ErrorUnsupportedSetting; - } - DEBUG_PRINT_LOW("\n i/p actual cnt requested = %d\n", portDefn->nBufferCountActual); - DEBUG_PRINT_LOW("\n i/p min cnt requested = %d\n", portDefn->nBufferCountMin); - DEBUG_PRINT_LOW("\n i/p buffersize requested = %d\n", portDefn->nBufferSize); - if(portDefn->nBufferCountMin > portDefn->nBufferCountActual) - { - DEBUG_PRINT_ERROR("\nERROR: (In_PORT) Min buffers (%d) > actual count (%d)\n", - portDefn->nBufferCountMin, portDefn->nBufferCountActual); - return OMX_ErrorUnsupportedSetting; - } - if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); - return OMX_ErrorUnsupportedSetting; - } - - DEBUG_PRINT_LOW("\n i/p previous actual cnt = %d\n", m_sInPortDef.nBufferCountActual); - DEBUG_PRINT_LOW("\n i/p previous min cnt = %d\n", m_sInPortDef.nBufferCountMin); - memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); - -#ifdef _ANDROID_ICS_ - if (portDefn->format.video.eColorFormat == (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { - m_sInPortDef.format.video.eColorFormat = - OMX_COLOR_FormatYUV420SemiPlanar; - if(!mUseProxyColorFormat){ - if (!c2d_conv.init()) { - DEBUG_PRINT_ERROR("\n C2D init failed"); - return OMX_ErrorUnsupportedSetting; - } - DEBUG_PRINT_ERROR("\nC2D init is successful"); - } - mUseProxyColorFormat = true; - m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ; - } else - mUseProxyColorFormat = false; -#endif - /*Query Input Buffer Requirements*/ - dev_get_buf_req (&m_sInPortDef.nBufferCountMin, - &m_sInPortDef.nBufferCountActual, - &m_sInPortDef.nBufferSize, - m_sInPortDef.nPortIndex); - - /*Query ouput Buffer Requirements*/ - dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual; - } - else if(PORT_INDEX_OUT == portDefn->nPortIndex) - { - DEBUG_PRINT_LOW("\n o/p actual cnt requested = %d\n", portDefn->nBufferCountActual); - DEBUG_PRINT_LOW("\n o/p min cnt requested = %d\n", portDefn->nBufferCountMin); - DEBUG_PRINT_LOW("\n o/p buffersize requested = %d\n", portDefn->nBufferSize); - if(portDefn->nBufferCountMin > portDefn->nBufferCountActual) - { - DEBUG_PRINT_ERROR("\nERROR: (Out_PORT) Min buffers (%d) > actual count (%d)\n", - portDefn->nBufferCountMin, portDefn->nBufferCountActual); - return OMX_ErrorUnsupportedSetting; - } - if(handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_set_param output failed"); - return OMX_ErrorUnsupportedSetting; - } -#ifdef _MSM8974_ - /*Query ouput Buffer Requirements*/ - dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); -#endif - memcpy(&m_sOutPortDef,portDefn,sizeof(struct OMX_PARAM_PORTDEFINITIONTYPE)); - update_profile_level(); //framerate , bitrate - - DEBUG_PRINT_LOW("\n o/p previous actual cnt = %d\n", m_sOutPortDef.nBufferCountActual); - DEBUG_PRINT_LOW("\n o/p previous min cnt = %d\n", m_sOutPortDef.nBufferCountMin); - m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Set_parameter: Bad Port idx %d", - (int)portDefn->nPortIndex); - eRet = OMX_ErrorBadPortIndex; - } - m_sConfigFramerate.xEncodeFramerate = portDefn->format.video.xFramerate; - m_sConfigBitrate.nEncodeBitrate = portDefn->format.video.nBitrate; - m_sParamBitrate.nTargetBitrate = portDefn->format.video.nBitrate; - } - break; - - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", - portFmt->eColorFormat); - //set the driver with the corresponding values - if(PORT_INDEX_IN == portFmt->nPortIndex) - { - if(handle->venc_set_param(paramData,OMX_IndexParamVideoPortFormat) != true) - { - return OMX_ErrorUnsupportedSetting; - } - - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n", - portFmt->eColorFormat); - update_profile_level(); //framerate - -#ifdef _ANDROID_ICS_ - if (portFmt->eColorFormat == - (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) { - m_sInPortFormat.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar; - if(!mUseProxyColorFormat){ - if (!c2d_conv.init()) { - DEBUG_PRINT_ERROR("\n C2D init failed"); - return OMX_ErrorUnsupportedSetting; - } - DEBUG_PRINT_ERROR("\nC2D init is successful"); - } - mUseProxyColorFormat = true; - m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ; - } - else -#endif - { - m_sInPortFormat.eColorFormat = portFmt->eColorFormat; - m_input_msg_id = OMX_COMPONENT_GENERATE_ETB; - mUseProxyColorFormat = false; - } - m_sInPortFormat.xFramerate = portFmt->xFramerate; - } - //TODO if no use case for O/P port,delet m_sOutPortFormat - } - break; - case OMX_IndexParamVideoInit: - { //TODO, do we need this index set param - OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData); - DEBUG_PRINT_LOW("\n Set OMX_IndexParamVideoInit called"); - break; - } - - case OMX_IndexParamVideoBitrate: - { - OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoBitrate"); - if(handle->venc_set_param(paramData,OMX_IndexParamVideoBitrate) != true) - { - return OMX_ErrorUnsupportedSetting; - } - m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate; - m_sParamBitrate.eControlRate = pParam->eControlRate; - update_profile_level(); //bitrate - m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate; - m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate; - m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate; - DEBUG_PRINT_LOW("\nbitrate = %u", m_sOutPortDef.format.video.nBitrate); - break; - } - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; - OMX_VIDEO_PARAM_MPEG4TYPE mp4_param; - memcpy(&mp4_param, pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4"); - if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { -#ifdef MAX_RES_1080P - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - mp4_param.nBFrames = 1; - } -#else - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - mp4_param.nBFrames = 0; - } -#endif - } - else - { - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - mp4_param.nBFrames = 0; - } - } - if(handle->venc_set_param(&mp4_param,OMX_IndexParamVideoMpeg4) != true) - { - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamMPEG4,pParam, sizeof(struct OMX_VIDEO_PARAM_MPEG4TYPE)); - m_sIntraperiod.nPFrames = m_sParamMPEG4.nPFrames; - m_sIntraperiod.nBFrames = m_sParamMPEG4.nBFrames; - break; - } - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263"); - if(handle->venc_set_param(paramData,OMX_IndexParamVideoH263) != true) - { - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamH263,pParam, sizeof(struct OMX_VIDEO_PARAM_H263TYPE)); - m_sIntraperiod.nPFrames = m_sParamH263.nPFrames; - m_sIntraperiod.nBFrames = m_sParamH263.nBFrames; - break; - } - case OMX_IndexParamVideoAvc: - { - OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; - OMX_VIDEO_PARAM_AVCTYPE avc_param; - memcpy(&avc_param, pParam, sizeof( struct OMX_VIDEO_PARAM_AVCTYPE)); - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc"); - - if((pParam->eProfile == OMX_VIDEO_AVCProfileHigh)|| - (pParam->eProfile == OMX_VIDEO_AVCProfileMain)) - { -#ifdef MAX_RES_1080P - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - avc_param.nBFrames = 1; - } - if(pParam->nRefFrames != 2) - { - DEBUG_PRINT_ERROR("Warning: 2 RefFrames are needed, changing RefFrames from %lu to 2", pParam->nRefFrames); - avc_param.nRefFrames = 2; - } -#else - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - avc_param.nBFrames = 0; - } - if(pParam->nRefFrames != 1) - { - DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %lu to 1)", pParam->nRefFrames); - avc_param.nRefFrames = 1; - } -#endif - } - else - { - if(pParam->nRefFrames != 1) - { - DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %lu to 1)", pParam->nRefFrames); - avc_param.nRefFrames = 1; - } - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - avc_param.nBFrames = 0; - } - } - if(handle->venc_set_param(&avc_param,OMX_IndexParamVideoAvc) != true) - { - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamAVC,pParam, sizeof(struct OMX_VIDEO_PARAM_AVCTYPE)); - m_sIntraperiod.nPFrames = m_sParamAVC.nPFrames; - m_sIntraperiod.nBFrames = m_sParamAVC.nBFrames; - break; - } - case OMX_IndexParamVideoProfileLevelCurrent: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent"); - if(handle->venc_set_param(pParam,OMX_IndexParamVideoProfileLevelCurrent) != true) - { - DEBUG_PRINT_ERROR("set_parameter: OMX_IndexParamVideoProfileLevelCurrent failed for Profile: %lu " - "Level :%lu", pParam->eProfile, pParam->eLevel); - return OMX_ErrorUnsupportedSetting; - } - m_sParamProfileLevel.eProfile = pParam->eProfile; - m_sParamProfileLevel.eLevel = pParam->eLevel; - - if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile; - m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel; - DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, - m_sParamMPEG4.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile; - m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel; - DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, - m_sParamH263.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)m_sParamProfileLevel.eProfile; - m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)m_sParamProfileLevel.eLevel; - DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, - m_sParamAVC.eLevel); - } - break; - } - case OMX_IndexParamStandardComponentRole: - { - OMX_PARAM_COMPONENTROLETYPE *comp_role; - comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n", - comp_role->cRole); - - if((m_state == OMX_StateLoaded)&& - !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) - { - DEBUG_PRINT_LOW("Set Parameter called in valid state"); - } - else - { - DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - - if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((char*)comp_role->cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet = OMX_ErrorUnsupportedSetting; - } - } - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } -#ifdef _MSM8974_ - else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - if(!strncmp((const char*)comp_role->cRole,"video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) - { - strlcpy((char*)m_cRole,"video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); - } - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s\n", comp_role->cRole); - eRet =OMX_ErrorUnsupportedSetting; - } - } -#endif - else - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s\n", m_nkind); - eRet = OMX_ErrorInvalidComponentName; - } - break; - } - - case OMX_IndexParamPriorityMgmt: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt"); - if(m_state != OMX_StateLoaded) - { - DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State\n"); - return OMX_ErrorIncorrectStateOperation; - } - OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n", - priorityMgmtype->nGroupID); - - DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n", - priorityMgmtype->nGroupPriority); - - m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID; - m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority; - - break; - } - - case OMX_IndexParamCompBufferSupplier: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier"); - OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n", - bufferSupplierType->eBufferSupplier); - if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1) - m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier; - - else - - eRet = OMX_ErrorBadPortIndex; - - break; - - } - case OMX_IndexParamVideoQuantization: - { - DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization\n"); - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; - if(session_qp->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_param(paramData, OMX_IndexParamVideoQuantization) != true) - { - return OMX_ErrorUnsupportedSetting; - } - m_sSessionQuantization.nQpI = session_qp->nQpI; - m_sSessionQuantization.nQpP = session_qp->nQpP; - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for Session QP setting\n"); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - - case OMX_QcomIndexParamVideoQPRange: - { - DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoQPRange\n"); - OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData; - if(qp_range->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_param(paramData, - (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPRange) != true) - { - return OMX_ErrorUnsupportedSetting; - } - m_sSessionQPRange.minQP= qp_range->minQP; - m_sSessionQPRange.maxQP= qp_range->maxQP; - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Unsupported port Index for QP range setting\n"); - eRet = OMX_ErrorBadPortIndex; - } - break; - } - - case OMX_QcomIndexPortDefn: - { - OMX_QCOM_PARAM_PORTDEFINITIONTYPE* pParam = - (OMX_QCOM_PARAM_PORTDEFINITIONTYPE*)paramData; - DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexPortDefn"); - if(pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) - { - if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && - pParam->nMemRegion < OMX_QCOM_MemRegionMax) - { - m_use_input_pmem = OMX_TRUE; - } - else - { - m_use_input_pmem = OMX_FALSE; - } - } - else if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(pParam->nMemRegion > OMX_QCOM_MemRegionInvalid && - pParam->nMemRegion < OMX_QCOM_MemRegionMax) - { - m_use_output_pmem = OMX_TRUE; - } - else - { - m_use_output_pmem = OMX_FALSE; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: SetParameter called on unsupported Port Index for QcomPortDefn"); - return OMX_ErrorBadPortIndex; - } - break; - } - - case OMX_IndexParamVideoErrorCorrection: - { - DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam = - (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; - if(!handle->venc_set_param(paramData, OMX_IndexParamVideoErrorCorrection)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Error Resilience failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection)); - break; - } - case OMX_IndexParamVideoIntraRefresh: - { - DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh\n"); - OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam = - (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; - if(!handle->venc_set_param(paramData,OMX_IndexParamVideoIntraRefresh)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra refresh failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh)); - break; - } -#ifdef _ANDROID_ICS_ - case OMX_QcomIndexParamVideoEncodeMetaBufferMode: - { - StoreMetaDataInBuffersParams *pParam = - (StoreMetaDataInBuffersParams*)paramData; - DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoEncodeMetaBufferMode: " - "port_index = %lu, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData); - if(pParam->nPortIndex == PORT_INDEX_IN) - { - if(pParam->bStoreMetaData != meta_mode_enable) - { - if(!handle->venc_set_meta_mode(pParam->bStoreMetaData)) - { - DEBUG_PRINT_ERROR("\nERROR: set Metabuffer mode %d fail", - pParam->bStoreMetaData); - return OMX_ErrorUnsupportedSetting; - } - meta_mode_enable = pParam->bStoreMetaData; - if(meta_mode_enable) { - m_sInPortDef.nBufferCountActual = 4; - if(handle->venc_set_param(&m_sInPortDef,OMX_IndexParamPortDefinition) != true) - { - DEBUG_PRINT_ERROR("\nERROR: venc_set_param input failed"); - return OMX_ErrorUnsupportedSetting; - } - } else { - /*TODO: reset encoder driver Meta mode*/ - dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - } - } - } - else - { - DEBUG_PRINT_ERROR("set_parameter: metamode is " - "valid for input port only"); - eRet = OMX_ErrorUnsupportedIndex; - } - } - break; -#endif -#if !defined(MAX_RES_720P) || defined(_MSM8974_) - case OMX_QcomIndexParamIndexExtraDataType: - { - DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType"); - QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; - if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) - { - if (pParam->nPortIndex == PORT_INDEX_OUT) - { - if (pParam->bEnabled == OMX_TRUE) - m_sExtraData |= VEN_EXTRADATA_SLICEINFO; - else - m_sExtraData &= ~VEN_EXTRADATA_SLICEINFO; - DEBUG_PRINT_HIGH("SliceInfo extradata %s", - ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled")); - if(handle->venc_set_param(&m_sExtraData, - (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting " - "OMX_ExtraDataVideoEncoderSliceInfo failed"); - return OMX_ErrorUnsupportedSetting; - } - else - { - m_sOutPortDef.nPortIndex = PORT_INDEX_OUT; - dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%lu, " - "count min=%lu, buffer size=%lu", - m_sOutPortDef.nBufferCountActual, - m_sOutPortDef.nBufferCountMin, - m_sOutPortDef.nBufferSize); - } - } - } -#ifndef _MSM8974_ - else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) - { - if (pParam->nPortIndex == PORT_INDEX_OUT) - { - if (pParam->bEnabled == OMX_TRUE) - m_sExtraData |= VEN_EXTRADATA_LTRINFO; - else - m_sExtraData &= ~VEN_EXTRADATA_LTRINFO; - DEBUG_PRINT_HIGH("LTRInfo extradata %s", - ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled")); - if(handle->venc_set_param(&m_sExtraData, - (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting " - "OMX_ExtraDataVideoLTRInfo failed"); - return OMX_ErrorUnsupportedSetting; - } - else - { - m_sOutPortDef.nPortIndex = PORT_INDEX_OUT; - dev_get_buf_req(&m_sOutPortDef.nBufferCountMin, - &m_sOutPortDef.nBufferCountActual, - &m_sOutPortDef.nBufferSize, - m_sOutPortDef.nPortIndex); - DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%d, " - "count min=%d, buffer size=%d", - m_sOutPortDef.nBufferCountActual, - m_sOutPortDef.nBufferCountMin, - m_sOutPortDef.nBufferSize); - } - } - else - { - DEBUG_PRINT_ERROR("set_parameter: LTR information is " - "valid for output port only"); - eRet = OMX_ErrorUnsupportedIndex; - } - } -#endif - else - { - DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)", - pParam->nIndex); - eRet = OMX_ErrorUnsupportedIndex; - } - break; - } - case QOMX_IndexParamVideoLTRMode: - { - QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam = - (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData; - if(!handle->venc_set_param(paramData, (OMX_INDEXTYPE)QOMX_IndexParamVideoLTRMode)) - { - DEBUG_PRINT_ERROR("\nERROR: Setting LTR mode failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamLTRMode, pParam, sizeof(m_sParamLTRMode)); - break; - } - case QOMX_IndexParamVideoLTRCount: - { - QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam = - (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData; - if(!handle->venc_set_param(paramData, (OMX_INDEXTYPE)QOMX_IndexParamVideoLTRCount)) - { - DEBUG_PRINT_ERROR("\nERROR: Setting LTR count failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sParamLTRCount, pParam, sizeof(m_sParamLTRCount)); - break; - } -#endif - case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - handle->m_max_allowed_bitrate_check = - ((pParam->bEnable == OMX_TRUE) ? true : false); - DEBUG_PRINT_HIGH("set_parameter: max allowed bitrate check %s", - ((pParam->bEnable == OMX_TRUE) ? "enabled" : "disabled")); - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexParamVideoMaxAllowedBitrateCheck " - " called on wrong port(%lu)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } -#ifdef MAX_RES_1080P - case OMX_QcomIndexEnableSliceDeliveryMode: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(!handle->venc_set_param(paramData, - (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) - { - DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableSliceDeliveryMode " - "called on wrong port(%lu)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } -#endif - case OMX_QcomIndexEnableH263PlusPType: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType"); - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(!handle->venc_set_param(paramData, - (OMX_INDEXTYPE)OMX_QcomIndexEnableH263PlusPType)) - { - DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableH263PlusPType " - "called on wrong port(%lu)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case OMX_IndexParamVideoSliceFMO: - default: - { - DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d\n", paramIndex); - eRet = OMX_ErrorUnsupportedIndex; - break; - } - } - return eRet; -} - -bool omx_venc::update_profile_level() -{ - OMX_U32 eProfile, eLevel; - - if(!handle->venc_get_profile_level(&eProfile,&eLevel)) - { - DEBUG_PRINT_ERROR("\nFailed to update the profile_level\n"); - return false; - } - - m_sParamProfileLevel.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; - m_sParamProfileLevel.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; - - if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.mpeg4",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)eProfile; - m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)eLevel; - DEBUG_PRINT_LOW("\n MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile, - m_sParamMPEG4.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile; - m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel; - DEBUG_PRINT_LOW("\n H263 profile = %d, level = %d", m_sParamH263.eProfile, - m_sParamH263.eLevel); - } - else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ - OMX_MAX_STRINGNAME_SIZE)) - { - m_sParamAVC.eProfile = (OMX_VIDEO_AVCPROFILETYPE)eProfile; - m_sParamAVC.eLevel = (OMX_VIDEO_AVCLEVELTYPE)eLevel; - DEBUG_PRINT_LOW("\n AVC profile = %d, level = %d", m_sParamAVC.eProfile, - m_sParamAVC.eLevel); - } - return true; -} -/* ====================================================================== -FUNCTION - omx_video::SetConfig - -DESCRIPTION - OMX Set Config method implementation - -PARAMETERS - . - -RETURN VALUE - OMX Error None if successful. -========================================================================== */ -OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp, - OMX_IN OMX_INDEXTYPE configIndex, - OMX_IN OMX_PTR configData) -{ - if(configData == NULL) - { - DEBUG_PRINT_ERROR("ERROR: param is null"); - return OMX_ErrorBadParameter; - } - - if(m_state == OMX_StateInvalid) - { - DEBUG_PRINT_ERROR("ERROR: config called in Invalid state"); - return OMX_ErrorIncorrectStateOperation; - } - - // params will be validated prior to venc_init - switch(configIndex) - { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE* pParam = - reinterpret_cast(configData); - DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%lu)", pParam->nEncodeBitrate); - - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_config(configData, OMX_IndexConfigVideoBitrate) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoBitrate failed"); - return OMX_ErrorUnsupportedSetting; - } - - m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate; - m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate; - m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE* pParam = - reinterpret_cast(configData); - DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%lx)", pParam->xEncodeFramerate); - - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_config(configData, OMX_IndexConfigVideoFramerate) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoFramerate failed"); - return OMX_ErrorUnsupportedSetting; - } - - m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate; - m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate; - m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - - break; - } - case QOMX_IndexConfigVideoIntraperiod: - { - QOMX_VIDEO_INTRAPERIODTYPE* pParam = - reinterpret_cast(configData); - - DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod"); - if(pParam->nPortIndex == PORT_INDEX_OUT) - { -#ifdef MAX_RES_720P - if(pParam->nBFrames > 0) - { - DEBUG_PRINT_ERROR("B frames not supported\n"); - return OMX_ErrorUnsupportedSetting; - } -#endif - DEBUG_PRINT_HIGH("Old: P/B frames = %lu/%lu, New: P/B frames = %lu/%lu", - m_sIntraperiod.nPFrames, m_sIntraperiod.nBFrames, - pParam->nPFrames, pParam->nBFrames); - if (m_sIntraperiod.nBFrames != pParam->nBFrames) - { - DEBUG_PRINT_HIGH("Dynamically changing B-frames not supported"); - return OMX_ErrorUnsupportedSetting; - } - if(handle->venc_set_config(configData, (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting QOMX_IndexConfigVideoIntraperiod failed"); - return OMX_ErrorUnsupportedSetting; - } - m_sIntraperiod.nPFrames = pParam->nPFrames; - m_sIntraperiod.nBFrames = pParam->nBFrames; - m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod; - - if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingMPEG4) - { - m_sParamMPEG4.nPFrames = pParam->nPFrames; - if(m_sParamMPEG4.eProfile != OMX_VIDEO_MPEG4ProfileSimple) - m_sParamMPEG4.nBFrames = pParam->nBFrames; - else - m_sParamMPEG4.nBFrames = 0; - } - else if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingH263) - { - m_sParamH263.nPFrames = pParam->nPFrames; - } - else - { - m_sParamAVC.nPFrames = pParam->nPFrames; - if(m_sParamAVC.eProfile != OMX_VIDEO_AVCProfileBaseline) - m_sParamAVC.nBFrames = pParam->nBFrames; - else - m_sParamAVC.nBFrames = 0; - } - } - else - { - DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %lu", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - - break; - } - - case OMX_IndexConfigVideoIntraVOPRefresh: - { - OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam = - reinterpret_cast(configData); - - DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh"); - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(handle->venc_set_config(configData, - OMX_IndexConfigVideoIntraVOPRefresh) != true) - { - DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoIntraVOPRefresh failed"); - return OMX_ErrorUnsupportedSetting; - } - - m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP; - } - else - { - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - - break; - } - case OMX_IndexConfigCommonRotate: - { - OMX_CONFIG_ROTATIONTYPE *pParam = - reinterpret_cast(configData); - OMX_S32 nRotation; - - if(pParam->nPortIndex != PORT_INDEX_IN){ - DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %lu", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - if( pParam->nRotation == 0 || - pParam->nRotation == 90 || - pParam->nRotation == 180 || - pParam->nRotation == 270 ) { - DEBUG_PRINT_HIGH("\nset_config: Rotation Angle %lu", pParam->nRotation); - } else { - DEBUG_PRINT_ERROR("ERROR: un supported Rotation %lu", pParam->nRotation); - return OMX_ErrorUnsupportedSetting; - } - nRotation = pParam->nRotation - m_sConfigFrameRotation.nRotation; - if(nRotation < 0) - nRotation = -nRotation; - if(nRotation == 90 || nRotation == 270) { - DEBUG_PRINT_HIGH("\nset_config: updating device Dims"); - if(handle->venc_set_config(configData, - OMX_IndexConfigCommonRotate) != true) { - DEBUG_PRINT_ERROR("ERROR: Set OMX_IndexConfigCommonRotate failed"); - return OMX_ErrorUnsupportedSetting; - } else { - OMX_U32 nFrameWidth; - - DEBUG_PRINT_HIGH("\nset_config: updating port Dims"); - - nFrameWidth = m_sInPortDef.format.video.nFrameWidth; - m_sInPortDef.format.video.nFrameWidth = - m_sInPortDef.format.video.nFrameHeight; - m_sInPortDef.format.video.nFrameHeight = nFrameWidth; - - m_sOutPortDef.format.video.nFrameWidth = - m_sInPortDef.format.video.nFrameWidth; - m_sOutPortDef.format.video.nFrameHeight = - m_sInPortDef.format.video.nFrameHeight; - m_sConfigFrameRotation.nRotation = pParam->nRotation; - } - } else { - m_sConfigFrameRotation.nRotation = pParam->nRotation; - } - break; - } - case OMX_QcomIndexConfigVideoFramePackingArrangement: - { - DEBUG_PRINT_HIGH("set_config(): OMX_QcomIndexConfigVideoFramePackingArrangement"); - if(m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingAVC) - { - OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt = - (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData; - extra_data_handle.set_frame_pack_data(configFmt); - } - else - { - DEBUG_PRINT_ERROR("ERROR: FramePackingData not supported for non AVC compression"); - } - break; - } - case QOMX_IndexConfigVideoLTRPeriod: - { - QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData; - if(!handle->venc_set_config(configData, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRPeriod)) - { - DEBUG_PRINT_ERROR("\nERROR: Setting LTR period failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sConfigLTRPeriod, pParam, sizeof(m_sConfigLTRPeriod)); - break; - } - case QOMX_IndexConfigVideoLTRUse: - { - QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData; - if(!handle->venc_set_config(configData, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRUse)) - { - DEBUG_PRINT_ERROR("\nERROR: Setting LTR use failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sConfigLTRUse, pParam, sizeof(m_sConfigLTRUse)); - break; - } - case QOMX_IndexConfigVideoLTRMark: - { - QOMX_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRMARK_TYPE*)configData; - DEBUG_PRINT_ERROR("Setting ltr mark is not supported"); - return OMX_ErrorUnsupportedSetting; - break; - } - case OMX_IndexConfigVideoAVCIntraPeriod: - { - OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData; - DEBUG_PRINT_LOW("set_config: OMX_IndexConfigVideoAVCIntraPeriod"); - if(!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_IndexConfigVideoAVCIntraPeriod)) - { - DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigVideoAVCIntraPeriod failed"); - return OMX_ErrorUnsupportedSetting; - } - memcpy(&m_sConfigAVCIDRPeriod, pParam, sizeof(m_sConfigAVCIDRPeriod)); - break; - } - default: - DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); - break; - } - - return OMX_ErrorNone; -} - -/* ====================================================================== -FUNCTION - omx_venc::ComponentDeInit - -DESCRIPTION - Destroys the component and release memory allocated to the heap. - -PARAMETERS - . - -RETURN VALUE - OMX Error None if everything successful. - -========================================================================== */ -OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp) -{ - OMX_U32 i = 0; - DEBUG_PRINT_HIGH("\n omx_venc(): Inside component_deinit()"); - if(OMX_StateLoaded != m_state) - { - DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\ - m_state); - } - if(m_out_mem_ptr) - { - DEBUG_PRINT_LOW("Freeing the Output Memory\n"); - for(i=0; i< m_sOutPortDef.nBufferCountActual; i++ ) - { - free_output_buffer (&m_out_mem_ptr[i]); - } - free(m_out_mem_ptr); - m_out_mem_ptr = NULL; - } - - /*Check if the input buffers have to be cleaned up*/ - if(m_inp_mem_ptr -#ifdef _ANDROID_ICS_ - && !meta_mode_enable -#endif - ) - { - DEBUG_PRINT_LOW("Freeing the Input Memory\n"); - for(i=0; ivenc_close(); - DEBUG_PRINT_HIGH("Deleting HANDLE[%p]\n", handle); - delete (handle); - DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit\n"); - return OMX_ErrorNone; -} - - -OMX_U32 omx_venc::dev_stop( void) -{ - return handle->venc_stop(); -} - - -OMX_U32 omx_venc::dev_pause(void) -{ - return handle->venc_pause(); -} - -OMX_U32 omx_venc::dev_start(void) -{ - return handle->venc_start(); -} - -OMX_U32 omx_venc::dev_flush(unsigned port) -{ - return handle->venc_flush(port); -} -OMX_U32 omx_venc::dev_resume(void) -{ - return handle->venc_resume(); -} - -OMX_U32 omx_venc::dev_start_done(void) -{ - return handle->venc_start_done(); -} - -OMX_U32 omx_venc::dev_set_message_thread_id(pthread_t tid) -{ - return handle->venc_set_message_thread_id(tid); -} - -bool omx_venc::dev_use_buf(void *buf_addr,unsigned port,unsigned index) -{ - return handle->venc_use_buf(buf_addr,port,index); -} - -bool omx_venc::dev_free_buf(void *buf_addr,unsigned port) -{ - return handle->venc_free_buf(buf_addr,port); -} - -bool omx_venc::dev_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) -{ - return handle->venc_empty_buf(buffer, pmem_data_buf,index,fd); -} - -bool omx_venc::dev_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) -{ - return handle->venc_fill_buf(buffer, pmem_data_buf,index,fd); -} - -bool omx_venc::dev_get_seq_hdr(void *buffer, unsigned size, unsigned *hdrlen) -{ - return handle->venc_get_seq_hdr(buffer, size, hdrlen); -} - -bool omx_venc::dev_get_capability_ltrcount(OMX_U32 *min, OMX_U32 *max, OMX_U32 *step_size) -{ -#ifdef _MSM8974_ - DEBUG_PRINT_ERROR("Get Capability LTR Count is not supported"); - return false; -#else - return handle->venc_get_capability_ltrcount(min, max, step_size); -#endif -} - -bool omx_venc::dev_loaded_start() -{ - return handle->venc_loaded_start(); -} - -bool omx_venc::dev_loaded_stop() -{ - return handle->venc_loaded_stop(); -} - -bool omx_venc::dev_loaded_start_done() -{ - return handle->venc_loaded_start_done(); -} - -bool omx_venc::dev_loaded_stop_done() -{ - return handle->venc_loaded_stop_done(); -} - -bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count, - OMX_U32 *actual_buff_count, - OMX_U32 *buff_size, - OMX_U32 port) -{ - return handle->venc_get_buf_req(min_buff_count, - actual_buff_count, - buff_size, - port); - -} - -bool omx_venc::dev_set_buf_req(OMX_U32 *min_buff_count, - OMX_U32 *actual_buff_count, - OMX_U32 *buff_size, - OMX_U32 port) -{ - return handle->venc_set_buf_req(min_buff_count, - actual_buff_count, - buff_size, - port); - -} - -bool omx_venc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height) -{ -#ifdef _MSM8974_ - return handle->venc_is_video_session_supported(width,height); -#else - DEBUG_PRINT_LOW("Check against video capability not supported"); - return true; -#endif -} - -#ifdef _MSM8974_ -int omx_venc::dev_handle_extradata(void *buffer, int index) -{ - return handle->handle_extradata(buffer, index); -} - -int omx_venc::dev_set_format(int color) -{ - return handle->venc_set_format(color); -} -#endif - -int omx_venc::async_message_process (void *context, void* message) -{ - omx_video* omx = NULL; - struct venc_msg *m_sVenc_msg = NULL; - OMX_BUFFERHEADERTYPE* omxhdr = NULL; - struct venc_buffer *temp_buff = NULL; - - if(context == NULL || message == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: omx_venc::async_message_process invalid i/p params"); - return -1; - } - m_sVenc_msg = (struct venc_msg *)message; - - omx = reinterpret_cast(context); - - if(m_sVenc_msg->statuscode != VEN_S_SUCCESS) - { - DEBUG_PRINT_ERROR("\nERROR: async_msg_process() - Error statuscode = %lu\n", - m_sVenc_msg->statuscode); - omx->omx_report_error(); - } - - DEBUG_PRINT_LOW("\n omx_venc::async_message_process- msgcode = %d\n", - m_sVenc_msg->msgcode); - switch(m_sVenc_msg->msgcode) - { - case VEN_MSG_START: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_START_DONE); - break; - case VEN_MSG_STOP: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_STOP_DONE); - break; - case VEN_MSG_RESUME: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_RESUME_DONE); - break; - case VEN_MSG_PAUSE: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_PAUSE_DONE); - break; - case VEN_MSG_FLUSH_INPUT_DONE: - - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH); - break; - case VEN_MSG_FLUSH_OUPUT_DONE: - omx->post_event (NULL,m_sVenc_msg->statuscode,\ - OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH); - break; - case VEN_MSG_INPUT_BUFFER_DONE: - omxhdr = (OMX_BUFFERHEADERTYPE* )\ - m_sVenc_msg->buf.clientdata; - - if(omxhdr == NULL || - (((OMX_U32)(omxhdr - omx->m_inp_mem_ptr) > omx->m_sInPortDef.nBufferCountActual) && - ((OMX_U32)(omxhdr - omx->meta_buffer_hdr) > omx->m_sInPortDef.nBufferCountActual))) - { - omxhdr = NULL; - m_sVenc_msg->statuscode = VEN_S_EFAIL; - } - -#ifdef _ANDROID_ICS_ - omx->omx_release_meta_buffer(omxhdr); -#endif - omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, - OMX_COMPONENT_GENERATE_EBD); - break; - case VEN_MSG_OUTPUT_BUFFER_DONE: - omxhdr = (OMX_BUFFERHEADERTYPE*)m_sVenc_msg->buf.clientdata; - - if( (omxhdr != NULL) && - ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual)) - { - if(m_sVenc_msg->buf.len <= omxhdr->nAllocLen) - { - omxhdr->nFilledLen = m_sVenc_msg->buf.len; - omxhdr->nOffset = m_sVenc_msg->buf.offset; - omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp; - DEBUG_PRINT_LOW("\n o/p TS = %u", (OMX_U32)m_sVenc_msg->buf.timestamp); - omxhdr->nFlags = m_sVenc_msg->buf.flags; - - /*Use buffer case*/ - if(omx->output_use_buffer && !omx->m_use_output_pmem) - { - DEBUG_PRINT_LOW("\n memcpy() for o/p Heap UseBuffer"); - memcpy(omxhdr->pBuffer, - (m_sVenc_msg->buf.ptrbuffer), - m_sVenc_msg->buf.len); - } - } - else - { - omxhdr->nFilledLen = 0; - } - - } - else - { - omxhdr = NULL; - m_sVenc_msg->statuscode = VEN_S_EFAIL; - } - omx->post_event ((unsigned int)omxhdr,m_sVenc_msg->statuscode, - OMX_COMPONENT_GENERATE_FBD); - break; - case VEN_MSG_NEED_OUTPUT_BUFFER: - //TBD what action needs to be done here?? - break; -#ifndef _MSM8974_ - case VEN_MSG_LTRUSE_FAILED: - DEBUG_PRINT_ERROR("LTRUSE Failed!"); - omx->post_event (NULL,m_sVenc_msg->statuscode, - OMX_COMPONENT_GENERATE_LTRUSE_FAILED); - break; -#endif - default: - break; - } - return 0; -} diff --git a/mm-video/vidc/venc/src/video_encoder_device.cpp b/mm-video/vidc/venc/src/video_encoder_device.cpp deleted file mode 100644 index 7b56d33a..00000000 --- a/mm-video/vidc/venc/src/video_encoder_device.cpp +++ /dev/null @@ -1,3235 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2012, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include "video_encoder_device.h" -#include "omx_video_encoder.h" -#include -#ifdef USE_ION -#include -#endif - -#define MPEG4_SP_START 0 -#define MPEG4_ASP_START (MPEG4_SP_START + 8) -#define MPEG4_720P_LEVEL 6 -#define H263_BP_START 0 -#define H264_BP_START 0 -#define H264_HP_START (H264_BP_START + 13) -#define H264_MP_START (H264_BP_START + 26) - -/* MPEG4 profile and level table*/ -static const unsigned int mpeg4_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, - {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, - {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, - {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, - {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, - {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {0,0,0,0,0}, - - {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {0,0,0,0,0}, -}; - -/* H264 profile and level table*/ -static const unsigned int h264_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, - {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, - {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, - {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, - {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, - {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, - {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, - {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, - {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, - {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, - {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, - {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, - {0,0,0,0,0}, - - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, - {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, - {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, - {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, - {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, - {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, - {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, - {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, - {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, - {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, - {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, - {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, - {0,0,0,0,0}, - - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, - {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, - {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, - {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, - {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, - {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, - {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, - {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, - {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, - {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, - {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, - {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, - {0,0,0,0,0} - -}; - -/* H263 profile and level table*/ -static const unsigned int h263_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, - {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, - {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, - {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, - {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, - {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, - {0,0,0,0,0} -}; - -#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } -#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } - -#ifdef INPUT_BUFFER_LOG -FILE *inputBufferFile1; -char inputfilename [] = "/data/input.yuv"; -#endif -#ifdef OUTPUT_BUFFER_LOG -FILE *outputBufferFile1; -char outputfilename [] = "/data/output-bitstream.\0\0\0\0"; -#endif -//constructor -venc_dev::venc_dev(class omx_venc *venc_class) -{ - m_max_allowed_bitrate_check = false; - m_eLevel = 0; - m_eProfile = 0; - pthread_mutex_init(&loaded_start_stop_mlock, NULL); - pthread_cond_init (&loaded_start_stop_cond, NULL); - DEBUG_PRINT_LOW("venc_dev constructor"); -} - -venc_dev::~venc_dev() -{ - pthread_cond_destroy(&loaded_start_stop_cond); - pthread_mutex_destroy(&loaded_start_stop_mlock); - DEBUG_PRINT_LOW("venc_dev distructor"); -} - -void* async_venc_message_thread (void *input) -{ - struct venc_ioctl_msg ioctl_msg ={NULL,NULL}; - struct venc_timeout timeout; - struct venc_msg venc_msg; - int error_code = 0; - omx_venc *omx = reinterpret_cast(input); - - prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); - timeout.millisec = VEN_TIMEOUT_INFINITE; - while(1) - { - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&venc_msg; - - /*Wait for a message from the video decoder driver*/ - error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg); - if (error_code == -512) // ERESTARTSYS - { - DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!"); - } - else if (error_code <0) - { - DEBUG_PRINT_LOW("\nioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed"); - break; - } - else if(omx->async_message_process(input,&venc_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); - break; - } - } - DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n"); - return NULL; -} - -bool venc_dev::venc_open(OMX_U32 codec) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - int r; - unsigned int alignment = 0,buffer_size = 0, temp =0; - - m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); - if(m_nDriver_fd == 0) - { - DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n"); - m_nDriver_fd = open ("/dev/msm_vidc_enc",O_RDWR|O_NONBLOCK); - } - - if((int)m_nDriver_fd < 0) - { - DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n"); - return false; - } - - DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd); -#ifdef SINGLE_ENCODER_INSTANCE - OMX_U32 num_instances = 0; - ioctl_msg.in = NULL; - ioctl_msg.out = &num_instances; - if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_NUMBER_INSTANCES, (void*)&ioctl_msg) < 0 ) - { - DEBUG_PRINT_ERROR("\nERROR: Request number of encoder instances failed"); - } - else if (num_instances > 1) - { - DEBUG_PRINT_ERROR("\nSecond encoder instance rejected!"); - venc_close(); - return false; - } -#endif - // set the basic configuration of the video encoder driver - m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; - m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; - m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; - m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; - m_sVenc_cfg.fps_num = 30; - m_sVenc_cfg.fps_den = 1; - m_sVenc_cfg.targetbitrate = 64000; -#ifdef MAX_RES_1080P - m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; -#else - m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12; -#endif -// initializing QP range parameters - qp_range.minqp = 2; - if(codec == OMX_VIDEO_CodingAVC) - qp_range.maxqp = 51; - else - qp_range.maxqp = 31; - - if(codec == OMX_VIDEO_CodingMPEG4) - { - m_sVenc_cfg.codectype = VEN_CODEC_MPEG4; - codec_profile.profile = VEN_PROFILE_MPEG4_SP; - profile_level.level = VEN_LEVEL_MPEG4_2; -#ifdef OUTPUT_BUFFER_LOG - strcat(outputfilename, "m4v"); -#endif - } - else if(codec == OMX_VIDEO_CodingH263) - { - m_sVenc_cfg.codectype = VEN_CODEC_H263; - codec_profile.profile = VEN_PROFILE_H263_BASELINE; - profile_level.level = VEN_LEVEL_H263_20; -#ifdef OUTPUT_BUFFER_LOG - strcat(outputfilename, "263"); -#endif - } - if(codec == OMX_VIDEO_CodingAVC) - { - m_sVenc_cfg.codectype = VEN_CODEC_H264; - codec_profile.profile = VEN_PROFILE_H264_BASELINE; - profile_level.level = VEN_LEVEL_H264_1p1; -#ifdef OUTPUT_BUFFER_LOG - strcat(outputfilename, "264"); -#endif - } - ioctl_msg.in = (void*)&m_sVenc_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0 ) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting base configuration failed"); - return false; - } -#ifdef INPUT_BUFFER_LOG - inputBufferFile1 = fopen (inputfilename, "ab"); -#endif -#ifdef OUTPUT_BUFFER_LOG - outputBufferFile1 = fopen (outputfilename, "ab"); -#endif - // Get the I/P and O/P buffer requirements - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&m_sInput_buff_property; - if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed"); - return false; - } - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&m_sOutput_buff_property; - if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed"); - return false; - } - - m_profile_set = false; - m_level_set = false; - if(venc_set_profile_level(0, 0)) - { - DEBUG_PRINT_HIGH("\n %s(): Init Profile/Level setting success", - __func__); - } - recon_buffers_count = MAX_RECON_BUFFERS; - ltrmode.ltr_mode = 0; - ltrcount.ltr_count = 0; - ltrperiod.ltr_period = 0; - - return true; -} - -void venc_dev::venc_close() -{ - DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd); - if((int)m_nDriver_fd >= 0) - { - DEBUG_PRINT_HIGH("\n venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG"); - (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG, - NULL); - DEBUG_PRINT_LOW("\nCalling close()\n"); - close(m_nDriver_fd); - m_nDriver_fd = -1; - } -#ifdef INPUT_BUFFER_LOG - fclose (inputBufferFile1); -#endif -#ifdef OUTPUT_BUFFER_LOG - fclose (outputBufferFile1); -#endif -} - -bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count, - unsigned long *actual_buff_count, - unsigned long *buff_size, - unsigned long port) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - unsigned long temp_count = 0; - - if(port == 0) - { - if(*actual_buff_count > m_sInput_buff_property.mincount) - { - temp_count = m_sInput_buff_property.actualcount; - m_sInput_buff_property.actualcount = *actual_buff_count; - ioctl_msg.in = (void*)&m_sInput_buff_property; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirement failed"); - m_sInput_buff_property.actualcount = temp_count; - return false; - } - DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count); - } - } - else - { - if(*actual_buff_count > m_sOutput_buff_property.mincount) - { - temp_count = m_sOutput_buff_property.actualcount; - m_sOutput_buff_property.actualcount = *actual_buff_count; - ioctl_msg.in = (void*)&m_sOutput_buff_property; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer requirement failed"); - m_sOutput_buff_property.actualcount = temp_count; - return false; - } - DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count); - } - } - - return true; - -} - -bool venc_dev::venc_loaded_start() -{ - struct timespec ts; - int status = 0; - if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_START, NULL) < 0) - { - DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_START failed"); - return false; - } - if (clock_gettime(CLOCK_REALTIME, &ts) < 0) - { - DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__); - return false; - } - ts.tv_sec += 1; - pthread_mutex_lock(&loaded_start_stop_mlock); - DEBUG_PRINT_LOW("%s: wait on start done", __func__); - status = pthread_cond_timedwait(&loaded_start_stop_cond, - &loaded_start_stop_mlock, &ts); - if (status != 0) - { - DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__, - status, strerror(status)); - pthread_mutex_unlock(&loaded_start_stop_mlock); - return false; - } - DEBUG_PRINT_LOW("%s: wait over on start done", __func__); - pthread_mutex_unlock(&loaded_start_stop_mlock); - DEBUG_PRINT_LOW("%s: venc_loaded_start success", __func__); - return true; -} - -bool venc_dev::venc_loaded_stop() -{ - struct timespec ts; - int status = 0; - if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_STOP, NULL) < 0) - { - DEBUG_PRINT_ERROR("ERROR: VEN_IOCTL_CMD_STOP failed"); - return false; - } - if (clock_gettime(CLOCK_REALTIME, &ts) < 0) - { - DEBUG_PRINT_ERROR("%s: clock_gettime failed", __func__); - return false; - } - ts.tv_sec += 1; - pthread_mutex_lock(&loaded_start_stop_mlock); - DEBUG_PRINT_LOW("%s: wait on stop done", __func__); - status = pthread_cond_timedwait(&loaded_start_stop_cond, - &loaded_start_stop_mlock, &ts); - if (status != 0) - { - DEBUG_PRINT_ERROR("%s: error status = %d, %s", __func__, - status, strerror(status)); - pthread_mutex_unlock(&loaded_start_stop_mlock); - return false; - } - DEBUG_PRINT_LOW("%s: wait over on stop done", __func__); - pthread_mutex_unlock(&loaded_start_stop_mlock); - DEBUG_PRINT_LOW("%s: venc_loaded_stop success", __func__); - return true; -} - -bool venc_dev::venc_loaded_start_done() -{ - pthread_mutex_lock(&loaded_start_stop_mlock); - DEBUG_PRINT_LOW("%s: signal start done", __func__); - pthread_cond_signal(&loaded_start_stop_cond); - pthread_mutex_unlock(&loaded_start_stop_mlock); - return true; -} - -bool venc_dev::venc_loaded_stop_done() -{ - pthread_mutex_lock(&loaded_start_stop_mlock); - DEBUG_PRINT_LOW("%s: signal stop done", __func__); - pthread_cond_signal(&loaded_start_stop_cond); - pthread_mutex_unlock(&loaded_start_stop_mlock); - return true; -} - -bool venc_dev::venc_get_seq_hdr(void *buffer, - unsigned buffer_size, unsigned *header_len) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - int i = 0; - DEBUG_PRINT_HIGH("venc_dev::venc_get_seq_hdr"); - venc_seqheader seq_in, seq_out; - seq_in.hdrlen = 0; - seq_in.bufsize = buffer_size; - seq_in.hdrbufptr = (unsigned char*)buffer; - if (seq_in.hdrbufptr == NULL) { - DEBUG_PRINT_ERROR("ERROR: malloc for sequence header failed"); - return false; - } - DEBUG_PRINT_LOW("seq_in: buf=%x, sz=%d, hdrlen=%d", seq_in.hdrbufptr, - seq_in.bufsize, seq_in.hdrlen); - - ioctl_msg.in = (void*)&seq_in; - ioctl_msg.out = (void*)&seq_out; - if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_SEQUENCE_HDR,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("ERROR: Request for getting sequence header failed"); - return false; - } - if (seq_out.hdrlen == 0) { - DEBUG_PRINT_ERROR("ERROR: Seq header returned zero length header"); - DEBUG_PRINT_ERROR("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr, - seq_out.bufsize, seq_out.hdrlen); - return false; - } - *header_len = seq_out.hdrlen; - DEBUG_PRINT_LOW("seq_out: buf=%x, sz=%d, hdrlen=%d", seq_out.hdrbufptr, - seq_out.bufsize, seq_out.hdrlen); - - return true; -} - -bool venc_dev::venc_get_capability_ltrcount(unsigned long *min, - unsigned long *max, unsigned long *step_size) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - venc_range cap_ltr_count; - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&cap_ltr_count; - if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_CAPABILITY_LTRCOUNT, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("ERROR: Get LTR Capability failed"); - return false; - } - else - { - *min = cap_ltr_count.min; - *max = cap_ltr_count.max; - *step_size = cap_ltr_count.step_size; - DEBUG_PRINT_HIGH("LTR Capability: min=%x, max=%d, step_size=%d", - *min, *max, *step_size); - } - return true; -} - -bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count, - unsigned long *actual_buff_count, - unsigned long *buff_size, - unsigned long port) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - - if(port == 0) - { - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&m_sInput_buff_property; - if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p buffer requirement failed"); - return false; - } - *min_buff_count = m_sInput_buff_property.mincount; - *actual_buff_count = m_sInput_buff_property.actualcount; -#ifdef USE_ION - // For ION memory allocations of the allocated buffer size - // must be 4k aligned, hence aligning the input buffer - // size to 4k. - m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095) - & (~4095); -#endif - *buff_size = m_sInput_buff_property.datasize; - } - else - { - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&m_sOutput_buff_property; - if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p buffer requirement failed"); - return false; - } - *min_buff_count = m_sOutput_buff_property.mincount; - *actual_buff_count = m_sOutput_buff_property.actualcount; - *buff_size = m_sOutput_buff_property.datasize; - } - - return true; - -} - -bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n"); - switch(index) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_HIGH("venc_set_param: OMX_IndexParamPortDefinition"); - if(portDefn->nPortIndex == PORT_INDEX_IN) - { - - if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) - { - return false; - } - - if(!venc_set_color_format(portDefn->format.video.eColorFormat)) - { - return false; - } - - DEBUG_PRINT_LOW("Basic parameter has changed"); - m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; - m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; - - ioctl_msg.in = (void*)&m_sVenc_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Request for setting base config failed"); - return false; - } - DEBUG_PRINT_HIGH("WxH (%dx%d), codec (%d), fps(nr/dr) (%d/%d), bitrate (%d), " - "color_format (%d)", m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, - m_sVenc_cfg.codectype, m_sVenc_cfg.fps_num, m_sVenc_cfg.fps_den, - m_sVenc_cfg.targetbitrate, m_sVenc_cfg.inputformat); - - DEBUG_PRINT_LOW("Updating the buffer count/size for the new resolution"); - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&m_sInput_buff_property; - if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Request for getting i/p bufreq failed"); - return false; - } - DEBUG_PRINT_HIGH("Got updated m_sInput_buff_property values: " - "datasize = %u, maxcount = %u, actualcnt = %u, " - "mincount = %u", m_sInput_buff_property.datasize, - m_sInput_buff_property.maxcount, m_sInput_buff_property.actualcount, - m_sInput_buff_property.mincount); - - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&m_sOutput_buff_property; - if(ioctl (m_nDriver_fd, VEN_IOCTL_GET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Request for getting o/p bufreq failed"); - return false; - } - - DEBUG_PRINT_HIGH("Got updated m_sOutput_buff_property values: " - "datasize = %u, maxcount = %u, actualcnt = %u, " - "mincount = %u", m_sOutput_buff_property.datasize, - m_sOutput_buff_property.maxcount, m_sOutput_buff_property.actualcount, - m_sOutput_buff_property.mincount); - ioctl_msg.in = (void*)&m_sOutput_buff_property; - ioctl_msg.out = NULL; - - if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p bufreq failed"); - return false; - } - - if((portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) && - (portDefn->nBufferCountActual <= m_sInput_buff_property.maxcount)) { - m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; - ioctl_msg.in = (void*)&m_sInput_buff_property; - ioctl_msg.out = NULL; - if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Request for setting i/p buffer requirements failed"); - return false; - } - } - if(m_sInput_buff_property.datasize != portDefn->nBufferSize) { - DEBUG_PRINT_ERROR("\nWARNING: Requested i/p bufsize[%u]," - "Driver's updated i/p bufsize = %u", portDefn->nBufferSize, - m_sInput_buff_property.datasize); - } - m_level_set = false; - if(venc_set_profile_level(0, 0)) { - DEBUG_PRINT_LOW("%s(): Profile/Level setting success", __func__); - } - } - else if(portDefn->nPortIndex == PORT_INDEX_OUT) - { - if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) - { - return false; - } - - if( (portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) - && - (m_sOutput_buff_property.maxcount >= portDefn->nBufferCountActual) - && - (m_sOutput_buff_property.datasize == portDefn->nBufferSize) - ) - { - m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; - ioctl_msg.in = (void*)&m_sOutput_buff_property; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); - } - break; - } - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; - portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n"); - - if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) - { - if(!venc_set_color_format(portFmt->eColorFormat)) - { - return false; - } - } - else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(!venc_set_encode_framerate(portFmt->xFramerate, 0)) - { - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); - } - break; - } - case OMX_IndexParamVideoBitrate: - { - OMX_VIDEO_PARAM_BITRATETYPE* pParam; - pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n"); - - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) - { - DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed"); - return false; - } - if(!venc_set_ratectrl_cfg(pParam->eControlRate)) - { - DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); - } - break; - } - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE* pParam; - OMX_U32 bFrames = 0; - - pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n"); - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(!venc_set_voptiming_cfg(pParam->nTimeIncRes)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed"); - return false; - } - m_profile_set = false; - m_level_set = false; - if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); - return false; - } -#ifdef MAX_RES_1080P - else { - if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - bFrames = 1; - } - } - else - { - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - bFrames = 0; - } - } - } -#endif - if(!venc_set_intra_period (pParam->nPFrames,bFrames)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); - } - break; - } - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n"); - OMX_U32 bFrames = 0; - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - m_profile_set = false; - m_level_set = false; - if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); - return false; - } - if (pParam->nBFrames) - DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263"); - - if(venc_set_intra_period (pParam->nPFrames, bFrames) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263"); - } - break; - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n"); - OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; - OMX_U32 bFrames = 0; - - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n", - pParam->eProfile,pParam->eLevel); - - m_profile_set = false; - m_level_set = false; - - if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d", - pParam->eProfile, pParam->eLevel); - return false; - } -#ifdef MAX_RES_1080P - else { - if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) - { - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - bFrames = 1; - } - } - else - { - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - bFrames = 0; - } - } - } -#endif - if(!venc_set_intra_period (pParam->nPFrames, bFrames)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed"); - return false; - } - if(!venc_set_inloop_filter (pParam->eLoopFilterMode)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed"); - return false; - } - if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) - { - DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); - } - //TBD, lot of other variables to be updated, yet to decide - break; - } - case OMX_IndexParamVideoIntraRefresh: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n"); - OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = - (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; - if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); - } - break; - } - case OMX_IndexParamVideoErrorCorrection: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n"); - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = - (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; - if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_error_resilience(error_resilience) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); - } - break; - } - case OMX_IndexParamVideoProfileLevelCurrent: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n"); - OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = - (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; - if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - m_profile_set = false; - m_level_set = false; - if(!venc_set_profile_level (profile_level->eProfile, - profile_level->eLevel)) - { - DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); - } - break; - } - case OMX_IndexParamVideoQuantization: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n"); - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = - (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; - if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_session_qp (session_qp->nQpI, - session_qp->nQpP) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); - } - break; - } - - case OMX_QcomIndexParamVideoQPRange: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange\n"); - OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = - (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData; - if(qp_range->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_qp_range (qp_range->minQP, - qp_range->maxQP) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting QP Range failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange"); - } - break; - } - - case OMX_ExtraDataVideoEncoderSliceInfo: - { - DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); - OMX_U32 extra_data = *(OMX_U32 *)paramData; - if(venc_set_extradata(extra_data) == false) - { - DEBUG_PRINT_ERROR("ERROR: Setting " - "OMX_ExtraDataVideoEncoderSliceInfo failed"); - return false; - } - break; - } - case OMX_ExtraDataVideoLTRInfo: - { - DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoLTRInfo"); - OMX_U32 extra_data = *(OMX_U32 *)paramData; - if(venc_set_extradata(extra_data) == false) - { - DEBUG_PRINT_ERROR("ERROR: Setting " - "OMX_ExtraDataVideoLTRInfo failed"); - return false; - } - break; - } - case OMX_QcomIndexEnableSliceDeliveryMode: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(venc_set_slice_delivery_mode(pParam->bEnable) == false) - { - DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case OMX_QcomIndexEnableH263PlusPType: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - DEBUG_PRINT_LOW("OMX_QcomIndexEnableH263PlusPType"); - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(venc_set_plusptype(pParam->bEnable) == false) - { - DEBUG_PRINT_ERROR("Setting PlusPType failed for H263"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("OMX_QcomIndexEnableH263PlusPType " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case QOMX_IndexParamVideoLTRMode: - { - QOMX_VIDEO_PARAM_LTRMODE_TYPE* pParam = - (QOMX_VIDEO_PARAM_LTRMODE_TYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(!venc_set_ltrmode(pParam->eLTRMode)) - { - DEBUG_PRINT_ERROR("Setting ltr mode failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRMode " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case QOMX_IndexParamVideoLTRCount: - { - QOMX_VIDEO_PARAM_LTRCOUNT_TYPE* pParam = - (QOMX_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(!venc_set_ltrcount(pParam->nCount)) - { - DEBUG_PRINT_ERROR("Setting ltr count failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("QOMX_IndexParamVideoLTRCount " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case OMX_IndexParamVideoSliceFMO: - default: - DEBUG_PRINT_ERROR("venc_set_param: Unsupported index 0x%x", index); - break; - } - - return true; -} - -bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - DEBUG_PRINT_LOW("\n Inside venc_set_config"); - - switch(index) - { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) - configData; - if(m_max_allowed_bitrate_check && - !venc_max_allowed_bitrate_check(bit_rate->nEncodeBitrate)) - { - DEBUG_PRINT_ERROR("Max Allowed Bitrate Check failed"); - return false; - } - DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate"); - if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); - } - break; - } - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) - configData; - DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate"); - if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); - } - break; - } - case QOMX_IndexConfigVideoIntraperiod: - { - DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n"); - QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = - (QOMX_VIDEO_INTRAPERIODTYPE *)configData; - if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - } - break; - } - case OMX_IndexConfigVideoIntraVOPRefresh: - { - OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) - configData; - DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); - if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); - } - break; - } - case OMX_IndexConfigCommonRotate: - { - OMX_CONFIG_ROTATIONTYPE *config_rotation = - reinterpret_cast(configData); - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - OMX_U32 nFrameWidth; - - DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims"); - nFrameWidth = m_sVenc_cfg.input_width; - m_sVenc_cfg.input_width = m_sVenc_cfg.input_height; - m_sVenc_cfg.input_height = nFrameWidth; - ioctl_msg.in = (void*)&m_sVenc_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed"); - return false; - } - break; - } - case QOMX_IndexConfigVideoLTRPeriod: - { - QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE* pParam = - (QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE*)configData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(!venc_set_ltrperiod(pParam->nFrames)) - { - DEBUG_PRINT_ERROR("Setting ltr period failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRPeriod " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case QOMX_IndexConfigVideoLTRUse: - { - QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam = - (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(!venc_set_ltruse(pParam->nID, pParam->nFrames)) - { - DEBUG_PRINT_ERROR("Setting ltr use failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("QOMX_IndexConfigVideoLTRUse " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - default: - DEBUG_PRINT_ERROR("venc_set_config: Unsupported index = 0x%x", index); - break; - } - - return true; -} - -unsigned venc_dev::venc_stop( void) -{ -#ifdef MAX_RES_1080P - pmem_free(); -#endif - return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_STOP,NULL); -} - -unsigned venc_dev::venc_pause(void) -{ - return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_PAUSE,NULL); -} - -unsigned venc_dev::venc_resume(void) -{ - return ioctl(m_nDriver_fd,VEN_IOCTL_CMD_RESUME,NULL) ; -} - -unsigned venc_dev::venc_start_done(void) -{ - return 0; -} - -unsigned venc_dev::venc_set_message_thread_id(pthread_t) -{ - return 0; -} - -unsigned venc_dev::venc_start(void) -{ - DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start", - __func__); - if (!venc_set_profile_level(0, 0)) - { - DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET", - __func__); - } - else - { - DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET", - __func__, codec_profile.profile, profile_level.level); - } - - if(m_max_allowed_bitrate_check && - !venc_max_allowed_bitrate_check(bitrate.target_bitrate)) - { - DEBUG_PRINT_ERROR("Maximum Allowed Bitrate Check failed"); - return -1; - } - - venc_config_print(); - -#ifdef MAX_RES_1080P - if((codec_profile.profile == VEN_PROFILE_MPEG4_SP) || - (codec_profile.profile == VEN_PROFILE_H264_BASELINE) || - (codec_profile.profile == VEN_PROFILE_H263_BASELINE)) - recon_buffers_count = MAX_RECON_BUFFERS - 2; - else - recon_buffers_count = MAX_RECON_BUFFERS; - - if (ltrmode.ltr_mode == (unsigned long)QOMX_VIDEO_LTRMode_Auto) - { - recon_buffers_count = MAX_RECON_BUFFERS; - DEBUG_PRINT_HIGH("ltr mode enabled, so set recon buffers " - "count to %d", recon_buffers_count); - } - - if (!venc_allocate_recon_buffers()) - return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL); - else - { - DEBUG_PRINT_ERROR("Failed in creating Recon buffers\n"); - return -1; - } -#else - return ioctl(m_nDriver_fd, VEN_IOCTL_CMD_START, NULL); -#endif -} - -#ifdef MAX_RES_1080P -OMX_U32 venc_dev::venc_allocate_recon_buffers() -{ - OMX_U32 yuv_size; - struct venc_ioctl_msg ioctl_msg; - struct venc_recon_buff_size recon_buff_size; - - recon_buff_size.width = ((m_sVenc_cfg.input_width + 15) / 16) * 16; - recon_buff_size.height = ((m_sVenc_cfg.input_height + 15) / 16 ) * 16; - - DEBUG_PRINT_LOW("Width %d, Height %d, w_round %d, h_round %d\n", m_sVenc_cfg.input_width, - m_sVenc_cfg.input_height, recon_buff_size.width, recon_buff_size.height); - - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&recon_buff_size; - - if (ioctl (m_nDriver_fd,VEN_IOCTL_GET_RECON_BUFFER_SIZE, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\n VEN_IOCTL_GET_RECON_BUFFER_SIZE Failed for width: %d, Height %d" , - recon_buff_size.width, recon_buff_size.height); - return OMX_ErrorInsufficientResources; - } - - DEBUG_PRINT_HIGH("Width %d, Height %d, w_round %d, h_round %d, yuv_size %d alignment %d count %d\n", - m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, recon_buff_size.width, - recon_buff_size.height, recon_buff_size.size, recon_buff_size.alignment, - recon_buffers_count); - - for(int i = 0; i < recon_buffers_count; i++) - { - if(pmem_allocate(recon_buff_size.size, recon_buff_size.alignment,i)) - { - DEBUG_PRINT_ERROR("Error returned in allocating recon buffers\n"); - return -1; - } - } - return 0; -} -OMX_U32 venc_dev::pmem_allocate(OMX_U32 size, OMX_U32 alignment, OMX_U32 count) -{ - OMX_U32 pmem_fd = -1; - OMX_U32 width, height; - void *buf_addr = NULL; - struct venc_ioctl_msg ioctl_msg; - struct venc_recon_addr recon_addr; - int rc = 0; - -#ifdef USE_ION - recon_buff[count].ion_device_fd = open (MEM_DEVICE,O_RDONLY); - if(recon_buff[count].ion_device_fd < 0) - { - DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed"); - return -1; - } - - recon_buff[count].alloc_data.len = size; -#ifdef MAX_RES_720P - recon_buff[count].alloc_data.heap_mask = ION_HEAP(MEM_HEAP_ID); -#else - recon_buff[count].alloc_data.heap_mask = (ION_HEAP(MEM_HEAP_ID) | - ION_HEAP(ION_IOMMU_HEAP_ID)); -#endif - recon_buff[count].alloc_data.flags = ION_FLAG_CACHED; - recon_buff[count].alloc_data.align = clip2(alignment); - if (recon_buff[count].alloc_data.align != 8192) - recon_buff[count].alloc_data.align = 8192; - - rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_ALLOC,&recon_buff[count].alloc_data); - if(rc || !recon_buff[count].alloc_data.handle) { - DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); - recon_buff[count].alloc_data.handle=NULL; - return -1; - } - - recon_buff[count].ion_alloc_fd.handle = recon_buff[count].alloc_data.handle; - rc = ioctl(recon_buff[count].ion_device_fd,ION_IOC_MAP,&recon_buff[count].ion_alloc_fd); - if(rc) { - DEBUG_PRINT_ERROR("\n ION MAP failed "); - recon_buff[count].ion_alloc_fd.fd =-1; - recon_buff[count].ion_alloc_fd.fd =-1; - return -1; - } - pmem_fd = recon_buff[count].ion_alloc_fd.fd; -#else - struct pmem_allocation allocation; - pmem_fd = open(MEM_DEVICE, O_RDWR); - - if ((int)(pmem_fd) < 0) - { - DEBUG_PRINT_ERROR("\n Failed to get an pmem handle"); - return -1; - } - - allocation.size = size; - allocation.align = clip2(alignment); - - if (allocation.align != 8192) - allocation.align = 8192; - - if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) - { - DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)", - allocation.align, allocation.size); - return -1; - } -#endif - buf_addr = mmap(NULL, size, - PROT_READ | PROT_WRITE, - MAP_SHARED, pmem_fd, 0); - - if (buf_addr == (void*) MAP_FAILED) - { - close(pmem_fd); - pmem_fd = -1; - DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr); -#ifdef USE_ION - if(ioctl(recon_buff[count].ion_device_fd,ION_IOC_FREE, - &recon_buff[count].alloc_data.handle)) { - DEBUG_PRINT_LOW("ion recon buffer free failed"); - } - recon_buff[count].alloc_data.handle = NULL; - recon_buff[count].ion_alloc_fd.fd =-1; - close(recon_buff[count].ion_device_fd); - recon_buff[count].ion_device_fd =-1; -#endif - return -1; - } - - DEBUG_PRINT_HIGH("\n Allocated virt:%p, FD: %d of size %d \n", buf_addr, pmem_fd, size); - - recon_addr.buffer_size = size; - recon_addr.pmem_fd = pmem_fd; - recon_addr.offset = 0; - recon_addr.pbuffer = (unsigned char *)buf_addr; - - ioctl_msg.in = (void*)&recon_addr; - ioctl_msg.out = NULL; - - if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_RECON_BUFFER, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Failed to set the Recon_buffers\n"); - return -1; - } - - recon_buff[count].virtual_address = (unsigned char *) buf_addr; - recon_buff[count].size = size; - recon_buff[count].offset = 0; - recon_buff[count].pmem_fd = pmem_fd; - - DEBUG_PRINT_ERROR("\n Allocated virt:%p, FD: %d of size %d at index: %d\n", recon_buff[count].virtual_address, - recon_buff[count].pmem_fd, recon_buff[count].size, count); - return 0; -} - -OMX_U32 venc_dev::pmem_free() -{ - int cnt = 0; - struct venc_ioctl_msg ioctl_msg; - struct venc_recon_addr recon_addr; - for (cnt = 0; cnt < recon_buffers_count; cnt++) - { - if(recon_buff[cnt].pmem_fd) - { - recon_addr.pbuffer = recon_buff[cnt].virtual_address; - recon_addr.offset = recon_buff[cnt].offset; - recon_addr.pmem_fd = recon_buff[cnt].pmem_fd; - recon_addr.buffer_size = recon_buff[cnt].size; - ioctl_msg.in = (void*)&recon_addr; - ioctl_msg.out = NULL; - if(ioctl(m_nDriver_fd, VEN_IOCTL_FREE_RECON_BUFFER ,&ioctl_msg) < 0) - DEBUG_PRINT_ERROR("VEN_IOCTL_FREE_RECON_BUFFER failed"); - munmap(recon_buff[cnt].virtual_address, recon_buff[cnt].size); - close(recon_buff[cnt].pmem_fd); -#ifdef USE_ION - if(ioctl(recon_buff[cnt].ion_device_fd,ION_IOC_FREE, - &recon_buff[cnt].alloc_data.handle)) { - DEBUG_PRINT_LOW("ion recon buffer free failed"); - } - recon_buff[cnt].alloc_data.handle = NULL; - recon_buff[cnt].ion_alloc_fd.fd =-1; - close(recon_buff[cnt].ion_device_fd); - recon_buff[cnt].ion_device_fd =-1; -#endif - DEBUG_PRINT_LOW("\n cleaning Index %d of size %d \n",cnt,recon_buff[cnt].size); - recon_buff[cnt].pmem_fd = -1; - recon_buff[cnt].virtual_address = NULL; - recon_buff[cnt].offset = 0; - recon_buff[cnt].alignment = 0; - recon_buff[cnt].size = 0; - } - } - return 0; -} -#endif - -void venc_dev::venc_config_print() -{ - - DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %d, Profile %d, level : %d", - m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level); - - DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %d, Height:%d, Fps: %d", - m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, - m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d", - bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %d, qpP: %d, qpb: 0", - session_qp.iframeqp, session_qp.pframqp); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: minQP: %d, maxQP: %d", - qp_range.minqp, qp_range.maxqp); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d", - voptimecfg.voptime_resolution, multislice.mslice_mode, - multislice.mslice_size); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %d", - entropy.longentropysel, entropy.cabacmodel); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d\n", - dbkfilter.db_mode, dbkfilter.slicealpha_offset, - dbkfilter.slicebeta_offset); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %d, HEC: %d\n", - intra_refresh.mbcount, hec.header_extension); -} - -unsigned venc_dev::venc_flush( unsigned port) -{ - struct venc_ioctl_msg ioctl_msg; - struct venc_bufferflush buffer_index; - - if(port == PORT_INDEX_IN) - { - DEBUG_PRINT_HIGH("Calling Input Flush"); - buffer_index.flush_mode = VEN_FLUSH_INPUT; - ioctl_msg.in = (void*)&buffer_index; - ioctl_msg.out = NULL; - - return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); - } - else if(port == PORT_INDEX_OUT) - { - DEBUG_PRINT_HIGH("Calling Output Flush"); - buffer_index.flush_mode = VEN_FLUSH_OUTPUT; - ioctl_msg.in = (void*)&buffer_index; - ioctl_msg.out = NULL; - return ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FLUSH,(void*)&ioctl_msg); - } - else - { - return -1; - } -} - -//allocating I/P memory from pmem and register with the device - - -bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct pmem *pmem_tmp; - struct venc_bufferpayload dev_buffer = {0}; - struct venc_allocatorproperty buff_alloc_property = {0}; - - pmem_tmp = (struct pmem *)buf_addr; - - DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); - - if(port == PORT_INDEX_IN) - { - dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; - dev_buffer.fd = pmem_tmp->fd; - dev_buffer.maped_size = pmem_tmp->size; - dev_buffer.sz = pmem_tmp->size; - dev_buffer.offset = pmem_tmp->offset; - - if((m_sVenc_cfg.input_height %16 !=0) || (m_sVenc_cfg.input_width%16 != 0)) - { - unsigned long ht = m_sVenc_cfg.input_height; - unsigned long wd = m_sVenc_cfg.input_width; - unsigned int luma_size, luma_size_2k; - - ht = (ht + 15) & ~15; - wd = (wd + 15) & ~15; - - luma_size = ht * wd; - luma_size_2k = (luma_size + 2047) & ~2047; - - dev_buffer.sz = luma_size_2k + ((luma_size/2 + 2047) & ~2047); -#ifdef USE_ION - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&buff_alloc_property; - if(ioctl (m_nDriver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:get input buffer failed "); - return false; - } - if(buff_alloc_property.alignment < 4096) - { - dev_buffer.sz = ((dev_buffer.sz + 4095) & ~4095); - } - else - { - dev_buffer.sz = ((dev_buffer.sz + (buff_alloc_property.alignment - 1)) & - ~(buff_alloc_property.alignment - 1)); - } -#endif - dev_buffer.maped_size = dev_buffer.sz; - } - - ioctl_msg.in = (void*)&dev_buffer; - ioctl_msg.out = NULL; - - DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ - dev_buffer.pbuffer, \ - dev_buffer.fd, \ - dev_buffer.offset, \ - dev_buffer.maped_size); - - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set input buffer failed "); - return false; - } - } - else if(port == PORT_INDEX_OUT) - { - dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; - dev_buffer.fd = pmem_tmp->fd; - dev_buffer.sz = pmem_tmp->size; - dev_buffer.maped_size = pmem_tmp->size; - dev_buffer.offset = pmem_tmp->offset; - ioctl_msg.in = (void*)&dev_buffer; - ioctl_msg.out = NULL; - - DEBUG_PRINT_LOW("\n venc_use_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ - dev_buffer.pbuffer, \ - dev_buffer.fd, \ - dev_buffer.offset, \ - dev_buffer.maped_size); - - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:set output buffer failed "); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index "); - return false; - } - - return true; -} - -bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct pmem *pmem_tmp; - struct venc_bufferpayload dev_buffer = {0}; - - pmem_tmp = (struct pmem *)buf_addr; - - DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); - - if(port == PORT_INDEX_IN) - { - dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; - dev_buffer.fd = pmem_tmp->fd; - dev_buffer.maped_size = pmem_tmp->size; - dev_buffer.sz = pmem_tmp->size; - dev_buffer.offset = pmem_tmp->offset; - ioctl_msg.in = (void*)&dev_buffer; - ioctl_msg.out = NULL; - - DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ - dev_buffer.pbuffer, \ - dev_buffer.fd, \ - dev_buffer.offset, \ - dev_buffer.maped_size); - - if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_INPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free input buffer failed "); - return false; - } - } - else if(port == PORT_INDEX_OUT) - { - dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; - dev_buffer.fd = pmem_tmp->fd; - dev_buffer.sz = pmem_tmp->size; - dev_buffer.maped_size = pmem_tmp->size; - dev_buffer.offset = pmem_tmp->offset; - ioctl_msg.in = (void*)&dev_buffer; - ioctl_msg.out = NULL; - - DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ - dev_buffer.pbuffer, \ - dev_buffer.fd, \ - dev_buffer.offset, \ - dev_buffer.maped_size); - - if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FREE_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: venc_free_buf: free output buffer failed "); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index "); - return false; - } - - return true; -} - -bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned) -{ - struct venc_buffer frameinfo; - struct pmem *temp_buffer; - struct venc_ioctl_msg ioctl_msg; - struct OMX_BUFFERHEADERTYPE *bufhdr; - - if(buffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL"); - return false; - } - bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; - - DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen); - - if(pmem_data_buf) - { - DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); - frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; - } - else - { - DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); - frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; - } - - frameinfo.clientdata = (void *) buffer; - frameinfo.sz = bufhdr->nFilledLen; - frameinfo.len = bufhdr->nFilledLen; - frameinfo.flags = bufhdr->nFlags; - frameinfo.offset = bufhdr->nOffset; - frameinfo.timestamp = bufhdr->nTimeStamp; - DEBUG_PRINT_LOW("\n i/p TS = %u", (OMX_U32)frameinfo.timestamp); - ioctl_msg.in = &frameinfo; - ioctl_msg.out = NULL; - - DEBUG_PRINT_LOW("DBG: i/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", - bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); - if(ioctl(m_nDriver_fd,VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) - { - /*Generate an async error and move to invalid state*/ - return false; - } -#ifdef INPUT_BUFFER_LOG -#ifdef MAX_RES_1080P - - int y_size = 0; - int c_offset = 0; - unsigned char *buf_addr = NULL; - - y_size = m_sVenc_cfg.input_width * m_sVenc_cfg.input_height; - //chroma offset is y_size aligned to the 2k boundary - c_offset= (y_size + 2047) & (~(2047)); - - if(pmem_data_buf) - { - DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); - buf_addr = (OMX_U8 *)pmem_data_buf; - } - else - { - DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); - buf_addr = (unsigned char *)mmap(NULL, - ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2], - PROT_READ|PROT_WRITE, MAP_SHARED, - ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[0], 0); - } - - if(inputBufferFile1) - { - fwrite((const char *)buf_addr, y_size, 1,inputBufferFile1); - fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1,inputBufferFile1); - } - - munmap (buf_addr, ((encoder_media_buffer_type *)bufhdr->pBuffer)->meta_handle->data[2]); -#else - if(inputBufferFile1) - { - fwrite((const char *)frameinfo.ptrbuffer, frameinfo.len, 1,inputBufferFile1); - } -#endif - -#endif - return true; -} -bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned,unsigned) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct pmem *temp_buffer = NULL; - struct venc_buffer frameinfo; - struct OMX_BUFFERHEADERTYPE *bufhdr; - - if(buffer == NULL) - { - return false; - } - bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; - - if(pmem_data_buf) - { - DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); - frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf; - } - else - { - DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); - frameinfo.ptrbuffer = (OMX_U8 *)bufhdr->pBuffer; - } - - frameinfo.clientdata = buffer; - frameinfo.sz = bufhdr->nAllocLen; - frameinfo.flags = bufhdr->nFlags; - frameinfo.offset = bufhdr->nOffset; - - ioctl_msg.in = &frameinfo; - ioctl_msg.out = NULL; - DEBUG_PRINT_LOW("DBG: o/p frameinfo: bufhdr->pBuffer = %p, ptrbuffer = %p, offset = %u, len = %u", - bufhdr->pBuffer, frameinfo.ptrbuffer, frameinfo.offset, frameinfo.len); - if(ioctl (m_nDriver_fd,VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: ioctl VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER failed"); - return false; - } - - return true; -} - -bool venc_dev::venc_set_slice_delivery_mode(OMX_BOOL enable) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - DEBUG_PRINT_HIGH("Set slice_delivery_mode: %d", enable); - if(multislice.mslice_mode == VEN_MSLICE_CNT_MB) - { - if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_SLICE_DELIVERY_MODE) < 0) - { - DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("WARNING: slice_mode[%d] is not VEN_MSLICE_CNT_MB to set " - "slice delivery mode to the driver.", multislice.mslice_mode); - } - return true; -} - -bool venc_dev::venc_set_plusptype(OMX_BOOL enable) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_plusptype plusptype = {0}; - DEBUG_PRINT_LOW("Set plusptype: %d", enable); - plusptype.plusptype_enable = enable; - ioctl_msg.in = (void*)&plusptype; - ioctl_msg.out = NULL; - if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_H263_PLUSPTYPE,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("Request for setting plusptype for h263 failed"); - return false; - } - return true; -} - -bool venc_dev::venc_set_ltrmode(QOMX_VIDEO_LTRMODETYPE mode) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - venc_ltrmode ltr_mode; - ltr_mode.ltr_mode = (unsigned long)mode; - DEBUG_PRINT_HIGH("Set ltr mode: %d", mode); - ioctl_msg.in = (void*)<r_mode; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRMODE, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("ERROR: Setting ltrmode failed"); - return false; - } - ltrmode.ltr_mode = (unsigned long)mode; - return true; -} - -bool venc_dev::venc_set_ltrcount(OMX_U32 count) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - venc_ltrcount ltr_count; - ltr_count.ltr_count = (unsigned long)count; - DEBUG_PRINT_HIGH("Set ltr count: %d", count); - ioctl_msg.in = (void*)<r_count; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRCOUNT, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("ERROR: Setting ltrcount failed"); - return false; - } - ltrcount.ltr_count = (unsigned long)count; - return true; -} - -bool venc_dev::venc_set_ltrperiod(OMX_U32 period) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - venc_ltrperiod ltr_period; - ltr_period.ltr_period = (unsigned long)period; - DEBUG_PRINT_HIGH("Set ltr period: %d", period); - ioctl_msg.in = (void*)<r_period; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRPERIOD, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("ERROR: Setting ltrperiod failed"); - return false; - } - ltrperiod.ltr_period = (unsigned long)period; - return true; -} - -bool venc_dev::venc_set_ltruse(OMX_U32 id, OMX_U32 frames) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - venc_ltruse ltr_use; - ltr_use.ltr_id = (unsigned long)id; - ltr_use.ltr_frames = (unsigned long)frames; - DEBUG_PRINT_HIGH("Set ltr use: id = %d, ltr_frames = %d", id, frames); - ioctl_msg.in = (void*)<r_use; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_LTRUSE, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("ERROR: Setting ltruse failed"); - return false; - } - return true; -} - -bool venc_dev::venc_set_extradata(OMX_U32 extra_data) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - DEBUG_PRINT_HIGH("venc_set_extradata:: %x", extra_data); - ioctl_msg.in = (void*)&extra_data; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_EXTRADATA, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed"); - return false; - } - - return true; -} - -bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_sessionqp qp = {0, 0}; - DEBUG_PRINT_HIGH("venc_set_session_qp:: i_frame_qp = %d, p_frame_qp = %d", i_frame_qp, - p_frame_qp); - - qp.iframeqp = i_frame_qp; - qp.pframqp = p_frame_qp; - - ioctl_msg.in = (void*)&qp; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_SESSION_QP,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting session qp failed"); - return false; - } - - session_qp.iframeqp = i_frame_qp; - session_qp.pframqp = p_frame_qp; - - return true; -} - -bool venc_dev::venc_set_qp_range(OMX_U32 min_qp, OMX_U32 max_qp) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_qprange qp = {0, 0}; - DEBUG_PRINT_LOW("venc_set_qp_range:: min_qp = %d, max_qp = %d", min_qp, - max_qp); - - qp.minqp = min_qp; - qp.maxqp = max_qp; - - ioctl_msg.in = (void*)&qp; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_QP_RANGE,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting qp range failed"); - return false; - } - - qp_range.minqp= min_qp; - qp_range.maxqp= max_qp; - - return true; -} - -bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_profile requested_profile; - struct ven_profilelevel requested_level; - unsigned const int *profile_tbl = NULL; - unsigned long mb_per_frame = 0, mb_per_sec = 0; - DEBUG_PRINT_HIGH("venc_set_profile_level:: eProfile = %d, Level = %d", - eProfile, eLevel); - mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* - ((m_sVenc_cfg.input_width + 15) >> 4); - if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) - { - DEBUG_PRINT_HIGH("Set profile/level was done already"); - return true; - } - - if(eProfile && eLevel) - { - /* non-zero values will be set by user, saving the same*/ - m_eProfile = eProfile; - m_eLevel = eLevel; - DEBUG_PRINT_HIGH("Save profile/level (%d/%d) for max allowed bitrate check", - m_eProfile, m_eLevel); - } - - DEBUG_PRINT_LOW("Validating Profile/Level from table"); - if(!venc_validate_profile_level(&eProfile, &eLevel)) - { - DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed"); - return false; - } - - if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) - { - DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and " - "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile, - OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); - if(eProfile == OMX_VIDEO_MPEG4ProfileSimple) - { - requested_profile.profile = VEN_PROFILE_MPEG4_SP; - profile_tbl = (unsigned int const *) - (&mpeg4_profile_level_table[MPEG4_SP_START]); - profile_tbl += MPEG4_720P_LEVEL*5; - } - else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { - requested_profile.profile = VEN_PROFILE_MPEG4_ASP; - profile_tbl = (unsigned int const *) - (&mpeg4_profile_level_table[MPEG4_ASP_START]); - profile_tbl += MPEG4_720P_LEVEL*5; - } - else - { - DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u", - eProfile); - return false; - } - - DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," - "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," - "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, - OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); - - if(mb_per_frame >= 3600) - { - if(requested_profile.profile == VEN_PROFILE_MPEG4_ASP) - requested_level.level = VEN_LEVEL_MPEG4_5; - if(requested_profile.profile == VEN_PROFILE_MPEG4_SP) - requested_level.level = VEN_LEVEL_MPEG4_6; - } - else - { - switch(eLevel) - { - case OMX_VIDEO_MPEG4Level0: - requested_level.level = VEN_LEVEL_MPEG4_0; - break; - case OMX_VIDEO_MPEG4Level1: - requested_level.level = VEN_LEVEL_MPEG4_1; - break; - case OMX_VIDEO_MPEG4Level2: - requested_level.level = VEN_LEVEL_MPEG4_2; - break; - case OMX_VIDEO_MPEG4Level3: - requested_level.level = VEN_LEVEL_MPEG4_3; - break; - case OMX_VIDEO_MPEG4Level4a: - requested_level.level = VEN_LEVEL_MPEG4_4; - break; - case OMX_VIDEO_MPEG4Level5: - mb_per_sec = mb_per_frame * (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den); - if((requested_profile.profile == VEN_PROFILE_MPEG4_SP) && (mb_per_frame >= profile_tbl[0]) && - (mb_per_sec >= profile_tbl[1])) - { - DEBUG_PRINT_LOW("\nMPEG4 Level 6 is set for 720p resolution"); - requested_level.level = VEN_LEVEL_MPEG4_6; - } - else - { - DEBUG_PRINT_LOW("\nMPEG4 Level 5 is set for non-720p resolution"); - requested_level.level = VEN_LEVEL_MPEG4_5; - } - break; - default: - return false; - // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 - break; - } - } - } - else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) - { - if(eProfile == OMX_VIDEO_H263ProfileBaseline) - { - requested_profile.profile = VEN_PROFILE_H263_BASELINE; - } - else - { - DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u", - requested_profile.profile); - return false; - } - //profile level - switch(eLevel) - { - case OMX_VIDEO_H263Level10: - requested_level.level = VEN_LEVEL_H263_10; - break; - case OMX_VIDEO_H263Level20: - requested_level.level = VEN_LEVEL_H263_20; - break; - case OMX_VIDEO_H263Level30: - requested_level.level = VEN_LEVEL_H263_30; - break; - case OMX_VIDEO_H263Level40: - requested_level.level = VEN_LEVEL_H263_40; - break; - case OMX_VIDEO_H263Level45: - requested_level.level = VEN_LEVEL_H263_45; - break; - case OMX_VIDEO_H263Level50: - requested_level.level = VEN_LEVEL_H263_50; - break; - case OMX_VIDEO_H263Level60: - requested_level.level = VEN_LEVEL_H263_60; - break; - case OMX_VIDEO_H263Level70: - requested_level.level = VEN_LEVEL_H263_70; - break; - default: - return false; - break; - } - } - else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) - { - if(eProfile == OMX_VIDEO_AVCProfileBaseline) - { - requested_profile.profile = VEN_PROFILE_H264_BASELINE; - } - else if(eProfile == OMX_VIDEO_AVCProfileMain) - { - requested_profile.profile = VEN_PROFILE_H264_MAIN; - } - else if(eProfile == OMX_VIDEO_AVCProfileHigh) - { - requested_profile.profile = VEN_PROFILE_H264_HIGH; - } - else - { - DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u", - requested_profile.profile); - return false; - } - //profile level - switch(eLevel) - { - case OMX_VIDEO_AVCLevel1: - requested_level.level = VEN_LEVEL_H264_1; - break; - case OMX_VIDEO_AVCLevel1b: - requested_level.level = VEN_LEVEL_H264_1b; - break; - case OMX_VIDEO_AVCLevel11: - requested_level.level = VEN_LEVEL_H264_1p1; - break; - case OMX_VIDEO_AVCLevel12: - requested_level.level = VEN_LEVEL_H264_1p2; - break; - case OMX_VIDEO_AVCLevel13: - requested_level.level = VEN_LEVEL_H264_1p3; - break; - case OMX_VIDEO_AVCLevel2: - requested_level.level = VEN_LEVEL_H264_2; - break; - case OMX_VIDEO_AVCLevel21: - requested_level.level = VEN_LEVEL_H264_2p1; - break; - case OMX_VIDEO_AVCLevel22: - requested_level.level = VEN_LEVEL_H264_2p2; - break; - case OMX_VIDEO_AVCLevel3: - requested_level.level = VEN_LEVEL_H264_3; - break; - case OMX_VIDEO_AVCLevel31: - requested_level.level = VEN_LEVEL_H264_3p1; - break; - case OMX_VIDEO_AVCLevel32: - requested_level.level = VEN_LEVEL_H264_3p2; - break; - case OMX_VIDEO_AVCLevel4: - requested_level.level = VEN_LEVEL_H264_4; - break; - default : - DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %u", - requested_level.level); - return false; - break; - } - } - if(!m_profile_set) - { - ioctl_msg.in = (void*)&requested_profile; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_CODEC_PROFILE,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting profile failed"); - return false; - } - codec_profile.profile = requested_profile.profile; - m_profile_set = true; - DEBUG_PRINT_HIGH("Set codec profile = 0x%x", codec_profile.profile); - } - - if(!m_level_set) - { - ioctl_msg.in = (void*)&requested_level; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_PROFILE_LEVEL,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting profile level failed"); - return false; - } - profile_level.level = requested_level.level; - m_level_set = true; - DEBUG_PRINT_HIGH("Set codec level = 0x%x", profile_level.level); - } - - return true; -} - -bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_voptimingcfg vop_timing_cfg; - - DEBUG_PRINT_HIGH("venc_set_voptiming_cfg: TimeRes = %u", - TimeIncRes); - - vop_timing_cfg.voptime_resolution = TimeIncRes; - - ioctl_msg.in = (void*)&vop_timing_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_VOP_TIMING_CFG,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Vop Timing failed"); - return false; - } - - voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; - return true; -} - -bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_intraperiod intraperiod_cfg; - - DEBUG_PRINT_LOW("venc_set_intra_period: nPFrames = %u", - nPFrames); - intraperiod_cfg.num_pframes = nPFrames; - if((codec_profile.profile == VEN_PROFILE_MPEG4_ASP) || - (codec_profile.profile == VEN_PROFILE_H264_MAIN) || - (codec_profile.profile == VEN_PROFILE_H264_HIGH)) - { -#ifdef MAX_RES_1080P - if (nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - intraperiod_cfg.num_bframes = 1; - } - else - intraperiod_cfg.num_bframes = 0; -#else - if(nBFrames) - { - DEBUG_PRINT_ERROR("B frames not supported"); - intraperiod_cfg.num_bframes = 0; - } - else - { - DEBUG_PRINT_ERROR("B frames not supported"); - intraperiod_cfg.num_bframes = 0; - } -#endif - } - else - intraperiod_cfg.num_bframes = 0; - - DEBUG_PRINT_HIGH("venc_set_intra_period: nPFrames = %u nBFrames = %u", - intraperiod_cfg.num_pframes, intraperiod_cfg.num_bframes); - ioctl_msg.in = (void*)&intraperiod_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_PERIOD,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - - intra_period.num_pframes = intraperiod_cfg.num_pframes; - intra_period.num_bframes = intraperiod_cfg.num_bframes; - return true; -} - -bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_entropycfg entropy_cfg; - - memset(&entropy_cfg,0,sizeof(entropy_cfg)); - DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level); - - if(enable &&(codec_profile.profile != VEN_PROFILE_H264_BASELINE)){ - entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CABAC; - if (i_cabac_level == 0) { - entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0; - } -#ifdef MAX_RES_1080P - else - { - DEBUG_PRINT_HIGH("Invalid model set (%d) defaulting to model 0",i_cabac_level); - entropy_cfg.cabacmodel = VEN_CABAC_MODEL_0; - } -#else - else if (i_cabac_level == 1) { - entropy_cfg.cabacmodel = VEN_CABAC_MODEL_1; - } - else if (i_cabac_level == 2) { - entropy_cfg.cabacmodel = VEN_CABAC_MODEL_2; - } -#endif - } - else if(!enable){ - entropy_cfg.longentropysel = VEN_ENTROPY_MODEL_CAVLC; - } - else{ - DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile"); - return false; - } - - ioctl_msg.in = (void*)&entropy_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_ENTROPY_CFG,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting entropy config failed"); - return false; - } - entropy.longentropysel = entropy_cfg.longentropysel; - entropy.cabacmodel = entropy_cfg.cabacmodel; - return true; -} - -bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB -{ - venc_ioctl_msg ioctl_msg = {NULL, NULL}; - bool status = true; - struct venc_multiclicecfg multislice_cfg; - - if((Codec != OMX_IndexParamVideoH263) && (nSlicesize)){ - multislice_cfg.mslice_mode = VEN_MSLICE_CNT_MB; - multislice_cfg.mslice_size = nSlicesize; - } - else{ - multislice_cfg.mslice_mode = VEN_MSLICE_OFF; - multislice_cfg.mslice_size = 0; - } - - DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode, - multislice_cfg.mslice_size); - - ioctl_msg.in = (void*)&multislice_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd, VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed"); - status = false; - } - else - { - multislice.mslice_mode = multislice_cfg.mslice_mode; - multislice.mslice_size = nSlicesize; - } - return status; -} - -bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) -{ - venc_ioctl_msg ioctl_msg = {NULL, NULL}; - bool status = true; - struct venc_intrarefresh intraRefresh_cfg; - - // There is no disabled mode. Disabled mode is indicated by a 0 count. - if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) - { - intraRefresh_cfg.irmode = VEN_IR_OFF; - intraRefresh_cfg.mbcount = 0; - } - else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && - (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) - { - intraRefresh_cfg.irmode = VEN_IR_CYCLIC; - intraRefresh_cfg.mbcount = irMBs; - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:" - "mb count: %d, mb mode:%d", irMBs, ir_mode); - return false; - } - - ioctl_msg.in = (void*)&intraRefresh_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_INTRA_REFRESH,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra Refresh failed"); - status = false; - } - else - { - intra_refresh.irmode = intraRefresh_cfg.irmode; - intra_refresh.mbcount = intraRefresh_cfg.mbcount; - } - return status; -} - -bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) -{ - venc_ioctl_msg ioctl_msg = {NULL, NULL}; - bool status = true; - struct venc_headerextension hec_cfg; - struct venc_multiclicecfg multislice_cfg; - - if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingMPEG4) { - if (error_resilience->bEnableHEC) { - hec_cfg.header_extension = 1; - } - else { - hec_cfg.header_extension = 0; - } - - ioctl_msg.in = (void*)&hec_cfg; - ioctl_msg.out = NULL; - if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_HEC,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Request for setting HEader Error correction failed"); - return false; - } - hec.header_extension = error_resilience->bEnableHEC; - } - - if (error_resilience->bEnableRVLC) { - DEBUG_PRINT_ERROR("\n RVLC is not Supported"); - return false; - } - - if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) && - (error_resilience->bEnableDataPartitioning)) { - DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264"); - return false; - } - - if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) && - (error_resilience->nResynchMarkerSpacing)) { - multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; - multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; - } - else if (m_sVenc_cfg.codectype == OMX_VIDEO_CodingH263 && - error_resilience->bEnableDataPartitioning) { - multislice_cfg.mslice_mode = VEN_MSLICE_GOB; - multislice_cfg.mslice_size = 0; - } - else { - multislice_cfg.mslice_mode = VEN_MSLICE_OFF; - multislice_cfg.mslice_size = 0; - } - DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, multislice_cfg.mslice_mode, - multislice_cfg.mslice_size); - ioctl_msg.in = (void*)&multislice_cfg; - ioctl_msg.out = NULL; - if (ioctl (m_nDriver_fd,VEN_IOCTL_SET_MULTI_SLICE_CFG,(void*)&ioctl_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Request for setting multi-slice cfg failed"); - status = false; - } - else - { - multislice.mslice_mode = multislice_cfg.mslice_mode ; - multislice.mslice_size = multislice_cfg.mslice_size; - - } - return status; -} - -bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_dbcfg filter_cfg; - - memset(&filter_cfg, 0, sizeof(filter_cfg)); - DEBUG_PRINT_LOW("\n venc_set_inloop_filter: %u",loopfilter); - - if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){ - filter_cfg.db_mode = VEN_DB_ALL_BLKG_BNDRY; - } - else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){ - filter_cfg.db_mode = VEN_DB_DISABLE; - } - else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){ - filter_cfg.db_mode = VEN_DB_SKIP_SLICE_BNDRY; - } - filter_cfg.slicealpha_offset = filter_cfg.slicebeta_offset = 0; - - ioctl_msg.in = (void*)&filter_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_DEBLOCKING_CFG,(void*)&ioctl_msg)< 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting inloop filter failed"); - return false; - } - - dbkfilter.db_mode = filter_cfg.db_mode; - dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; - return true; -} - -bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) -{ - venc_ioctl_msg ioctl_msg = {NULL, NULL}; - struct venc_targetbitrate bitrate_cfg; - - DEBUG_PRINT_HIGH("venc_set_target_bitrate: bitrate = %u", - nTargetBitrate); - bitrate_cfg.target_bitrate = nTargetBitrate ; - ioctl_msg.in = (void*)&bitrate_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_TARGET_BITRATE,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting bit rate failed"); - return false; - } - m_sVenc_cfg.targetbitrate = nTargetBitrate; - bitrate.target_bitrate = nTargetBitrate; - if(!config) - { - m_level_set = false; - if(venc_set_profile_level(0, 0)) - { - DEBUG_PRINT_LOW("Calling set level (Bitrate) with %d\n",profile_level.level); - } - } - return true; -} - -bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) -{ - venc_ioctl_msg ioctl_msg = {NULL, NULL}; - struct venc_framerate frame_rate_cfg; - - Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); - - DEBUG_PRINT_HIGH("venc_set_encode_framerate: framerate(Q16) = %u, NR: %d, DR: %d", - encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); - - ioctl_msg.in = (void*)&frame_rate_cfg; - ioctl_msg.out = NULL; - if(ioctl(m_nDriver_fd, VEN_IOCTL_SET_FRAME_RATE, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting framerate failed"); - return false; - } - - m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; - m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; - if(!config) - { - m_level_set = false; - if(venc_set_profile_level(0, 0)) - { - DEBUG_PRINT_LOW("Calling set level (Framerate) with %d",profile_level.level); - } - } - return true; -} - -bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) -{ - venc_ioctl_msg ioctl_msg = {NULL, NULL}; - if(color_format == OMX_COLOR_FormatYUV420SemiPlanar) - { -#ifdef MAX_RES_1080P - m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; -#else - m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; -#endif - } - else - { - DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format); -#ifdef MAX_RES_1080P - m_sVenc_cfg.inputformat= VEN_INPUTFMT_NV12_16M2KA; -#else - m_sVenc_cfg.inputformat = VEN_INPUTFMT_NV12; -#endif - DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set"); - } - ioctl_msg.in = (void*)&m_sVenc_cfg; - ioctl_msg.out = NULL; - if (ioctl(m_nDriver_fd, VEN_IOCTL_SET_BASE_CFG, (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting color format failed"); - return false; - } - return true; -} - -bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) -{ - DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); - if(intra_vop_refresh == OMX_TRUE) - { - if(ioctl(m_nDriver_fd, VEN_IOCTL_CMD_REQUEST_IFRAME, NULL) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Intra VOP Refresh failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect"); - } - return true; -} - -bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - bool status = true; - struct venc_ratectrlcfg ratectrl_cfg; - - //rate control - switch(eControlRate) - { - case OMX_Video_ControlRateDisable: - ratectrl_cfg.rcmode = VEN_RC_OFF; - break; - case OMX_Video_ControlRateVariableSkipFrames: - ratectrl_cfg.rcmode = VEN_RC_VBR_VFR; - break; - case OMX_Video_ControlRateVariable: - ratectrl_cfg.rcmode = VEN_RC_VBR_CFR; - break; - case OMX_Video_ControlRateConstantSkipFrames: - ratectrl_cfg.rcmode = VEN_RC_CBR_VFR; - break; - case OMX_Video_ControlRateConstant: - ratectrl_cfg.rcmode = VEN_RC_CBR_CFR; - break; - default: - status = false; - break; - } - - if(status) - { - ioctl_msg.in = (void*)&ratectrl_cfg; - ioctl_msg.out = NULL; - if(ioctl (m_nDriver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG,(void*)&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting rate control failed"); - status = false; - } - else - rate_ctrl.rcmode = ratectrl_cfg.rcmode; - } - return status; -} - -bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) -{ - bool status = true; - if(eProfile == NULL || eLevel == NULL) - { - return false; - } - - if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) - { - switch(codec_profile.profile) - { - case VEN_PROFILE_MPEG4_SP: - *eProfile = OMX_VIDEO_MPEG4ProfileSimple; - break; - case VEN_PROFILE_MPEG4_ASP: - *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - break; - default: - *eProfile = OMX_VIDEO_MPEG4ProfileMax; - status = false; - break; - } - - if(!status) - { - return status; - } - - //profile level - switch(profile_level.level) - { - case VEN_LEVEL_MPEG4_0: - *eLevel = OMX_VIDEO_MPEG4Level0; - break; - case VEN_LEVEL_MPEG4_1: - *eLevel = OMX_VIDEO_MPEG4Level1; - break; - case VEN_LEVEL_MPEG4_2: - *eLevel = OMX_VIDEO_MPEG4Level2; - break; - case VEN_LEVEL_MPEG4_3: - *eLevel = OMX_VIDEO_MPEG4Level3; - break; - case VEN_LEVEL_MPEG4_4: - *eLevel = OMX_VIDEO_MPEG4Level4a; - break; - case VEN_LEVEL_MPEG4_5: - case VEN_LEVEL_MPEG4_6: - *eLevel = OMX_VIDEO_MPEG4Level5; - break; - default: - *eLevel = OMX_VIDEO_MPEG4LevelMax; - status = false; - break; - } - } - else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) - { - if(codec_profile.profile == VEN_PROFILE_H263_BASELINE) - { - *eProfile = OMX_VIDEO_H263ProfileBaseline; - } - else - { - *eProfile = OMX_VIDEO_H263ProfileMax; - return false; - } - switch(profile_level.level) - { - case VEN_LEVEL_H263_10: - *eLevel = OMX_VIDEO_H263Level10; - break; - case VEN_LEVEL_H263_20: - *eLevel = OMX_VIDEO_H263Level20; - break; - case VEN_LEVEL_H263_30: - *eLevel = OMX_VIDEO_H263Level30; - break; - case VEN_LEVEL_H263_40: - *eLevel = OMX_VIDEO_H263Level40; - break; - case VEN_LEVEL_H263_45: - *eLevel = OMX_VIDEO_H263Level45; - break; - case VEN_LEVEL_H263_50: - *eLevel = OMX_VIDEO_H263Level50; - break; - case VEN_LEVEL_H263_60: - *eLevel = OMX_VIDEO_H263Level60; - break; - case VEN_LEVEL_H263_70: - *eLevel = OMX_VIDEO_H263Level70; - break; - default: - *eLevel = OMX_VIDEO_H263LevelMax; - status = false; - break; - } - } - else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) - { - switch(codec_profile.profile) - { - case VEN_PROFILE_H264_BASELINE: - *eProfile = OMX_VIDEO_AVCProfileBaseline; - break; - case VEN_PROFILE_H264_MAIN: - *eProfile = OMX_VIDEO_AVCProfileMain; - break; - case VEN_PROFILE_H264_HIGH: - *eProfile = OMX_VIDEO_AVCProfileHigh; - break; - default: - *eProfile = OMX_VIDEO_AVCProfileMax; - status = false; - break; - } - - if(!status) - { - return status; - } - - switch(profile_level.level) - { - case VEN_LEVEL_H264_1: - *eLevel = OMX_VIDEO_AVCLevel1; - break; - case VEN_LEVEL_H264_1b: - *eLevel = OMX_VIDEO_AVCLevel1b; - break; - case VEN_LEVEL_H264_1p1: - *eLevel = OMX_VIDEO_AVCLevel11; - break; - case VEN_LEVEL_H264_1p2: - *eLevel = OMX_VIDEO_AVCLevel12; - break; - case VEN_LEVEL_H264_1p3: - *eLevel = OMX_VIDEO_AVCLevel13; - break; - case VEN_LEVEL_H264_2: - *eLevel = OMX_VIDEO_AVCLevel2; - break; - case VEN_LEVEL_H264_2p1: - *eLevel = OMX_VIDEO_AVCLevel21; - break; - case VEN_LEVEL_H264_2p2: - *eLevel = OMX_VIDEO_AVCLevel22; - break; - case VEN_LEVEL_H264_3: - *eLevel = OMX_VIDEO_AVCLevel3; - break; - case VEN_LEVEL_H264_3p1: - *eLevel = OMX_VIDEO_AVCLevel31; - break; - case VEN_LEVEL_H264_3p2: - *eLevel = OMX_VIDEO_AVCLevel32; - break; - case VEN_LEVEL_H264_4: - *eLevel = OMX_VIDEO_AVCLevel4; - break; - default : - *eLevel = OMX_VIDEO_AVCLevelMax; - status = false; - break; - } - } - return status; -} - -bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) -{ - OMX_U32 new_profile = 0, new_level = 0; - unsigned const int *profile_tbl = NULL; - OMX_U32 mb_per_frame, mb_per_sec; - bool profile_level_found = false; - - DEBUG_PRINT_LOW("\n Init profile table for respective codec"); - //validate the ht,width,fps,bitrate and set the appropriate profile and level - if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) - { - if(*eProfile == 0) - { - if(!m_profile_set) - { - *eProfile = OMX_VIDEO_MPEG4ProfileSimple; - } - else - { - switch(codec_profile.profile) - { - case VEN_PROFILE_MPEG4_ASP: - *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - break; - case VEN_PROFILE_MPEG4_SP: - *eProfile = OMX_VIDEO_MPEG4ProfileSimple; - break; - default: - DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); - return false; - } - } - } - - if(*eLevel == 0 && !m_level_set) - { - *eLevel = OMX_VIDEO_MPEG4LevelMax; - } - - if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple) - { - profile_tbl = (unsigned int const *)mpeg4_profile_level_table; - } - else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { - profile_tbl = (unsigned int const *) - (&mpeg4_profile_level_table[MPEG4_ASP_START]); - } - else - { - DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile); - return false; - } - } - else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) - { - if(*eProfile == 0) - { - if(!m_profile_set) - { - *eProfile = OMX_VIDEO_AVCProfileBaseline; - } - else - { - switch(codec_profile.profile) - { - case VEN_PROFILE_H264_BASELINE: - *eProfile = OMX_VIDEO_AVCProfileBaseline; - break; - case VEN_PROFILE_H264_MAIN: - *eProfile = OMX_VIDEO_AVCProfileMain; - break; - case VEN_PROFILE_H264_HIGH: - *eProfile = OMX_VIDEO_AVCProfileHigh; - break; - default: - DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); - return false; - } - } - } - - if(*eLevel == 0 && !m_level_set) - { - *eLevel = OMX_VIDEO_AVCLevelMax; - } - - if(*eProfile == OMX_VIDEO_AVCProfileBaseline) - { - profile_tbl = (unsigned int const *)h264_profile_level_table; - } - else if(*eProfile == OMX_VIDEO_AVCProfileHigh) - { - profile_tbl = (unsigned int const *) - (&h264_profile_level_table[H264_HP_START]); - } - else if(*eProfile == OMX_VIDEO_AVCProfileMain) - { - profile_tbl = (unsigned int const *) - (&h264_profile_level_table[H264_MP_START]); - } - else - { - DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile); - return false; - } - } - else if(m_sVenc_cfg.codectype == VEN_CODEC_H263) - { - if(*eProfile == 0) - { - if(!m_profile_set) - { - *eProfile = OMX_VIDEO_H263ProfileBaseline; - } - else - { - switch(codec_profile.profile) - { - case VEN_PROFILE_H263_BASELINE: - *eProfile = OMX_VIDEO_H263ProfileBaseline; - break; - default: - DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); - return false; - } - } - } - - if(*eLevel == 0 && !m_level_set) - { - *eLevel = OMX_VIDEO_H263LevelMax; - } - - if(*eProfile == OMX_VIDEO_H263ProfileBaseline) - { - profile_tbl = (unsigned int const *)h263_profile_level_table; - } - else - { - DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile); - return false; - } - } - else - { - DEBUG_PRINT_LOW("\n Invalid codec type"); - return false; - } - - mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* - ((m_sVenc_cfg.input_width + 15)>> 4); - - if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == VEN_CODEC_MPEG4)) - { - if(codec_profile.profile == VEN_PROFILE_MPEG4_ASP) - profile_level.level = VEN_LEVEL_MPEG4_5; - if(codec_profile.profile == VEN_PROFILE_MPEG4_SP) - profile_level.level = VEN_LEVEL_MPEG4_6; - { - new_level = profile_level.level; - new_profile = codec_profile.profile; - return true; - } - } - - mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; - - do{ - if(mb_per_frame <= (int)profile_tbl[0]) - { - if(mb_per_sec <= (int)profile_tbl[1]) - { - if(m_sVenc_cfg.targetbitrate <= (int)profile_tbl[2]) - { - new_level = (int)profile_tbl[3]; - new_profile = (int)profile_tbl[4]; - profile_level_found = true; - DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level); - break; - } - } - } - profile_tbl = profile_tbl + 5; - }while(profile_tbl[0] != 0); - - if (profile_level_found != true) - { - DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n"); - return false; - } - - if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) - || (*eLevel == OMX_VIDEO_H263LevelMax)) - { - *eLevel = new_level; - } - DEBUG_PRINT_LOW("%s: Returning with eProfile = %lu" - "Level = %lu", __func__, *eProfile, *eLevel); - - return true; -} - -bool venc_dev::venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate) -{ - unsigned const int *profile_tbl = NULL; - - switch(m_sVenc_cfg.codectype) - { - case VEN_CODEC_MPEG4: - if(m_eProfile == OMX_VIDEO_MPEG4ProfileSimple) - { - profile_tbl = (unsigned int const *)mpeg4_profile_level_table; - } - else if(m_eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { - profile_tbl = (unsigned int const *) - (&mpeg4_profile_level_table[MPEG4_ASP_START]); - } - else - { - DEBUG_PRINT_ERROR("Unsupported MPEG4 profile type %lu", m_eProfile); - return false; - } - break; - case VEN_CODEC_H264: - if(m_eProfile == OMX_VIDEO_AVCProfileBaseline) - { - profile_tbl = (unsigned int const *)h264_profile_level_table; - } - else if(m_eProfile == OMX_VIDEO_AVCProfileHigh) - { - profile_tbl = (unsigned int const *) - (&h264_profile_level_table[H264_HP_START]); - } - else if(m_eProfile == OMX_VIDEO_AVCProfileMain) - { - profile_tbl = (unsigned int const *) - (&h264_profile_level_table[H264_MP_START]); - } - else - { - DEBUG_PRINT_ERROR("Unsupported AVC profile type %lu", m_eProfile); - return false; - } - - break; - case VEN_CODEC_H263: - if(m_eProfile == OMX_VIDEO_H263ProfileBaseline) - { - profile_tbl = (unsigned int const *)h263_profile_level_table; - } - else - { - DEBUG_PRINT_ERROR("Unsupported H.263 profile type %lu", m_eProfile); - return false; - } - break; - default: - DEBUG_PRINT_ERROR("%s: unknown codec type", __func__); - return false; - } - while(profile_tbl[0] != 0) - { - if(profile_tbl[3] == m_eLevel) - { - if(nTargetBitrate > profile_tbl[2]) - { - DEBUG_PRINT_ERROR("Max. supported bitrate for Profile[%d] & Level[%d]" - " is %u", m_eProfile, m_eLevel, profile_tbl[2]); - return false; - } - } - profile_tbl += 5; - } - return true; -} - -#ifdef _ANDROID_ICS_ -bool venc_dev::venc_set_meta_mode(bool mode) -{ - venc_ioctl_msg ioctl_msg = {NULL,NULL}; - ioctl_msg.in = &mode; - DEBUG_PRINT_HIGH("Set meta buffer mode: %d", mode); - if(ioctl(m_nDriver_fd,VEN_IOCTL_SET_METABUFFER_MODE,&ioctl_msg) < 0) - { - DEBUG_PRINT_ERROR(" Set meta buffer mode failed"); - return false; - } - return true; -} -#endif diff --git a/mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp deleted file mode 100644 index bddd8e4c..00000000 --- a/mm-video/vidc/venc/src/video_encoder_device_v4l2.cpp +++ /dev/null @@ -1,3214 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ - -#include -#include -#include -#include -#include -#include "video_encoder_device_v4l2.h" -#include "omx_video_encoder.h" -#include -#ifdef USE_ION -#include -#endif -#include -#include - -#define EXTRADATA_IDX(__num_planes) (__num_planes - 1) - -#define MPEG4_SP_START 0 -#define MPEG4_ASP_START (MPEG4_SP_START + 10) -#define H263_BP_START 0 -#define H264_BP_START 0 -#define H264_HP_START (H264_BP_START + 17) -#define H264_MP_START (H264_BP_START + 34) -#define POLL_TIMEOUT 1000 -#define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */ - -/* MPEG4 profile and level table*/ -static const unsigned int mpeg4_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, - {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, - {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, - {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, - {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, - {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {0,0,0,0,0}, - - {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {0,0,0,0,0}, -}; - -/* H264 profile and level table*/ -static const unsigned int h264_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, - {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, - {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, - {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, - {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, - {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, - {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, - {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, - {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, - {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, - {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, - {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, - {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline}, - {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline}, - {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline}, - {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline}, - {0,0,0,0,0}, - - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, - {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, - {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, - {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, - {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, - {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, - {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, - {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, - {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, - {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, - {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, - {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, - {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh}, - {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh}, - {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh}, - {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh}, - {0,0,0,0,0}, - - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, - {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, - {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, - {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, - {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, - {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, - {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, - {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, - {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, - {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, - {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, - {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, - {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain}, - {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain}, - {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain}, - {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain}, - {0,0,0,0,0} - -}; - -/* H263 profile and level table*/ -static const unsigned int h263_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, - {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, - {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, - {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, - {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, - {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, - {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, - {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, - {0,0,0,0,0} -}; - -#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } -#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); } - -#ifdef INPUT_BUFFER_LOG -FILE *inputBufferFile1; -char inputfilename [] = "/data/input.yuv"; -#endif -#ifdef OUTPUT_BUFFER_LOG -FILE *outputBufferFile1; -char outputfilename [] = "/data/output-bitstream.\0\0\0\0"; -#endif - -//constructor -venc_dev::venc_dev(class omx_venc *venc_class) -{ - //nothing to do - int i = 0; - venc_handle = venc_class; - etb = ebd = ftb = fbd = 0; - for (i = 0; i < MAX_PORT; i++) - streaming[i] = false; - - paused = false; - async_thread_created = false; - color_format = 0; - pthread_mutex_init(&pause_resume_mlock, NULL); - pthread_cond_init(&pause_resume_cond, NULL); - memset(&extradata_info, 0, sizeof(extradata_info)); - memset(&idrperiod, 0, sizeof(idrperiod)); - memset(&multislice, 0, sizeof(multislice)); - memset (&slice_mode, 0 , sizeof(slice_mode)); - memset(&m_sVenc_cfg, 0, sizeof(m_sVenc_cfg)); - memset(&rate_ctrl, 0, sizeof(rate_ctrl)); - memset(&bitrate, 0, sizeof(bitrate)); - memset(&intra_period, 0, sizeof(intra_period)); - memset(&codec_profile, 0, sizeof(codec_profile)); - memset(&set_param, 0, sizeof(set_param)); - memset(&time_inc, 0, sizeof(time_inc)); - memset(&m_sInput_buff_property, 0, sizeof(m_sInput_buff_property)); - memset(&m_sOutput_buff_property, 0, sizeof(m_sOutput_buff_property)); - memset(&session_qp, 0, sizeof(session_qp)); - memset(&entropy, 0, sizeof(entropy)); - memset(&dbkfilter, 0, sizeof(dbkfilter)); - memset(&intra_refresh, 0, sizeof(intra_refresh)); - memset(&hec, 0, sizeof(hec)); - memset(&voptimecfg, 0, sizeof(voptimecfg)); - memset(&capability, 0, sizeof(capability)); -} - -venc_dev::~venc_dev() -{ - //nothing to do -} - -void* venc_dev::async_venc_message_thread (void *input) -{ - struct venc_msg venc_msg; - omx_video* omx_venc_base = NULL; - omx_venc *omx = reinterpret_cast(input); - omx_venc_base = reinterpret_cast(input); - OMX_BUFFERHEADERTYPE* omxhdr = NULL; - - prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0); - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - struct pollfd pfd; - struct v4l2_buffer v4l2_buf; - struct v4l2_event dqevent; - pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI; - pfd.fd = omx->handle->m_nDriver_fd; - int error_code = 0,rc=0; - - memset(&v4l2_buf, 0, sizeof(v4l2_buf)); - while(1) - { - pthread_mutex_lock(&omx->handle->pause_resume_mlock); - if (omx->handle->paused) { - venc_msg.msgcode = VEN_MSG_PAUSE; - venc_msg.statuscode = VEN_S_SUCCESS; - if(omx->async_message_process(input, &venc_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Failed to process pause msg"); - pthread_mutex_unlock(&omx->handle->pause_resume_mlock); - break; - } - - /* Block here until the IL client resumes us again */ - pthread_cond_wait(&omx->handle->pause_resume_cond, - &omx->handle->pause_resume_mlock); - - venc_msg.msgcode = VEN_MSG_RESUME; - venc_msg.statuscode = VEN_S_SUCCESS; - if(omx->async_message_process(input, &venc_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Failed to process resume msg"); - pthread_mutex_unlock(&omx->handle->pause_resume_mlock); - break; - } - } - pthread_mutex_unlock(&omx->handle->pause_resume_mlock); - - rc = poll(&pfd, 1, POLL_TIMEOUT); - if (!rc) { - DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d\n", - omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd); - continue; - } else if (rc < 0) { - DEBUG_PRINT_ERROR("Error while polling: %d\n", rc); - break; - } - - if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) { - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - v4l2_buf.memory = V4L2_MEMORY_USERPTR; - v4l2_buf.length = omx->handle->num_planes; - v4l2_buf.m.planes = plane; - while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { - venc_msg.msgcode=VEN_MSG_OUTPUT_BUFFER_DONE; - venc_msg.statuscode=VEN_S_SUCCESS; - omxhdr=omx_venc_base->m_out_mem_ptr+v4l2_buf.index; - venc_msg.buf.len= v4l2_buf.m.planes->bytesused; - venc_msg.buf.offset = 0; - venc_msg.buf.flags = 0; - venc_msg.buf.ptrbuffer = (OMX_U8 *)omx_venc_base->m_pOutput_pmem[v4l2_buf.index].buffer; - venc_msg.buf.clientdata=(void*)omxhdr; - venc_msg.buf.timestamp = (uint64_t) v4l2_buf.timestamp.tv_sec * (uint64_t) 1000000 + (uint64_t) v4l2_buf.timestamp.tv_usec; - /* TODO: ideally report other types of frames as well - * for now it doesn't look like IL client cares about - * other types - */ - if (v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) - venc_msg.buf.flags |= QOMX_VIDEO_PictureTypeIDR; - if (v4l2_buf.flags & V4L2_BUF_FLAG_KEYFRAME) - venc_msg.buf.flags |= OMX_BUFFERFLAG_SYNCFRAME; - if(v4l2_buf.flags & V4L2_QCOM_BUF_FLAG_CODECCONFIG) - venc_msg.buf.flags |= OMX_BUFFERFLAG_CODECCONFIG; - if(v4l2_buf.flags & V4L2_BUF_FLAG_EOS) - venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS; - if(omx->handle->num_planes > 1 && v4l2_buf.m.planes->bytesused) - venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA; - omx->handle->fbd++; - if(omx->async_message_process(input,&venc_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); - break; - } - } - } - if((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) { - v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - v4l2_buf.memory = V4L2_MEMORY_USERPTR; - v4l2_buf.m.planes = plane; - v4l2_buf.length = 1; - while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) { - venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE; - venc_msg.statuscode=VEN_S_SUCCESS; - omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index; - venc_msg.buf.clientdata=(void*)omxhdr; - omx->handle->ebd++; - if(omx->async_message_process(input,&venc_msg) < 0) - { - DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); - break; - } - } - } - if (pfd.revents & POLLPRI) { - rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent); - if(dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) { - DEBUG_PRINT_HIGH("CLOSE DONE\n"); - break; - } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) { - venc_msg.msgcode = VEN_MSG_FLUSH_INPUT_DONE; - venc_msg.statuscode = VEN_S_SUCCESS; - if (omx->async_message_process(input,&venc_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); - break; - } - venc_msg.msgcode = VEN_MSG_FLUSH_OUPUT_DONE; - venc_msg.statuscode = VEN_S_SUCCESS; - if (omx->async_message_process(input,&venc_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); - break; - } - } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){ - DEBUG_PRINT_ERROR("\n HW Error recieved \n"); - venc_msg.statuscode=VEN_S_EFAIL; - if (omx->async_message_process(input,&venc_msg) < 0) { - DEBUG_PRINT_ERROR("\nERROR: Wrong ioctl message"); - break; - } - } - } - } - DEBUG_PRINT_HIGH("omx_venc: Async Thread exit\n"); - return NULL; -} - -static const int event_type[] = { - V4L2_EVENT_MSM_VIDC_FLUSH_DONE, - V4L2_EVENT_MSM_VIDC_CLOSE_DONE, - V4L2_EVENT_MSM_VIDC_SYS_ERROR -}; - -static OMX_ERRORTYPE subscribe_to_events(int fd) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_event_subscription sub; - int array_sz = sizeof(event_type)/sizeof(int); - int i,rc; - memset(&sub, 0, sizeof(sub)); - if (fd < 0) { - printf("Invalid input: %d\n", fd); - return OMX_ErrorBadParameter; - } - - for (i = 0; i < array_sz; ++i) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub); - if (rc) { - printf("Failed to subscribe event: 0x%x\n", sub.type); - break; - } - } - if (i < array_sz) { - for (--i; i >=0 ; i--) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); - if (rc) - printf("Failed to unsubscribe event: 0x%x\n", sub.type); - } - eRet = OMX_ErrorNotImplemented; - } - return eRet; -} - -bool venc_dev::handle_extradata(void *buffer, int index) -{ - OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer; - OMX_OTHER_EXTRADATATYPE *p_extra = NULL; - if (!extradata_info.uaddr) { - DEBUG_PRINT_ERROR("Extradata buffers not allocated\n"); - return false; - } - p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned)(p_bufhdr->pBuffer + p_bufhdr->nOffset + p_bufhdr->nFilledLen + 3)&(~3)); - char *p_extradata = extradata_info.uaddr + index * extradata_info.buffer_size; - if ((OMX_U8*)p_extra > (p_bufhdr->pBuffer + p_bufhdr->nAllocLen)){ - DEBUG_PRINT_ERROR("Insufficient buffer size\n"); - p_extra = NULL; - return false; - } - memcpy(p_extra, p_extradata, extradata_info.buffer_size); - return true; -} - -int venc_dev::venc_set_format(int format) -{ - int rc = true; - if (format) - color_format = format; - else - { - color_format = 0; - rc = false; - } - return rc; -} - -OMX_ERRORTYPE venc_dev::allocate_extradata() -{ - if (extradata_info.allocated) { - DEBUG_PRINT_ERROR("2nd allocation return"); - return OMX_ErrorNone; - } -#ifdef USE_ION - if (extradata_info.buffer_size) { - if (extradata_info.ion.ion_alloc_data.handle) { - munmap((void *)extradata_info.uaddr, extradata_info.size); - close(extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&extradata_info.ion); - } - extradata_info.size = (extradata_info.size + 4095) & (~4095); - - extradata_info.ion.ion_device_fd = alloc_map_ion_memory( - extradata_info.size, - &extradata_info.ion.ion_alloc_data, - &extradata_info.ion.fd_ion_data, 0); - if (extradata_info.ion.ion_device_fd < 0) { - DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n"); - return OMX_ErrorInsufficientResources; - } - extradata_info.uaddr = (char *)mmap(NULL, - extradata_info.size, - PROT_READ|PROT_WRITE, MAP_SHARED, - extradata_info.ion.fd_ion_data.fd , 0); - if (extradata_info.uaddr == MAP_FAILED) { - DEBUG_PRINT_ERROR("Failed to map extradata memory\n"); - close(extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&extradata_info.ion); - return OMX_ErrorInsufficientResources; - } - } -#endif - extradata_info.allocated = 1; - return OMX_ErrorNone; -} - -void venc_dev::free_extradata() { -#ifdef USE_ION - if (extradata_info.uaddr) { - munmap((void *)extradata_info.uaddr, extradata_info.size); - close(extradata_info.ion.fd_ion_data.fd); - free_ion_memory(&extradata_info.ion); - } - memset(&extradata_info, 0, sizeof(extradata_info)); -#endif -} - -bool venc_dev::venc_open(OMX_U32 codec) -{ - int r; - unsigned int alignment = 0,buffer_size = 0, temp =0; - struct v4l2_control control; - OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc"; - - char platform_name[64]; - property_get("ro.board.platform", platform_name, "0"); - if (!strncmp(platform_name, "msm8610", 7)) { - device_name = (OMX_STRING)"/dev/video/q6_enc"; - } - - m_nDriver_fd = open (device_name, O_RDWR); - if(m_nDriver_fd == 0) - { - DEBUG_PRINT_ERROR("ERROR: Got fd as 0 for msm_vidc_enc, Opening again\n"); - m_nDriver_fd = open (device_name, O_RDWR); - } - - if((int)m_nDriver_fd < 0) - { - DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure\n"); - return false; - } - - DEBUG_PRINT_LOW("\nm_nDriver_fd = %d\n", m_nDriver_fd); - // set the basic configuration of the video encoder driver - m_sVenc_cfg.input_width = OMX_CORE_QCIF_WIDTH; - m_sVenc_cfg.input_height= OMX_CORE_QCIF_HEIGHT; - m_sVenc_cfg.dvs_width = OMX_CORE_QCIF_WIDTH; - m_sVenc_cfg.dvs_height = OMX_CORE_QCIF_HEIGHT; - m_sVenc_cfg.fps_num = 30; - m_sVenc_cfg.fps_den = 1; - m_sVenc_cfg.targetbitrate = 64000; - m_sVenc_cfg.inputformat= V4L2_PIX_FMT_NV12; - if(codec == OMX_VIDEO_CodingMPEG4) - { - m_sVenc_cfg.codectype = V4L2_PIX_FMT_MPEG4; - codec_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; - profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; -#ifdef OUTPUT_BUFFER_LOG - strcat(outputfilename, "m4v"); -#endif - } - else if(codec == OMX_VIDEO_CodingH263) - { - m_sVenc_cfg.codectype = V4L2_PIX_FMT_H263; - codec_profile.profile = VEN_PROFILE_H263_BASELINE; - profile_level.level = VEN_LEVEL_H263_20; -#ifdef OUTPUT_BUFFER_LOG - strcat(outputfilename, "263"); -#endif - } - if(codec == OMX_VIDEO_CodingAVC) - { - m_sVenc_cfg.codectype = V4L2_PIX_FMT_H264; - codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; - profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; -#ifdef OUTPUT_BUFFER_LOG - strcat(outputfilename, "264"); -#endif - } -if (codec == OMX_VIDEO_CodingVPX) - { - m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8; - codec_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; - profile_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; -#ifdef OUTPUT_BUFFER_LOG - strcat(outputfilename, "ivf"); -#endif - } -#ifdef INPUT_BUFFER_LOG - inputBufferFile1 = fopen (inputfilename, "ab"); - if (!inputBufferFile1) - DEBUG_PRINT_ERROR("Input File open failed"); -#endif -#ifdef OUTPUT_BUFFER_LOG - outputBufferFile1 = fopen (outputfilename, "ab"); -#endif - int ret; - ret = subscribe_to_events(m_nDriver_fd); - if (ret) { - DEBUG_PRINT_ERROR("\n Subscribe Event Failed \n"); - return false; - } - struct v4l2_capability cap; - struct v4l2_fmtdesc fdesc; - struct v4l2_format fmt; - struct v4l2_requestbuffers bufreq; - - ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap); - if (ret) { - DEBUG_PRINT_ERROR("Failed to query capabilities\n"); - } else { - DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s," - " version = %d, capabilities = %x\n", cap.driver, cap.card, - cap.bus_info, cap.version, cap.capabilities); - } - ret=0; - fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fdesc.index=0; - while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { - DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, - fdesc.pixelformat, fdesc.flags); - fdesc.index++; - } - fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fdesc.index=0; - while (ioctl(m_nDriver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) { - DEBUG_PRINT_LOW("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description, - fdesc.pixelformat, fdesc.flags); - fdesc.index++; - } - - m_sOutput_buff_property.alignment=m_sInput_buff_property.alignment=4096; - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; - - /*TODO: Return values not handled properly in this function anywhere. - * Need to handle those.*/ - ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); - if (ret) { - DEBUG_PRINT_ERROR("Failed to set format on capture port\n"); - return false; - } - m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; - - ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); - m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = 2; - - bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); - m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; - - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - bufreq.count = 2; - ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); - m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; - - - stopped = 0; - metadatamode = 0; - - control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE; - control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE; - - DEBUG_PRINT_LOW("Calling IOCTL to disable seq_hdr in sync_frame id=%d, val=%d\n", control.id, control.value); - if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) - DEBUG_PRINT_ERROR("Failed to set control\n"); - - struct v4l2_frmsizeenum frmsize; - - //Get the hardware capabilities - memset((void *)&frmsize,0,sizeof(frmsize)); - frmsize.index = 0; - frmsize.pixel_format = m_sVenc_cfg.codectype; - ret = ioctl(m_nDriver_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize); - if(ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) { - DEBUG_PRINT_ERROR("Failed to get framesizes\n"); - return false; - } - - if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) { - capability.min_width = frmsize.stepwise.min_width; - capability.max_width = frmsize.stepwise.max_width; - capability.min_height = frmsize.stepwise.min_height; - capability.max_height = frmsize.stepwise.max_height; - } - - return true; -} - - -static OMX_ERRORTYPE unsubscribe_to_events(int fd) -{ - OMX_ERRORTYPE eRet = OMX_ErrorNone; - struct v4l2_event_subscription sub; - int array_sz = sizeof(event_type)/sizeof(int); - int i,rc; - if (fd < 0) { - printf("Invalid input: %d\n", fd); - return OMX_ErrorBadParameter; - } - - for (i = 0; i < array_sz; ++i) { - memset(&sub, 0, sizeof(sub)); - sub.type = event_type[i]; - rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); - if (rc) { - printf("Failed to unsubscribe event: 0x%x\n", sub.type); - break; - } - } - return eRet; -} - -void venc_dev::venc_close() -{ - struct v4l2_encoder_cmd enc; - DEBUG_PRINT_LOW("\nvenc_close: fd = %d", m_nDriver_fd); - if((int)m_nDriver_fd >= 0) - { - enc.cmd = V4L2_ENC_CMD_STOP; - ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc); - DEBUG_PRINT_HIGH("venc_close E\n"); - if (async_thread_created) - pthread_join(m_tid,NULL); - DEBUG_PRINT_HIGH("venc_close X\n"); - unsubscribe_to_events(m_nDriver_fd); - close(m_nDriver_fd); - m_nDriver_fd = -1; - } -#ifdef INPUT_BUFFER_LOG - fclose (inputBufferFile1); -#endif -#ifdef OUTPUT_BUFFER_LOG - fclose (outputBufferFile1); -#endif -} - -bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count, - unsigned long *actual_buff_count, - unsigned long *buff_size, - unsigned long port) -{ - - unsigned long temp_count = 0; - - if(port == 0) - { - if(*actual_buff_count > m_sInput_buff_property.mincount) - { - temp_count = m_sInput_buff_property.actualcount; - m_sInput_buff_property.actualcount = *actual_buff_count; - DEBUG_PRINT_LOW("\n I/P Count set to %lu\n", *actual_buff_count); - } - } - else - { - if(*actual_buff_count > m_sOutput_buff_property.mincount) - { - temp_count = m_sOutput_buff_property.actualcount; - m_sOutput_buff_property.actualcount = *actual_buff_count; - DEBUG_PRINT_LOW("\n O/P Count set to %lu\n", *actual_buff_count); - } - } - - return true; - -} - -bool venc_dev::venc_loaded_start() -{ - return true; -} - -bool venc_dev::venc_loaded_stop() -{ - return true; -} - -bool venc_dev::venc_loaded_start_done() -{ - return true; -} - -bool venc_dev::venc_loaded_stop_done() -{ - return true; -} - -bool venc_dev::venc_get_seq_hdr(void *buffer, - unsigned buffer_size, unsigned *header_len) -{ - return true; -} - -bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count, - unsigned long *actual_buff_count, - unsigned long *buff_size, - unsigned long port) -{ - struct v4l2_format fmt; - struct v4l2_requestbuffers bufreq; - unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0; - int ret; - if(port == 0) - { - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; - ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); - m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - bufreq.memory = V4L2_MEMORY_USERPTR; - if (*actual_buff_count) - bufreq.count = *actual_buff_count; - else - bufreq.count = 2; - bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); - if (ret) { - DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n "); - return false; - } - m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; - *min_buff_count = m_sInput_buff_property.mincount; - *actual_buff_count = m_sInput_buff_property.actualcount; -#ifdef USE_ION -// For ION memory allocations of the allocated buffer size -// must be 4k aligned, hence aligning the input buffer -// size to 4k. - m_sInput_buff_property.datasize = (m_sInput_buff_property.datasize + 4095) & (~4095); -#endif - *buff_size = m_sInput_buff_property.datasize; - } - else - { - int extra_idx = 0; - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; - - ret = ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt); - m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; - - ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt); - m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - bufreq.memory = V4L2_MEMORY_USERPTR; - if (*actual_buff_count) - bufreq.count = *actual_buff_count; - else - bufreq.count = 2; - bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq); - if (ret) { - DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS CAPTURE_MPLANE Failed \n "); - return false; - } - m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; - *min_buff_count = m_sOutput_buff_property.mincount; - *actual_buff_count = m_sOutput_buff_property.actualcount; - *buff_size = m_sOutput_buff_property.datasize; - num_planes = fmt.fmt.pix_mp.num_planes; - extra_idx = EXTRADATA_IDX(num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - extradata_info.buffer_size = extra_data_size; - extradata_info.count = m_sOutput_buff_property.actualcount; - extradata_info.size = extradata_info.buffer_size * extradata_info.count; - } - return true; -} - -bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index ) -{ - DEBUG_PRINT_LOW("venc_set_param:: venc-720p\n"); - struct v4l2_format fmt; - struct v4l2_requestbuffers bufreq; - int ret; - switch(index) - { - case OMX_IndexParamPortDefinition: - { - OMX_PARAM_PORTDEFINITIONTYPE *portDefn; - portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamPortDefinition\n"); - if(portDefn->nPortIndex == PORT_INDEX_IN) - { - if(!venc_set_encode_framerate(portDefn->format.video.xFramerate, 0)) - { - return false; - } - if(!venc_set_color_format(portDefn->format.video.eColorFormat)) - { - return false; - } - if(m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight || - m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) - { - DEBUG_PRINT_LOW("\n Basic parameter has changed"); - m_sVenc_cfg.input_height = portDefn->format.video.nFrameHeight; - m_sVenc_cfg.input_width = portDefn->format.video.nFrameWidth; - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_NV12; - if(ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { - DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT OUTPUT_MPLANE Failed \n "); - return false; - } - m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = portDefn->nBufferCountActual; - bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) { - DEBUG_PRINT_ERROR("\n VIDIOC_REQBUFS OUTPUT_MPLANE Failed \n "); - return false; - } - if(bufreq.count == portDefn->nBufferCountActual) - m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = bufreq.count; - if(portDefn->nBufferCountActual >= m_sInput_buff_property.mincount) - m_sInput_buff_property.actualcount = portDefn->nBufferCountActual; - } - DEBUG_PRINT_LOW("input: actual: %d, min: %d, count_req: %d\n", - portDefn->nBufferCountActual, m_sInput_buff_property.mincount, bufreq.count); - } - else if(portDefn->nPortIndex == PORT_INDEX_OUT) - { - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype; - if(ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { - DEBUG_PRINT_ERROR("\n VIDIOC_S_FMT CAPTURE_MPLANE Failed \n "); - return false; - } - m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage; - - if(!venc_set_target_bitrate(portDefn->format.video.nBitrate, 0)) - { - return false; - } - - if((portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) - && (m_sOutput_buff_property.datasize == portDefn->nBufferSize)) - { - m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; - bufreq.memory = V4L2_MEMORY_USERPTR; - bufreq.count = portDefn->nBufferCountActual; - bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting o/p buffer count failed: requested: %lu, current: %lu", - portDefn->nBufferCountActual, m_sOutput_buff_property.actualcount); - return false; - } - if(bufreq.count == portDefn->nBufferCountActual) - m_sOutput_buff_property.mincount = m_sOutput_buff_property.actualcount = bufreq.count; - if(portDefn->nBufferCountActual >= m_sOutput_buff_property.mincount) - m_sOutput_buff_property.actualcount = portDefn->nBufferCountActual; - if (num_planes > 1) - extradata_info.count = m_sOutput_buff_property.actualcount; - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Setting Output buffer requirements failed"); - return false; - } - DEBUG_PRINT_LOW("Output: actual: %d, min: %d, count_req: %d\n", - portDefn->nBufferCountActual, m_sOutput_buff_property.mincount, bufreq.count); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamPortDefinition"); - } - break; - } - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt; - portFmt =(OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoPortFormat\n"); - - if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) - { - if(!venc_set_color_format(portFmt->eColorFormat)) - { - return false; - } - } - else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(!venc_set_encode_framerate(portFmt->xFramerate, 0)) - { - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat"); - } - break; - } - case OMX_IndexParamVideoBitrate: - { - OMX_VIDEO_PARAM_BITRATETYPE* pParam; - pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate\n"); - - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) - { - DEBUG_PRINT_ERROR("\nERROR: Target Bit Rate setting failed"); - return false; - } - if(!venc_set_ratectrl_cfg(pParam->eControlRate)) - { - DEBUG_PRINT_ERROR("\nERROR: Rate Control setting failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoBitrate"); - } - break; - } - case OMX_IndexParamVideoMpeg4: - { - OMX_VIDEO_PARAM_MPEG4TYPE* pParam; - OMX_U32 bFrames = 0; - - pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoMpeg4\n"); - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(!venc_set_voptiming_cfg(pParam->nTimeIncRes)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting vop_timing failed"); - return false; - } - m_profile_set = false; - m_level_set = false; - if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); - return false; - } - else { - if(pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - bFrames = 1; - } - } - else - { - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - bFrames = 0; - } - } - } - if(!venc_set_intra_period (pParam->nPFrames,bFrames)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - if(!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating slice_config"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoMpeg4"); - } - break; - } - case OMX_IndexParamVideoH263: - { - OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoH263\n"); - OMX_U32 bFrames = 0; - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - m_profile_set = false; - m_level_set = false; - if(!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level"); - return false; - } - if (pParam->nBFrames) - DEBUG_PRINT_ERROR("\nWARNING: B frame not supported for H.263"); - - if(venc_set_intra_period (pParam->nPFrames, bFrames) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoH263"); - } - break; - } - case OMX_IndexParamVideoAvc: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc\n"); - OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; - OMX_U32 bFrames = 0; - - if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - DEBUG_PRINT_LOW("pParam->eProfile :%d ,pParam->eLevel %d\n", - pParam->eProfile,pParam->eLevel); - - m_profile_set = false; - m_level_set = false; - - if(!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) - { - DEBUG_PRINT_ERROR("\nERROR: Unsuccessful in updating Profile and level %d, %d", - pParam->eProfile, pParam->eLevel); - return false; - } - else { - if(pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) - { - if(pParam->nBFrames) - { - DEBUG_PRINT_HIGH("INFO: Only 1 Bframe is supported"); - bFrames = 1; - } - } - else - { - if(pParam->nBFrames) - { - DEBUG_PRINT_ERROR("Warning: B frames not supported\n"); - bFrames = 0; - } - } - } - if(!venc_set_intra_period (pParam->nPFrames, bFrames)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - if(!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Entropy failed"); - return false; - } - if(!venc_set_inloop_filter (pParam->eLoopFilterMode)) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting Inloop filter failed"); - return false; - } - if(!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) - { - DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating slice_config"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoAvc"); - } - //TBD, lot of other variables to be updated, yet to decide - break; - } - case OMX_IndexParamVideoIntraRefresh: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh\n"); - OMX_VIDEO_PARAM_INTRAREFRESHTYPE *intra_refresh = - (OMX_VIDEO_PARAM_INTRAREFRESHTYPE *)paramData; - if(intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_intra_refresh(intra_refresh->eRefreshMode, intra_refresh->nCirMBs) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh"); - } - break; - } - case OMX_IndexParamVideoErrorCorrection: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection\n"); - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *error_resilience = - (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE *)paramData; - if(error_resilience->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_error_resilience(error_resilience) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Intra refresh failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection"); - } - break; - } - case OMX_IndexParamVideoProfileLevelCurrent: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent\n"); - OMX_VIDEO_PARAM_PROFILELEVELTYPE *profile_level = - (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData; - if(profile_level->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - m_profile_set = false; - m_level_set = false; - if(!venc_set_profile_level (profile_level->eProfile, - profile_level->eLevel)) - { - DEBUG_PRINT_ERROR("\nWARNING: Unsuccessful in updating Profile and level"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent"); - } - break; - } - case OMX_IndexParamVideoQuantization: - { - DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization\n"); - OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = - (OMX_VIDEO_PARAM_QUANTIZATIONTYPE *)paramData; - if(session_qp->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_session_qp (session_qp->nQpI, - session_qp->nQpP, - session_qp->nQpB) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Session QP failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexParamVideoQuantization"); - } - break; - } - case OMX_QcomIndexEnableSliceDeliveryMode: - { - QOMX_EXTNINDEX_PARAMTYPE* pParam = - (QOMX_EXTNINDEX_PARAMTYPE*)paramData; - if(pParam->nPortIndex == PORT_INDEX_OUT) - { - if(venc_set_slice_delivery_mode(pParam->bEnable) == false) - { - DEBUG_PRINT_ERROR("Setting slice delivery mode failed"); - return OMX_ErrorUnsupportedSetting; - } - } - else - { - DEBUG_PRINT_ERROR("OMX_QcomIndexEnableSliceDeliveryMode " - "called on wrong port(%d)", pParam->nPortIndex); - return OMX_ErrorBadPortIndex; - } - break; - } - case OMX_ExtraDataVideoEncoderSliceInfo: - { - DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo"); - OMX_U32 extra_data = *(OMX_U32 *)paramData; - if(venc_set_extradata(extra_data) == false) - { - DEBUG_PRINT_ERROR("ERROR: Setting " - "OMX_ExtraDataVideoEncoderSliceInfo failed"); - return false; - } - extradata = true; - break; - } - case OMX_IndexParamVideoSliceFMO: - default: - DEBUG_PRINT_ERROR("\nERROR: Unsupported parameter in venc_set_param: %u", - index); - break; - //case - } - - return true; -} - -bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index) -{ - - DEBUG_PRINT_LOW("\n Inside venc_set_config"); - - switch(index) - { - case OMX_IndexConfigVideoBitrate: - { - OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *) - configData; - DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoBitrate"); - if(bit_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(venc_set_target_bitrate(bit_rate->nEncodeBitrate, 1) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Target Bit rate failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate"); - } - break; - } - case OMX_IndexConfigVideoFramerate: - { - OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *) - configData; - DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoFramerate"); - if(frame_rate->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(venc_set_encode_framerate(frame_rate->xEncodeFramerate, 1) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); - } - break; - } - case QOMX_IndexConfigVideoIntraperiod: - { - DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod\n"); - QOMX_VIDEO_INTRAPERIODTYPE *intraperiod = - (QOMX_VIDEO_INTRAPERIODTYPE *)configData; - if(intraperiod->nPortIndex == (OMX_U32) PORT_INDEX_OUT) - { - if(venc_set_intra_period(intraperiod->nPFrames, intraperiod->nBFrames) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - } - break; - } - case OMX_IndexConfigVideoIntraVOPRefresh: - { - OMX_CONFIG_INTRAREFRESHVOPTYPE *intra_vop_refresh = (OMX_CONFIG_INTRAREFRESHVOPTYPE *) - configData; - DEBUG_PRINT_LOW("\n venc_set_config: OMX_IndexConfigVideoIntraVOPRefresh"); - if(intra_vop_refresh->nPortIndex == (OMX_U32)PORT_INDEX_OUT) - { - if(venc_set_intra_vop_refresh(intra_vop_refresh->IntraRefreshVOP) == false) - { - DEBUG_PRINT_ERROR("\nERROR: Setting Encode Framerate failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate"); - } - break; - } - case OMX_IndexConfigCommonRotate: - { - OMX_CONFIG_ROTATIONTYPE *config_rotation = - reinterpret_cast(configData); - OMX_U32 nFrameWidth; - - DEBUG_PRINT_HIGH("\nvenc_set_config: updating the new Dims"); - nFrameWidth = m_sVenc_cfg.input_width; - m_sVenc_cfg.input_width = m_sVenc_cfg.input_height; - m_sVenc_cfg.input_height = nFrameWidth; - if(/*ioctl (m_nDriver_fd,VEN_IOCTL_SET_BASE_CFG,(void*)&ioctl_msg) < */0) { - DEBUG_PRINT_ERROR("\nERROR: Dimension Change for Rotation failed"); - return false; - } - break; - } - case OMX_IndexConfigVideoAVCIntraPeriod: - { - OMX_VIDEO_CONFIG_AVCINTRAPERIOD *avc_iperiod = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD*) configData; - DEBUG_PRINT_LOW("venc_set_param: OMX_IndexConfigVideoAVCIntraPeriod"); - if(venc_set_idr_period(avc_iperiod->nPFrames, avc_iperiod->nIDRPeriod) - == false) - { - DEBUG_PRINT_ERROR("ERROR: Setting " - "OMX_IndexConfigVideoAVCIntraPeriod failed"); - return false; - } - break; - } - default: - DEBUG_PRINT_ERROR("\n Unsupported config index = %u", index); - break; - } - - return true; -} - -unsigned venc_dev::venc_stop( void) -{ - struct venc_msg venc_msg; - int rc = 0; - if(!stopped) { - enum v4l2_buf_type cap_type; - if (streaming[OUTPUT_PORT]) { - cap_type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); - if (rc) { - DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n", - cap_type, rc); - } else - streaming[OUTPUT_PORT] = false; - } - if (!rc && streaming[CAPTURE_PORT]) { - cap_type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - rc = ioctl(m_nDriver_fd, VIDIOC_STREAMOFF, &cap_type); - if (rc) { - DEBUG_PRINT_ERROR("Failed to call streamoff on driver: capability: %d, %d\n", - cap_type, rc); - } else - streaming[CAPTURE_PORT] = false; - } - if (!rc) { - venc_stop_done(); - stopped = 1; - } - } - return rc; -} - -unsigned venc_dev::venc_pause(void) -{ - pthread_mutex_lock(&pause_resume_mlock); - paused = true; - pthread_mutex_unlock(&pause_resume_mlock); - return 0; -} - -unsigned venc_dev::venc_resume(void) -{ - pthread_mutex_lock(&pause_resume_mlock); - paused = false; - pthread_mutex_unlock(&pause_resume_mlock); - - return pthread_cond_signal(&pause_resume_cond); -} - -unsigned venc_dev::venc_start_done(void) -{ - struct venc_msg venc_msg; - venc_msg.msgcode = VEN_MSG_START; - venc_msg.statuscode = VEN_S_SUCCESS; - venc_handle->async_message_process(venc_handle,&venc_msg); - return 0; -} - -unsigned venc_dev::venc_stop_done(void) -{ - struct venc_msg venc_msg; - free_extradata(); - venc_msg.msgcode=VEN_MSG_STOP; - venc_msg.statuscode=VEN_S_SUCCESS; - venc_handle->async_message_process(venc_handle,&venc_msg); - return 0; -} - -unsigned venc_dev::venc_set_message_thread_id(pthread_t tid) -{ - async_thread_created = true; - m_tid=tid; - return 0; -} - - -unsigned venc_dev::venc_start(void) -{ - enum v4l2_buf_type buf_type; - int ret,r; - DEBUG_PRINT_HIGH("\n %s(): Check Profile/Level set in driver before start", - __func__); - if (!venc_set_profile_level(0, 0)) - { - DEBUG_PRINT_ERROR("\n ERROR: %s(): Driver Profile/Level is NOT SET", - __func__); - } - else - { - DEBUG_PRINT_HIGH("\n %s(): Driver Profile[%lu]/Level[%lu] successfully SET", - __func__, codec_profile.profile, profile_level.level); - } - venc_config_print(); - /* Check if slice_delivery mode is enabled & max slices is sufficient for encoding complete frame */ - if (slice_mode.enable && multislice.mslice_size && - (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) { - DEBUG_PRINT_ERROR("slice_mode: %d, max slices (%d) should be less than (%d)\n", slice_mode.enable, - (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)/(256 * multislice.mslice_size), - MAX_SUPPORTED_SLICES_PER_FRAME); - return 1; - } - - buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n"); - ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type); - - if (ret) - return 1; - - streaming[CAPTURE_PORT] = true; - return 0; -} - -void venc_dev::venc_config_print() -{ - - DEBUG_PRINT_HIGH("\nENC_CONFIG: Codec: %ld, Profile %ld, level : %ld", - m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level); - - DEBUG_PRINT_HIGH("\n ENC_CONFIG: Width: %ld, Height:%ld, Fps: %ld", - m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, - m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld", - bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld", - session_qp.iframeqp, session_qp.pframqp,session_qp.bframqp); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld", - voptimecfg.voptime_resolution, multislice.mslice_mode, - multislice.mslice_size); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: EntropyMode: %d, CabacModel: %ld", - entropy.longentropysel, entropy.cabacmodel); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld\n", - dbkfilter.db_mode, dbkfilter.slicealpha_offset, - dbkfilter.slicebeta_offset); - - DEBUG_PRINT_HIGH("\nENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld\n", - intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod); - -} - -unsigned venc_dev::venc_flush( unsigned port) -{ - struct v4l2_encoder_cmd enc; - DEBUG_PRINT_LOW("in %s", __func__); - - enc.cmd = V4L2_ENC_QCOM_CMD_FLUSH; - enc.flags = V4L2_QCOM_CMD_FLUSH_OUTPUT | V4L2_QCOM_CMD_FLUSH_CAPTURE; - - if (ioctl(m_nDriver_fd, VIDIOC_ENCODER_CMD, &enc)) - { - DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", port); - return -1; - } - return 0; - -} - -//allocating I/P memory from pmem and register with the device - - -bool venc_dev::venc_use_buf(void *buf_addr, unsigned port,unsigned index) -{ - - struct pmem *pmem_tmp; - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - int rc = 0, extra_idx; - - pmem_tmp = (struct pmem *)buf_addr; - DEBUG_PRINT_LOW("\n venc_use_buf:: pmem_tmp = %p", pmem_tmp); - - if(port == PORT_INDEX_IN) - { - buf.index = index; - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].length = pmem_tmp->size; - plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; - plane[0].reserved[0] = pmem_tmp->fd; - plane[0].reserved[1] = 0; - plane[0].data_offset = pmem_tmp->offset; - buf.m.planes = plane; - buf.length = 1; - - rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); - if (rc) - DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n"); - } - else if(port == PORT_INDEX_OUT) - { - extra_idx = EXTRADATA_IDX(num_planes); - if ((num_planes > 1) && (extra_idx)) { - rc = allocate_extradata(); - if (rc) - DEBUG_PRINT_ERROR("Failed to allocate extradata: %d\n", rc); - } - buf.index = index; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].length = pmem_tmp->size; - plane[0].m.userptr = (unsigned long)pmem_tmp->buffer; - plane[0].reserved[0] = pmem_tmp->fd; - plane[0].reserved[1] = 0; - plane[0].data_offset = pmem_tmp->offset; - buf.m.planes = plane; - buf.length = num_planes; - - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].length = extradata_info.buffer_size; - plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx); - return OMX_ErrorBadParameter; - } - rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf); - if (rc) - DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed\n"); - } else { - DEBUG_PRINT_ERROR("\nERROR: venc_use_buf:Invalid Port Index "); - return false; - } - return true; -} - -bool venc_dev::venc_free_buf(void *buf_addr, unsigned port) -{ - struct pmem *pmem_tmp; - struct venc_bufferpayload dev_buffer; - - memset(&dev_buffer, 0, sizeof(dev_buffer)); - pmem_tmp = (struct pmem *)buf_addr; - - if(port == PORT_INDEX_IN) - { - dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; - dev_buffer.fd = pmem_tmp->fd; - dev_buffer.maped_size = pmem_tmp->size; - dev_buffer.sz = pmem_tmp->size; - dev_buffer.offset = pmem_tmp->offset; - DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ - dev_buffer.pbuffer, \ - dev_buffer.fd, \ - dev_buffer.offset, \ - dev_buffer.maped_size); - - } - else if(port == PORT_INDEX_OUT) - { - dev_buffer.pbuffer = (OMX_U8 *)pmem_tmp->buffer; - dev_buffer.fd = pmem_tmp->fd; - dev_buffer.sz = pmem_tmp->size; - dev_buffer.maped_size = pmem_tmp->size; - dev_buffer.offset = pmem_tmp->offset; - - DEBUG_PRINT_LOW("\n venc_free_buf:pbuffer = %x,fd = %x, offset = %d, maped_size = %d", \ - dev_buffer.pbuffer, \ - dev_buffer.fd, \ - dev_buffer.offset, \ - dev_buffer.maped_size); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: venc_free_buf:Invalid Port Index "); - return false; - } - return true; -} - -bool venc_dev::venc_empty_buf(void *buffer, void *pmem_data_buf, unsigned index, unsigned fd) -{ - struct pmem *temp_buffer; - struct v4l2_buffer buf; - struct v4l2_plane plane; - int rc=0; - struct OMX_BUFFERHEADERTYPE *bufhdr; - encoder_media_buffer_type * meta_buf = NULL; - temp_buffer = (struct pmem *)buffer; - - memset (&buf, 0, sizeof(buf)); - memset (&plane, 0, sizeof(plane)); - if(buffer == NULL) - { - DEBUG_PRINT_ERROR("\nERROR: venc_etb: buffer is NULL"); - return false; - } - bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; - - DEBUG_PRINT_LOW("\n Input buffer length %d",bufhdr->nFilledLen); - if(pmem_data_buf) - { - DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf); - plane.m.userptr = (unsigned long)pmem_data_buf; - plane.data_offset = bufhdr->nOffset; - plane.length = bufhdr->nAllocLen; - plane.bytesused = bufhdr->nFilledLen; - } - else - { - DEBUG_PRINT_LOW("\n Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); - if (metadatamode && !color_format) { // meta Buffer + Camera buffers - meta_buf = (encoder_media_buffer_type *)bufhdr->pBuffer; - if (!meta_buf) - return false; - plane.m.userptr = index; - plane.data_offset = meta_buf->meta_handle->data[1]; - plane.length = meta_buf->meta_handle->data[2]; - plane.bytesused = meta_buf->meta_handle->data[2]; - } - else - { // meta Buffer + Gralloc buffers || pmem buffers - plane.m.userptr = (unsigned long) bufhdr->pBuffer; - plane.data_offset = bufhdr->nOffset; - plane.length = bufhdr->nAllocLen; - plane.bytesused = bufhdr->nFilledLen; - } - } - - buf.index = index; - buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane.reserved[0] = fd; - plane.reserved[1] = 0; - buf.m.planes = &plane; - buf.length = 1; - if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS) - buf.flags = V4L2_BUF_FLAG_EOS; - buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000; - buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000); - rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); - if (rc) { - DEBUG_PRINT_ERROR("Failed to qbuf (etb) to driver"); - return false; - } - etb++; - if(!streaming[OUTPUT_PORT]) - { - enum v4l2_buf_type buf_type; - buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - int ret; - ret = ioctl(m_nDriver_fd, VIDIOC_STREAMON, &buf_type); - if (ret) { - DEBUG_PRINT_ERROR("Failed to call streamon\n"); - return false; - } else { - streaming[OUTPUT_PORT] = true; - } -} -#ifdef INPUT_BUFFER_LOG - int i; - int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width); - int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, m_sVenc_cfg.input_height); - char *temp = (char *)bufhdr->pBuffer; - for (i = 0; i < m_sVenc_cfg.input_height; i++) { - fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1); - temp += stride; - } - temp = (char *)bufhdr->pBuffer + (stride * scanlines); - for(i = 0; i < m_sVenc_cfg.input_height/2; i++) { - fwrite(temp, m_sVenc_cfg.input_width, 1, inputBufferFile1); - temp += stride; - } -#endif - return true; -} -bool venc_dev::venc_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd) -{ - struct pmem *temp_buffer = NULL; - struct venc_buffer frameinfo; - struct v4l2_buffer buf; - struct v4l2_plane plane[VIDEO_MAX_PLANES]; - int rc = 0, extra_idx; - struct OMX_BUFFERHEADERTYPE *bufhdr; - - if(buffer == NULL) - return false; - - bufhdr = (OMX_BUFFERHEADERTYPE *)buffer; - - if(pmem_data_buf) - { - DEBUG_PRINT_LOW("\n Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf); - plane[0].m.userptr = (unsigned long)pmem_data_buf; - } else { - DEBUG_PRINT_LOW("\n Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer); - plane[0].m.userptr = (unsigned long)bufhdr->pBuffer; - } - - buf.index = index; - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; - buf.memory = V4L2_MEMORY_USERPTR; - plane[0].length = bufhdr->nAllocLen; - plane[0].bytesused = bufhdr->nFilledLen; - plane[0].reserved[0] = fd; - plane[0].reserved[1] = 0; - plane[0].data_offset = bufhdr->nOffset; - buf.m.planes = plane; - buf.length = num_planes; - - extra_idx = EXTRADATA_IDX(num_planes); - if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) { - plane[extra_idx].bytesused = 0; - plane[extra_idx].length = extradata_info.buffer_size; - plane[extra_idx].m.userptr = (unsigned long) (extradata_info.uaddr + index * extradata_info.buffer_size); -#ifdef USE_ION - plane[extra_idx].reserved[0] = extradata_info.ion.fd_ion_data.fd; -#endif - plane[extra_idx].reserved[1] = extradata_info.buffer_size * index; - plane[extra_idx].data_offset = 0; - } else if (extra_idx >= VIDEO_MAX_PLANES) { - DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx); - return false; - } - rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf); - if (rc) { - DEBUG_PRINT_ERROR("Failed to qbuf (ftb) to driver"); - return false; - } - ftb++; - return true; -} - -bool venc_dev::venc_set_extradata(OMX_U32 extra_data) -{ - struct v4l2_control control; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA; - control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO; - DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data); - if(multislice.mslice_mode && multislice.mslice_mode != V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE) - { - if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed"); - return false; - } - } - else - { - DEBUG_PRINT_ERROR("Failed to set slice extradata, slice_mode " - "is set to [%lu]", multislice.mslice_mode); - } - return true; -} - -bool venc_dev::venc_set_slice_delivery_mode(OMX_U32 enable) -{ - struct v4l2_control control; - if (enable) { - control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_DELIVERY_MODE; - control.value = 1; - DEBUG_PRINT_LOW("Set slice_delivery_mode: %d", control.value); - if(multislice.mslice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) - { - if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) { - DEBUG_PRINT_ERROR("Request for setting slice delivery mode failed"); - return false; - } - else { - DEBUG_PRINT_LOW("Successfully set Slice delivery mode id: %d, value=%d\n", control.id, control.value); - slice_mode.enable = 1; - } - } - else - { - DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%d] " - "is not MB BASED or [%lu] is not H264 codec ", multislice.mslice_mode, - m_sVenc_cfg.codectype); - } - } - else - { - DEBUG_PRINT_ERROR("Slice_DELIVERY_MODE not enabled\n"); - } - return true; -} - -bool venc_dev::venc_set_session_qp(OMX_U32 i_frame_qp, OMX_U32 p_frame_qp,OMX_U32 b_frame_qp) -{ - int rc; - struct v4l2_control control; - - control.id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP; - control.value = i_frame_qp; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - session_qp.iframeqp = control.value; - - control.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP; - control.value = p_frame_qp; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - session_qp.pframqp = control.value; - - if((codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) || - (codec_profile.profile == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) - { - - control.id = V4L2_CID_MPEG_VIDEO_H264_B_FRAME_QP; - control.value = b_frame_qp; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - session_qp.bframqp = control.value; - } - - return true; -} - -bool venc_dev::venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel) -{ - struct venc_profile requested_profile = {0}; - struct ven_profilelevel requested_level = {0}; - unsigned long mb_per_frame = 0; - DEBUG_PRINT_LOW("venc_set_profile_level:: eProfile = %d, Level = %d", - eProfile, eLevel); - mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* - ((m_sVenc_cfg.input_width + 15) >> 4); - if((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) - { - DEBUG_PRINT_LOW("\n Profile/Level setting complete before venc_start"); - return true; - } - - DEBUG_PRINT_LOW("\n Validating Profile/Level from table"); - if(!venc_validate_profile_level(&eProfile, &eLevel)) - { - DEBUG_PRINT_LOW("\nERROR: Profile/Level validation failed"); - return false; - } - - if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) - { - DEBUG_PRINT_LOW("eProfile = %d, OMX_VIDEO_MPEG4ProfileSimple = %d and " - "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", eProfile, - OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4ProfileAdvancedSimple); - if(eProfile == OMX_VIDEO_MPEG4ProfileSimple) - { - requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE; - } - else if(eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { - requested_profile.profile = V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE; - } - else - { - DEBUG_PRINT_LOW("\nERROR: Unsupported MPEG4 profile = %u", - eProfile); - return false; - } - - DEBUG_PRINT_LOW("eLevel = %d, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d," - "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d," - "OMX_VIDEO_MPEG4Level5 = %d", eLevel, OMX_VIDEO_MPEG4Level0, OMX_VIDEO_MPEG4Level1, - OMX_VIDEO_MPEG4Level2, OMX_VIDEO_MPEG4Level3, OMX_VIDEO_MPEG4Level4, OMX_VIDEO_MPEG4Level5); - - if(mb_per_frame >= 3600) - { - if(requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; - if(requested_profile.profile == V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; - } - else - { - switch(eLevel) - { - case OMX_VIDEO_MPEG4Level0: - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0; - break; - case OMX_VIDEO_MPEG4Level0b: - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B; - break; - case OMX_VIDEO_MPEG4Level1: - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_1; - break; - case OMX_VIDEO_MPEG4Level2: - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_2; - break; - case OMX_VIDEO_MPEG4Level3: - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_3; - break; - case OMX_VIDEO_MPEG4Level4a: - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_4; - break; - case OMX_VIDEO_MPEG4Level5: - requested_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; - break; - default: - return false; - // TODO update corresponding levels for MPEG4_LEVEL_3b,MPEG4_LEVEL_6 - break; - } - } - } - else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) - { - - switch (eProfile) { - case OMX_VIDEO_H263ProfileBaseline: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BASELINE; - break; - case OMX_VIDEO_H263ProfileH320Coding: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_H320CODING; - break; - case OMX_VIDEO_H263ProfileBackwardCompatible: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_BACKWARDCOMPATIBLE; - break; - case OMX_VIDEO_H263ProfileISWV2: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV2; - break; - case OMX_VIDEO_H263ProfileISWV3: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_ISWV3; - break; - case OMX_VIDEO_H263ProfileHighCompression: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHCOMPRESSION; - break; - case OMX_VIDEO_H263ProfileInternet: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERNET; - break; - case OMX_VIDEO_H263ProfileInterlace: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_INTERLACE; - break; - case OMX_VIDEO_H263ProfileHighLatency: - requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_H263_PROFILE_HIGHLATENCY; - break; - default: - DEBUG_PRINT_LOW("\nERROR: Unsupported H.263 profile = %u", - requested_profile.profile); - return false; - } - //profile level - switch(eLevel) - { - case OMX_VIDEO_H263Level10: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_1_0; - break; - case OMX_VIDEO_H263Level20: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_2_0; - break; - case OMX_VIDEO_H263Level30: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_3_0; - break; - case OMX_VIDEO_H263Level40: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_0; - break; - case OMX_VIDEO_H263Level45: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_4_5; - break; - case OMX_VIDEO_H263Level50: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_5_0; - break; - case OMX_VIDEO_H263Level60: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_6_0; - break; - case OMX_VIDEO_H263Level70: - requested_level.level = V4L2_MPEG_VIDC_VIDEO_H263_LEVEL_7_0; - break; - default: - return false; - break; - } - } - else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) - { - if(eProfile == OMX_VIDEO_AVCProfileBaseline) - { - requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE; - } - else if(eProfile == OMX_VIDEO_AVCProfileMain) - { - requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN; - } - else if(eProfile == OMX_VIDEO_AVCProfileExtended) - { - requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED; - } - else if(eProfile == OMX_VIDEO_AVCProfileHigh) - { - requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH; - } - else if(eProfile == OMX_VIDEO_AVCProfileHigh10) - { - requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10; - } - else if(eProfile == OMX_VIDEO_AVCProfileHigh422) - { - requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422; - } - else if(eProfile == OMX_VIDEO_AVCProfileHigh444) - { - requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE; - } - else - { - DEBUG_PRINT_LOW("\nERROR: Unsupported H.264 profile = %u", - requested_profile.profile); - return false; - } - //profile level - switch(eLevel) - { - case OMX_VIDEO_AVCLevel1: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_0; - break; - case OMX_VIDEO_AVCLevel1b: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1B; - break; - case OMX_VIDEO_AVCLevel11: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_1; - break; - case OMX_VIDEO_AVCLevel12: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_2; - break; - case OMX_VIDEO_AVCLevel13: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_1_3; - break; - case OMX_VIDEO_AVCLevel2: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_0; - break; - case OMX_VIDEO_AVCLevel21: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_1; - break; - case OMX_VIDEO_AVCLevel22: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_2_2; - break; - case OMX_VIDEO_AVCLevel3: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_0; - break; - case OMX_VIDEO_AVCLevel31: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_1; - break; - case OMX_VIDEO_AVCLevel32: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_3_2; - break; - case OMX_VIDEO_AVCLevel4: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_0; - break; - case OMX_VIDEO_AVCLevel41: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_1; - break; - case OMX_VIDEO_AVCLevel42: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_4_2; - break; - case OMX_VIDEO_AVCLevel5: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_0; - break; - case OMX_VIDEO_AVCLevel51: - requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_1; - break; - default : - DEBUG_PRINT_ERROR("\nERROR: Unsupported H.264 level= %lu", - requested_level.level); - return false; - break; - } - } - if(!m_profile_set) - { - int rc; - struct v4l2_control control; - if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { - control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE; - } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { - control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE; - } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE; - } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { - DEBUG_PRINT_ERROR("\n No Profile and LEVEL Setting for VP8 \n"); - m_profile_set = true; - m_level_set = true; - return true; - } else { - DEBUG_PRINT_ERROR("\n Wrong CODEC \n"); - return false; - } - - control.value = requested_profile.profile; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - codec_profile.profile = control.value; - m_profile_set = true; - } - - if(!m_level_set) - { - int rc; - struct v4l2_control control; - if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) { - control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL; - } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { - control.id = V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL; - } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) { - control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL; - } else { - DEBUG_PRINT_ERROR("\n Wrong CODEC \n"); - return false; - } - - control.value = requested_level.level; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - profile_level.level = control.value; - m_level_set = true; - } - - return true; -} - -bool venc_dev::venc_set_voptiming_cfg( OMX_U32 TimeIncRes) -{ - - struct venc_voptimingcfg vop_timing_cfg; - - DEBUG_PRINT_LOW("\n venc_set_voptiming_cfg: TimeRes = %u", - TimeIncRes); - - vop_timing_cfg.voptime_resolution = TimeIncRes; - - voptimecfg.voptime_resolution = vop_timing_cfg.voptime_resolution; - return true; -} - -bool venc_dev::venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames) -{ - - DEBUG_PRINT_LOW("\n venc_set_intra_period: nPFrames = %u", - nPFrames); - int rc; - struct v4l2_control control; - if((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) && - (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) && - (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) - { - nBFrames=0; - } - - control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES; - control.value = nPFrames; - - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - intra_period.num_pframes = control.value; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES; - control.value = nBFrames; - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - - intra_period.num_bframes = control.value; - if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264){ - control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; - control.value = 1; - - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - idrperiod.idrperiod = 1; - } - return true; -} - -bool venc_dev::venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod) -{ - int rc = 0; - struct v4l2_control control; - DEBUG_PRINT_LOW("\n venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u\n", - nPFrames, nIDRPeriod); - - if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264){ - DEBUG_PRINT_ERROR("\nERROR: IDR period valid for H264 only!!"); - return false; - } - - if(venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) { - DEBUG_PRINT_ERROR("\nERROR: Request for setting intra period failed"); - return false; - } - - intra_period.num_pframes = nPFrames; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_IDR_PERIOD; - control.value = nIDRPeriod; - - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - - idrperiod.idrperiod = nIDRPeriod; - return true; -} - -bool venc_dev::venc_set_entropy_config(OMX_BOOL enable, OMX_U32 i_cabac_level) -{ - int rc = 0; - struct v4l2_control control; - - DEBUG_PRINT_LOW("\n venc_set_entropy_config: CABAC = %u level: %u", enable, i_cabac_level); - - if(enable &&(codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE)){ - - control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC; - control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - entropy.longentropysel = control.value; - if (i_cabac_level == 0) { - control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_0; - } - else if (i_cabac_level == 1) { - control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_1; - } - else if (i_cabac_level == 2) { - control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL_2; - } - - control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_CABAC_MODEL; - //control.value = entropy_cfg.cabacmodel; - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - entropy.longentropysel=control.value; - } - else if(!enable){ - control.value = V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CAVLC; - control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE; - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - entropy.longentropysel=control.value; - } - else{ - DEBUG_PRINT_ERROR("\nInvalid Entropy mode for Baseline Profile"); - return false; - } - - return true; -} - -bool venc_dev::venc_set_multislice_cfg(OMX_INDEXTYPE Codec, OMX_U32 nSlicesize) // MB -{ - int rc; - struct v4l2_control control; - bool status = true; - - if((Codec != OMX_IndexParamVideoH263) && (nSlicesize)){ - control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB; - } - else{ - control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; - } - control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - multislice.mslice_mode=control.value; - - if(multislice.mslice_mode!=V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE){ - - control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; - control.value = nSlicesize; - DEBUG_PRINT_LOW("Calling SLICE_MB IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - multislice.mslice_size=control.value; - - } - return status; -} - -bool venc_dev::venc_set_intra_refresh(OMX_VIDEO_INTRAREFRESHTYPE ir_mode, OMX_U32 irMBs) -{ - bool status = true; - int rc; - struct v4l2_control control_mode,control_mbs; - control_mode.id = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_MODE; - // There is no disabled mode. Disabled mode is indicated by a 0 count. - if (irMBs == 0 || ir_mode == OMX_VIDEO_IntraRefreshMax) - { - control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_NONE; - return status; - } - else if ((ir_mode == OMX_VIDEO_IntraRefreshCyclic) && - (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) - { - control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC; - control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS; - control_mbs.value=irMBs; - } - else if ((ir_mode == OMX_VIDEO_IntraRefreshAdaptive) && - (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) - { - control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_ADAPTIVE; - control_mbs.id=V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS; - control_mbs.value=irMBs; - } - else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) && - (irMBs < ((m_sVenc_cfg.input_width * m_sVenc_cfg.input_height)>>8))) - { - control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE; - } - else - { - DEBUG_PRINT_ERROR("\nERROR: Invalid IntraRefresh Parameters:" - "mb count: %lu, mb mode:%d", irMBs, ir_mode); - return false; - } - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%lu, val=%lu\n", control_mode.id, control_mode.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mode); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mode.id, control_mode.value); - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control_mbs.id, control_mbs.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control_mbs); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control_mbs.id, control_mbs.value); - - intra_refresh.irmode = control_mode.value; - intra_refresh.mbcount = control_mbs.value; - - return status; -} - -bool venc_dev::venc_set_error_resilience(OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* error_resilience) -{ - bool status = true; - struct venc_headerextension hec_cfg; - struct venc_multiclicecfg multislice_cfg; - int rc; - struct v4l2_control control; - - memset(&control, 0, sizeof(control)); - if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) { - if (error_resilience->bEnableHEC) { - hec_cfg.header_extension = 1; - } else { - hec_cfg.header_extension = 0; - } - hec.header_extension = error_resilience->bEnableHEC; - } - - if (error_resilience->bEnableRVLC) { - DEBUG_PRINT_ERROR("\n RVLC is not Supported"); - return false; - } - - if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && - (error_resilience->bEnableDataPartitioning)) { - DEBUG_PRINT_ERROR("\n DataPartioning are not Supported for MPEG4/H264"); - return false; - } - - if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) && - (error_resilience->nResynchMarkerSpacing)) { - multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE; - multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; - control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; - control.value = V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES; - } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263 && - error_resilience->bEnableDataPartitioning) { - multislice_cfg.mslice_mode = VEN_MSLICE_GOB; - multislice_cfg.mslice_size = error_resilience->nResynchMarkerSpacing; - control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; - control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_GOB; - } else { - multislice_cfg.mslice_mode = VEN_MSLICE_OFF; - multislice_cfg.mslice_size = 0; - control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE; - control.value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; - } - DEBUG_PRINT_LOW("\n %s(): mode = %u, size = %u", __func__, - multislice_cfg.mslice_mode, multislice_cfg.mslice_size); - printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - printf("Failed to set Slice mode control\n"); - return false; - } - printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); - multislice.mslice_mode=control.value; - - control.id = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; - control.value = error_resilience->nResynchMarkerSpacing; - printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - printf("Failed to set MAX MB control\n"); - return false; - } - printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); - multislice.mslice_mode = multislice_cfg.mslice_mode; - multislice.mslice_size = multislice_cfg.mslice_size; - return status; -} - -bool venc_dev::venc_set_inloop_filter(OMX_VIDEO_AVCLOOPFILTERTYPE loopfilter) -{ - int rc; - struct v4l2_control control; - control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE; - if (loopfilter == OMX_VIDEO_AVCLoopFilterEnable){ - control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_ENABLED; - } - else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisable){ - control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED; - } - else if(loopfilter == OMX_VIDEO_AVCLoopFilterDisableSliceBoundary){ - control.value=V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY; - } - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - dbkfilter.db_mode=control.value; - - control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA; - control.value=0; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - control.id=V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA; - control.value=0; - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - - dbkfilter.slicealpha_offset = dbkfilter.slicebeta_offset = 0; - return true; -} - -bool venc_dev::venc_set_target_bitrate(OMX_U32 nTargetBitrate, OMX_U32 config) -{ - DEBUG_PRINT_LOW("\n venc_set_target_bitrate: bitrate = %u", - nTargetBitrate); - struct v4l2_control control; - int rc = 0; - control.id = V4L2_CID_MPEG_VIDEO_BITRATE; - control.value = nTargetBitrate; - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - - m_sVenc_cfg.targetbitrate = control.value; - bitrate.target_bitrate = control.value; - if(!config) - { - m_level_set = false; - if(venc_set_profile_level(0, 0)) - { - DEBUG_PRINT_HIGH("Calling set level (Bitrate) with %lu\n",profile_level.level); - } - } - return true; -} - -bool venc_dev::venc_set_encode_framerate(OMX_U32 encode_framerate, OMX_U32 config) -{ - struct v4l2_streamparm parm; - int rc = 0; - struct venc_framerate frame_rate_cfg; - Q16ToFraction(encode_framerate,frame_rate_cfg.fps_numerator,frame_rate_cfg.fps_denominator); - parm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - parm.parm.output.timeperframe.numerator = frame_rate_cfg.fps_denominator; - parm.parm.output.timeperframe.denominator = frame_rate_cfg.fps_numerator; - if(frame_rate_cfg.fps_numerator > 0) - rc = ioctl(m_nDriver_fd, VIDIOC_S_PARM, &parm); - if (rc) { - DEBUG_PRINT_ERROR("ERROR: Request for setting framerate failed\n"); - return false; - } - m_sVenc_cfg.fps_den = frame_rate_cfg.fps_denominator; - m_sVenc_cfg.fps_num = frame_rate_cfg.fps_numerator; - if(!config) - { - m_level_set = false; - if(venc_set_profile_level(0, 0)) - { - DEBUG_PRINT_HIGH("Calling set level (Framerate) with %lu\n",profile_level.level); - } - } - return true; -} - -bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format) -{ - struct v4l2_format fmt; - DEBUG_PRINT_LOW("\n venc_set_color_format: color_format = %u ", color_format); - - if(color_format == OMX_COLOR_FormatYUV420SemiPlanar) - { - m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; - } - else if(color_format == QOMX_COLOR_FormatYVU420SemiPlanar) - { - m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21; - } - else - { - DEBUG_PRINT_ERROR("\nWARNING: Unsupported Color format [%d]", color_format); - m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12; - DEBUG_PRINT_HIGH("\n Default color format YUV420SemiPlanar is set"); - } - fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; - fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat; - fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height; - fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width; - if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) { - DEBUG_PRINT_ERROR("Failed setting color format %x", color_format); - return false; - } - - return true; -} - -bool venc_dev::venc_set_intra_vop_refresh(OMX_BOOL intra_vop_refresh) -{ - DEBUG_PRINT_LOW("\n venc_set_intra_vop_refresh: intra_vop = %uc", intra_vop_refresh); - if(intra_vop_refresh == OMX_TRUE) - { - struct v4l2_control control; - int rc; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_IFRAME; - control.value = 1; - printf("Calling IOCTL set control for id=%x, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - printf("Failed to set Intra Frame Request control\n"); - return false; - } - printf("Success IOCTL set control for id=%x, value=%d\n", control.id, control.value); - } - else - { - DEBUG_PRINT_ERROR("\nERROR: VOP Refresh is False, no effect"); - } - return true; -} - -bool venc_dev::venc_set_ratectrl_cfg(OMX_VIDEO_CONTROLRATETYPE eControlRate) -{ - bool status = true; - struct v4l2_control control; - int rc = 0; - control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL; - switch(eControlRate) - { - case OMX_Video_ControlRateDisable: - control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF; - break; - case OMX_Video_ControlRateVariableSkipFrames: - control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR; - break; - case OMX_Video_ControlRateVariable: - control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR; - break; - case OMX_Video_ControlRateConstantSkipFrames: - control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR; - break; - case OMX_Video_ControlRateConstant: - control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR; - break; - default: - status = false; - break; - } - - if(status) - { - - DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d\n", control.id, control.value); - rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control); - if (rc) { - DEBUG_PRINT_ERROR("Failed to set control\n"); - return false; - } - DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d\n", control.id, control.value); - - rate_ctrl.rcmode = control.value; - } - return status; -} - -bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel) -{ - bool status = true; - if(eProfile == NULL || eLevel == NULL) - { - return false; - } - - if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) - { - switch(codec_profile.profile) - { - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: - *eProfile = OMX_VIDEO_MPEG4ProfileSimple; - break; - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: - *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - break; - default: - *eProfile = OMX_VIDEO_MPEG4ProfileMax; - status = false; - break; - } - - if(!status) - { - return status; - } - - //profile level - switch(profile_level.level) - { - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0: - *eLevel = OMX_VIDEO_MPEG4Level0; - break; - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_0B: - *eLevel = OMX_VIDEO_MPEG4Level0b; - break; - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_1: - *eLevel = OMX_VIDEO_MPEG4Level1; - break; - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_2: - *eLevel = OMX_VIDEO_MPEG4Level2; - break; - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_3: - *eLevel = OMX_VIDEO_MPEG4Level3; - break; - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_4: - *eLevel = OMX_VIDEO_MPEG4Level4; - break; - case V4L2_MPEG_VIDEO_MPEG4_LEVEL_5: - *eLevel = OMX_VIDEO_MPEG4Level5; - break; - default: - *eLevel = OMX_VIDEO_MPEG4LevelMax; - status = false; - break; - } - } - else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) - { - if(codec_profile.profile == VEN_PROFILE_H263_BASELINE) - { - *eProfile = OMX_VIDEO_H263ProfileBaseline; - } - else - { - *eProfile = OMX_VIDEO_H263ProfileMax; - return false; - } - switch(profile_level.level) - { - case VEN_LEVEL_H263_10: - *eLevel = OMX_VIDEO_H263Level10; - break; - case VEN_LEVEL_H263_20: - *eLevel = OMX_VIDEO_H263Level20; - break; - case VEN_LEVEL_H263_30: - *eLevel = OMX_VIDEO_H263Level30; - break; - case VEN_LEVEL_H263_40: - *eLevel = OMX_VIDEO_H263Level40; - break; - case VEN_LEVEL_H263_45: - *eLevel = OMX_VIDEO_H263Level45; - break; - case VEN_LEVEL_H263_50: - *eLevel = OMX_VIDEO_H263Level50; - break; - case VEN_LEVEL_H263_60: - *eLevel = OMX_VIDEO_H263Level60; - break; - case VEN_LEVEL_H263_70: - *eLevel = OMX_VIDEO_H263Level70; - break; - default: - *eLevel = OMX_VIDEO_H263LevelMax; - status = false; - break; - } - } - else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) - { - switch(codec_profile.profile) - { - case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: - *eProfile = OMX_VIDEO_AVCProfileBaseline; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: - *eProfile = OMX_VIDEO_AVCProfileMain; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: - *eProfile = OMX_VIDEO_AVCProfileHigh; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: - *eProfile = OMX_VIDEO_AVCProfileExtended; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: - *eProfile = OMX_VIDEO_AVCProfileHigh10; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: - *eProfile = OMX_VIDEO_AVCProfileHigh422; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: - *eProfile = OMX_VIDEO_AVCProfileHigh444; - break; - default: - *eProfile = OMX_VIDEO_AVCProfileMax; - status = false; - break; - } - - if(!status) - { - return status; - } - - switch(profile_level.level) - { - case V4L2_MPEG_VIDEO_H264_LEVEL_1_0: - *eLevel = OMX_VIDEO_AVCLevel1; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_1B: - *eLevel = OMX_VIDEO_AVCLevel1b; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_1_1: - *eLevel = OMX_VIDEO_AVCLevel11; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_1_2: - *eLevel = OMX_VIDEO_AVCLevel12; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_1_3: - *eLevel = OMX_VIDEO_AVCLevel13; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_2_0: - *eLevel = OMX_VIDEO_AVCLevel2; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_2_1: - *eLevel = OMX_VIDEO_AVCLevel21; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_2_2: - *eLevel = OMX_VIDEO_AVCLevel22; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_3_0: - *eLevel = OMX_VIDEO_AVCLevel3; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_3_1: - *eLevel = OMX_VIDEO_AVCLevel31; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_3_2: - *eLevel = OMX_VIDEO_AVCLevel32; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_4_0: - *eLevel = OMX_VIDEO_AVCLevel4; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_4_1: - *eLevel = OMX_VIDEO_AVCLevel41; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_4_2: - *eLevel = OMX_VIDEO_AVCLevel42; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_5_0: - *eLevel = OMX_VIDEO_AVCLevel5; - break; - case V4L2_MPEG_VIDEO_H264_LEVEL_5_1: - *eLevel = OMX_VIDEO_AVCLevel51; - break; - default : - *eLevel = OMX_VIDEO_AVCLevelMax; - status = false; - break; - } - } - return status; -} - -bool venc_dev::venc_validate_profile_level(OMX_U32 *eProfile, OMX_U32 *eLevel) -{ - OMX_U32 new_profile = 0, new_level = 0; - unsigned const int *profile_tbl = NULL; - OMX_U32 mb_per_frame, mb_per_sec; - bool profile_level_found = false; - - DEBUG_PRINT_LOW("\n Init profile table for respective codec"); - //validate the ht,width,fps,bitrate and set the appropriate profile and level - if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) - { - if(*eProfile == 0) - { - if(!m_profile_set) - { - *eProfile = OMX_VIDEO_MPEG4ProfileSimple; - } - else - { - switch(codec_profile.profile) - { - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE: - *eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; - break; - case V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE: - *eProfile = OMX_VIDEO_MPEG4ProfileSimple; - break; - default: - DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); - return false; - } - } - } - - if(*eLevel == 0 && !m_level_set) - { - *eLevel = OMX_VIDEO_MPEG4LevelMax; - } - - if(*eProfile == OMX_VIDEO_MPEG4ProfileSimple) - { - profile_tbl = (unsigned int const *)mpeg4_profile_level_table; - } - else if(*eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) - { - profile_tbl = (unsigned int const *) - (&mpeg4_profile_level_table[MPEG4_ASP_START]); - } - else - { - DEBUG_PRINT_LOW("\n Unsupported MPEG4 profile type %lu", *eProfile); - return false; - } - } - else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) - { - if(*eProfile == 0) - { - if(!m_profile_set) - { - *eProfile = OMX_VIDEO_AVCProfileBaseline; - } - else - { - switch(codec_profile.profile) - { - case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE: - *eProfile = OMX_VIDEO_AVCProfileBaseline; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN: - *eProfile = OMX_VIDEO_AVCProfileMain; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED: - *eProfile = OMX_VIDEO_AVCProfileExtended; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH: - *eProfile = OMX_VIDEO_AVCProfileHigh; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10: - *eProfile = OMX_VIDEO_AVCProfileHigh10; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422: - *eProfile = OMX_VIDEO_AVCProfileHigh422; - break; - case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE: - *eProfile = OMX_VIDEO_AVCProfileHigh444; - break; - default: - DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); - return false; - } - } - } - - if(*eLevel == 0 && !m_level_set) - { - *eLevel = OMX_VIDEO_AVCLevelMax; - } - - if(*eProfile == OMX_VIDEO_AVCProfileBaseline) - { - profile_tbl = (unsigned int const *)h264_profile_level_table; - } - else if(*eProfile == OMX_VIDEO_AVCProfileHigh) - { - profile_tbl = (unsigned int const *) - (&h264_profile_level_table[H264_HP_START]); - } - else if(*eProfile == OMX_VIDEO_AVCProfileMain) - { - profile_tbl = (unsigned int const *) - (&h264_profile_level_table[H264_MP_START]); - } - else - { - DEBUG_PRINT_LOW("\n Unsupported AVC profile type %lu", *eProfile); - return false; - } - } - else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) - { - if(*eProfile == 0) - { - if(!m_profile_set) - { - *eProfile = OMX_VIDEO_H263ProfileBaseline; - } - else - { - switch(codec_profile.profile) - { - case VEN_PROFILE_H263_BASELINE: - *eProfile = OMX_VIDEO_H263ProfileBaseline; - break; - default: - DEBUG_PRINT_LOW("\n %s(): Unknown Error", __func__); - return false; - } - } - } - - if(*eLevel == 0 && !m_level_set) - { - *eLevel = OMX_VIDEO_H263LevelMax; - } - - if(*eProfile == OMX_VIDEO_H263ProfileBaseline) - { - profile_tbl = (unsigned int const *)h263_profile_level_table; - } - else - { - DEBUG_PRINT_LOW("\n Unsupported H.263 profile type %lu", *eProfile); - return false; - } - } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) { - DEBUG_PRINT_HIGH("Disregarding profile/level setting for VP8\n"); - return true; - } - else - { - DEBUG_PRINT_LOW("\n Invalid codec type"); - return false; - } - - mb_per_frame = ((m_sVenc_cfg.input_height + 15) >> 4)* - ((m_sVenc_cfg.input_width + 15)>> 4); - - if((mb_per_frame >= 3600) && (m_sVenc_cfg.codectype == (unsigned long) V4L2_PIX_FMT_MPEG4)) - { - if(codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) - profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; - if(codec_profile.profile == (unsigned long) V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) - profile_level.level = V4L2_MPEG_VIDEO_MPEG4_LEVEL_5; - { - new_level = profile_level.level; - new_profile = codec_profile.profile; - return true; - } - } - - mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den; - - do{ - if(mb_per_frame <= (unsigned int)profile_tbl[0]) - { - if(mb_per_sec <= (unsigned int)profile_tbl[1]) - { - if(m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) - { - new_level = (int)profile_tbl[3]; - new_profile = (int)profile_tbl[4]; - profile_level_found = true; - DEBUG_PRINT_LOW("\n Appropriate profile/level found %d/%d\n", new_profile, new_level); - break; - } - } - } - profile_tbl = profile_tbl + 5; - }while(profile_tbl[0] != 0); - - if (profile_level_found != true) - { - DEBUG_PRINT_LOW("\n ERROR: Unsupported profile/level\n"); - return false; - } - - if((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax) - || (*eLevel == OMX_VIDEO_H263LevelMax)) - { - *eLevel = new_level; - } - DEBUG_PRINT_HIGH("%s: Returning with eProfile = %lu" - "Level = %lu", __func__, *eProfile, *eLevel); - - return true; -} -#ifdef _ANDROID_ICS_ -bool venc_dev::venc_set_meta_mode(bool mode) -{ - metadatamode = 1; - return true; -} -#endif - -bool venc_dev::venc_is_video_session_supported(unsigned long width, - unsigned long height) -{ - if ((width * height < capability.min_width * capability.min_height) || - (width * height > capability.max_width * capability.max_height)) { - DEBUG_PRINT_ERROR( - "Unsupported video resolution WxH = (%d)x(%d) supported range = min (%d)x(%d) - max (%d)x(%d)\n", - width, height, capability.min_width, capability.min_height, - capability.max_width, capability.max_height); - return false; - } - DEBUG_PRINT_LOW("\n video session supported\n"); - return true; -} diff --git a/mm-video/vidc/venc/test/camera_test.cpp b/mm-video/vidc/venc/test/camera_test.cpp deleted file mode 100755 index f5ae6dbe..00000000 --- a/mm-video/vidc/venc/test/camera_test.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "camera_test.h" -// #include "camera_class.h" - -EXTERN_C_START - -// static android::Camera* pCamera = NULL; - -int CameraTest_Initialize(int nFrameRate, - int nFrameWidth, - int nFrameHeight, - CameraPreviewCallback pfnPreviewCallback) -{ - int result = 0; - -// pCamera = new android::Camera; -// if (!pCamera) -// return 1; - -// pCamera->init_camera(nFrameWidth, -// nFrameHeight, -// nFrameRate, -// pfnPreviewCallback); - - return result; -} - -int CameraTest_Run() -{ - int result = 0; - -// if (pCamera) -// pCamera->startPreview(); -// else -// return 1; - - return result; -} - -int CameraTest_ReleaseFrame(void* pPhys, void* pVirt) -{ - int result = 0; - -// if (pCamera) -// pCamera->releaseFrame(pPhys, pVirt); -// else -// return 1; - - return result; -} - -int CameraTest_Exit() -{ - int result = 0; - -// if (pCamera) -// { -// pCamera->stopPreview(); -// delete pCamera; -// } -// pCamera = NULL; - - return result; -} - - -EXTERN_C_END diff --git a/mm-video/vidc/venc/test/fb_test.c b/mm-video/vidc/venc/test/fb_test.c deleted file mode 100755 index 6479a3e9..00000000 --- a/mm-video/vidc/venc/test/fb_test.c +++ /dev/null @@ -1,48 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "fb_test.h" - -int FBTest_Initialize(int nFrameWidth, - int nFrameHeight) -{ - return 0; -} -int FBTest_DisplayImage(int nPmemFd, int nOffset) -{ - return 0; -} - -int FBTest_Exit() -{ - return 0; -} - -int FBTest_RunTest() -{ - return 0; -} diff --git a/mm-video/vidc/venc/test/queue.c b/mm-video/vidc/venc/test/queue.c deleted file mode 100755 index 94756b0a..00000000 --- a/mm-video/vidc/venc/test/queue.c +++ /dev/null @@ -1,174 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "queue.h" - -int check_if_queue_empty ( unsigned int queuetocheck, void* queuecontext ) -{ - struct video_queue_context *ptr_q = NULL; - /* - * queuetocheck - 0 command queue - * queuetocheck - 1 data queue - */ - if ( queuecontext == NULL || (queuetocheck > 1 ) ) - { - return 1; - } - ptr_q = (struct video_queue_context *)queuecontext; - - if (queuetocheck == 0) - { - if (ptr_q->read_comq == ptr_q->write_comq) - { - return 1; - } - } - else if (queuetocheck == 1) - { - if (ptr_q->write_dataq == ptr_q->read_dataq) - { - return 1; - } - } - - return 0; -} - - - -struct video_msgq * queue_get_cmd (void* queuecontext ) -{ - struct video_queue_context *ptr_q = NULL; - struct video_msgq *pitem = NULL; - - if( NULL == queuecontext ) - { - printf("\n queue_get_cmd: Invalid Input parameter\n"); - return NULL; - } - - ptr_q = (struct video_queue_context *)queuecontext; - - /* Wait on the semaphore till it is released */ - sem_wait(&ptr_q->sem_message); - - /* Lock the mutex to protect the critical section */ - pthread_mutex_lock(&ptr_q->mutex); - - if (ptr_q->read_comq != ptr_q->write_comq) - { - pitem = &ptr_q->ptr_cmdq [ptr_q->read_comq]; - ptr_q->read_comq = (ptr_q->read_comq + 1) % \ - ptr_q->commandq_size; - } - else if (ptr_q->write_dataq != ptr_q->read_dataq) - { - pitem = &ptr_q->ptr_dataq [ptr_q->read_dataq]; - ptr_q->read_dataq = (ptr_q->read_dataq + 1) % \ - ptr_q->dataq_size; - } - - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - - return pitem; -} - - -int queue_post_cmdq ( void* queuecontext, - struct video_msgq *pitem - ) -{ - struct video_queue_context *ptr_q = NULL; - - if (pitem == NULL || queuecontext == NULL) - { - return -1; - } - ptr_q = (struct video_queue_context *)queuecontext; - - /* Lock the mutex to protect the critical section */ - pthread_mutex_lock(&ptr_q->mutex); - - if ((ptr_q->write_comq + 1) % ptr_q->commandq_size == ptr_q->read_comq) - { - printf("\n QUEUE is FULL"); - return 0; - } - else - { - /* Store the command in the Message Queue & increment write offset */ - memcpy ( &ptr_q->ptr_cmdq [ptr_q->write_comq],pitem, \ - sizeof (struct video_msgq)); - ptr_q->write_comq = (ptr_q->write_comq + 1) % ptr_q->commandq_size; - } - - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - - /* Post the semaphore */ - sem_post(&ptr_q->sem_message); - return 1; -} - - -int queue_post_dataq ( void *queuecontext, - struct video_msgq *pitem - ) -{ - struct video_queue_context *ptr_q = NULL; - - if (pitem == NULL || queuecontext == NULL) - { - return -1; - } - ptr_q = (struct video_queue_context *)queuecontext; - - /* Lock the mutex to protect the critical section */ - pthread_mutex_lock(&ptr_q->mutex); - - if ((ptr_q->write_dataq + 1) % ptr_q->dataq_size == ptr_q->read_dataq) - { - printf("\n QUEUE is FULL"); - return 0; - } - else - { - /* Store the command in the Message Queue & increment write offset */ - memcpy ( &ptr_q->ptr_dataq [ptr_q->write_dataq],pitem, \ - sizeof (struct video_msgq)); - ptr_q->write_dataq = (ptr_q->write_dataq + 1) % ptr_q->dataq_size; - } - - /* Unlock the mutex to release the critical section */ - pthread_mutex_unlock(&ptr_q->mutex); - - /* Post the semaphore */ - sem_post(&ptr_q->sem_message); - return 1; - -} diff --git a/mm-video/vidc/venc/test/venc_test.cpp b/mm-video/vidc/venc/test/venc_test.cpp deleted file mode 100644 index 7afb5bd9..00000000 --- a/mm-video/vidc/venc/test/venc_test.cpp +++ /dev/null @@ -1,2442 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2013, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -/*============================================================================ - V E N C _ T E S T. C P P - -DESCRIPTION - - This is the OMX test app . - -REFERENCES - -============================================================================*/ - -//usage -// FILE QVGA MP4 24 384000 100 enc_qvga.yuv QVGA_24.m4v -// FILE QCIF MP4 15 96000 0 foreman.qcif.yuv output_qcif.m4v -// FILE VGA MP4 24 1200000 218 enc_vga.yuv vga_output.m4v -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -//#include -#include "OMX_QCOMExtns.h" -#include "OMX_Core.h" - -#define QCOM_EXT 1 - -#include "OMX_Core.h" -#include "OMX_Video.h" -#include "OMX_Component.h" -#include "camera_test.h" -#include "fb_test.h" -#include "venc_util.h" -#include "extra_data_handler.h" -#ifdef USE_ION -#include -#endif -#ifdef _MSM8974_ -#include -#endif - -////////////////////////// -// MACROS -////////////////////////// - -#define CHK(result) if ((result != OMX_ErrorNone) && (result != OMX_ErrorNoMore)) { E("*************** error *************"); exit(0); } -#define TEST_LOG -#ifdef VENC_SYSLOG -#include -/// Debug message macro -#define D(fmt, ...) ALOGE("venc_test Debug %s::%d "fmt, \ - __FUNCTION__, __LINE__, \ - ## __VA_ARGS__) - -/// Error message macro -#define E(fmt, ...) ALOGE("venc_test Error %s::%d "fmt, \ - __FUNCTION__, __LINE__, \ - ## __VA_ARGS__) - -#else - #ifdef TEST_LOG - #define D(fmt, ...) fprintf(stderr, "venc_test Debug %s::%d "fmt"\n", \ - __FUNCTION__, __LINE__, \ - ## __VA_ARGS__) - - /// Error message macro - #define E(fmt, ...) fprintf(stderr, "venc_test Error %s::%d "fmt"\n", \ - __FUNCTION__, __LINE__, \ - ## __VA_ARGS__) - #else - #define D(fmt, ...) - #define E(fmt, ...) - #endif - -#endif - -////////////////////////// -// CONSTANTS -////////////////////////// -static const int MAX_MSG = 100; -//#warning do not hardcode these use port definition -static const int PORT_INDEX_IN = 0; -static const int PORT_INDEX_OUT = 1; - -static const int NUM_IN_BUFFERS = 10; -static const int NUM_OUT_BUFFERS = 10; - -unsigned int num_in_buffers = 0; -unsigned int num_out_buffers = 0; - -////////////////////////// -/* MPEG4 profile and level table*/ -static const unsigned int mpeg4_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple}, - {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple}, - {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple}, - {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple}, - {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple}, - {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, -#ifdef _MSM8974_ - {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, - {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple}, -#endif - {0,0,0,0,0}, - - {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, -#ifdef _MSM8974_ - {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, - {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple}, -#endif - {0,0,0,0,0}, -}; - -/* H264 profile and level table*/ -static const unsigned int h264_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline}, - {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline}, - {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline}, - {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline}, - {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline}, - {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline}, - {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline}, - {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline}, - {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline}, - {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline}, - {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline}, - {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, -#ifdef _MSM8974_ - {32400,972000,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, - {34560,1036800,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline}, -#endif - {0,0,0,0,0}, - - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh}, - {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh}, - {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh}, - {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh}, - {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh}, - {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh}, - {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh}, - {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh}, - {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh}, - {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh}, - {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh}, - {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, -#ifdef _MSM8974_ - {32400,972000,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, - {34560,1036800,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh}, -#endif - {0,0,0,0,0}, - - {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain}, - {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain}, - {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain}, - {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain}, - {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain}, - {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain}, - {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain}, - {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain}, - {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain}, - {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain}, - {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain}, - {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, -#ifdef _MSM8974_ - {32400,972000,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, - {34560,1036800,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain}, -#endif - {0,0,0,0,0} - -}; - -/* H263 profile and level table*/ -static const unsigned int h263_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, - {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, - {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, - {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, - {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, - {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, -#ifdef _MSM8974_ - {32400,972000,20000000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, - {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, -#endif - {0,0,0,0,0} -}; -#ifdef _MSM8974_ -static const unsigned int VP8_profile_level_table[][5]= -{ - /*max mb per frame, max mb per sec, max bitrate, level, profile*/ - {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline}, - {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline}, - {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline}, - {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline}, - {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline}, - {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline}, - {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, - {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, - {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline}, - {0,0,0,0,0} -}; -#endif - -#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } } -#define FractionToQ16(q,num,den) { OMX_U32 power; Log2(den,power); q = num << (16 - power); } - -////////////////////////// -// TYPES -////////////////////////// -struct ProfileType -{ - OMX_VIDEO_CODINGTYPE eCodec; - OMX_VIDEO_MPEG4LEVELTYPE eLevel; - OMX_VIDEO_CONTROLRATETYPE eControlRate; - OMX_VIDEO_AVCSLICEMODETYPE eSliceMode; - OMX_U32 nFrameWidth; - OMX_U32 nFrameHeight; - OMX_U32 nFrameBytes; -#ifdef _MSM8974_ - OMX_U32 nFramestride; - OMX_U32 nFrameScanlines; - OMX_U32 nFrameRead; -#endif - OMX_U32 nBitrate; - float nFramerate; - char* cInFileName; - char* cOutFileName; - OMX_U32 nUserProfile; -}; - -enum MsgId -{ - MSG_ID_OUTPUT_FRAME_DONE, - MSG_ID_INPUT_FRAME_DONE, - MSG_ID_MAX -}; -union MsgData -{ - struct - { - OMX_BUFFERHEADERTYPE* pBuffer; - } sBitstreamData; -}; -struct Msg -{ - MsgId id; - MsgData data; -}; -struct MsgQ -{ - Msg q[MAX_MSG]; - int head; - int size; -}; - -enum Mode -{ - MODE_PREVIEW, - MODE_DISPLAY, - MODE_PROFILE, - MODE_FILE_ENCODE, - MODE_LIVE_ENCODE -}; - -enum ResyncMarkerType -{ - RESYNC_MARKER_NONE, ///< No resync marker - RESYNC_MARKER_BYTE, ///< BYTE Resync marker for MPEG4, H.264 - RESYNC_MARKER_MB, ///< MB resync marker for MPEG4, H.264 - RESYNC_MARKER_GOB ///< GOB resync marker for H.263 -}; - -union DynamicConfigData -{ - OMX_VIDEO_CONFIG_BITRATETYPE bitrate; - OMX_CONFIG_FRAMERATETYPE framerate; - QOMX_VIDEO_INTRAPERIODTYPE intraperiod; - OMX_CONFIG_INTRAREFRESHVOPTYPE intravoprefresh; - OMX_CONFIG_ROTATIONTYPE rotation; - float f_framerate; -}; - -struct DynamicConfig -{ - bool pending; - unsigned frame_num; - OMX_INDEXTYPE config_param; - union DynamicConfigData config_data; -}; - -#ifdef USE_ION -struct enc_ion -{ - int ion_device_fd; - struct ion_allocation_data alloc_data; - struct ion_fd_data ion_alloc_fd; -}; -#endif - -////////////////////////// -// MODULE VARS -////////////////////////// -static pthread_mutex_t m_mutex; -static pthread_cond_t m_signal; -static MsgQ m_sMsgQ; - -//#warning determine how many buffers we really have -OMX_STATETYPE m_eState = OMX_StateInvalid; -OMX_COMPONENTTYPE m_sComponent; -OMX_HANDLETYPE m_hHandle = NULL; -OMX_BUFFERHEADERTYPE* m_pOutBuffers[NUM_OUT_BUFFERS] = {NULL}; -OMX_BUFFERHEADERTYPE* m_pInBuffers[NUM_IN_BUFFERS] = {NULL}; -OMX_BOOL m_bInFrameFree[NUM_IN_BUFFERS]; - -ProfileType m_sProfile; - -static int m_nFramePlay = 0; -static int m_eMode = MODE_PREVIEW; -static int m_nInFd = -1; -static int m_nOutFd = -1; -static int m_nTimeStamp = 0; -static int m_nFrameIn = 0; // frames pushed to encoder -static int m_nFrameOut = 0; // frames returned by encoder -static int m_nAVCSliceMode = 0; -static bool m_bWatchDogKicked = false; -FILE *m_pDynConfFile = NULL; -static struct DynamicConfig dynamic_config; - -/* Statistics Logging */ -static long long tot_bufsize = 0; -int ebd_cnt=0, fbd_cnt=0; - -#ifdef USE_ION -static const char* PMEM_DEVICE = "/dev/ion"; -#elif MAX_RES_720P -static const char* PMEM_DEVICE = "/dev/pmem_adsp"; -#elif MAX_RES_1080P_EBI -static const char* PMEM_DEVICE = "/dev/pmem_adsp"; -#elif MAX_RES_1080P -static const char* PMEM_DEVICE = "/dev/pmem_smipool"; -#else -#error PMEM_DEVICE cannot be determined. -#endif - -#ifdef USE_ION -struct enc_ion ion_data; -#endif -////////////////////////// -// MODULE FUNCTIONS -////////////////////////// - -void* PmemMalloc(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, int nSize) -{ - void *pvirt = NULL; - int rc = 0; - - if (!pMem) - return NULL; - -#ifdef USE_ION - ion_data.ion_device_fd = open (PMEM_DEVICE, O_RDONLY); - if(ion_data.ion_device_fd < 0) - { - E("\nERROR: ION Device open() Failed"); - return NULL; - } - nSize = (nSize + 4095) & (~4095); - ion_data.alloc_data.len = nSize; - ion_data.alloc_data.heap_mask = 0x1 << ION_CP_MM_HEAP_ID; - ion_data.alloc_data.align = 4096; - ion_data.alloc_data.flags = ION_SECURE; - - rc = ioctl(ion_data.ion_device_fd,ION_IOC_ALLOC,&ion_data.alloc_data); - if(rc || !ion_data.alloc_data.handle) { - E("\n ION ALLOC memory failed rc: %d, handle: %p", rc, ion_data.alloc_data.handle); - ion_data.alloc_data.handle=NULL; - return NULL; - } - - ion_data.ion_alloc_fd.handle = ion_data.alloc_data.handle; - rc = ioctl(ion_data.ion_device_fd,ION_IOC_MAP,&ion_data.ion_alloc_fd); - if(rc) { - E("\n ION MAP failed "); - ion_data.ion_alloc_fd.fd =-1; - ion_data.ion_alloc_fd.fd =-1; - return NULL; - } - pMem->pmem_fd = ion_data.ion_alloc_fd.fd; -#else - pMem->pmem_fd = open(PMEM_DEVICE, O_RDWR); - if ((int)(pMem->pmem_fd) < 0) - return NULL; - nSize = (nSize + 4095) & (~4095); -#endif - pMem->offset = 0; - pvirt = mmap(NULL, nSize, - PROT_READ | PROT_WRITE, - MAP_SHARED, pMem->pmem_fd, pMem->offset); - if (pvirt == (void*) MAP_FAILED) - { - close(pMem->pmem_fd); - pMem->pmem_fd = -1; -#ifdef USE_ION - if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE, - &ion_data.alloc_data.handle)) { - E("ion recon buffer free failed"); - } - ion_data.alloc_data.handle = NULL; - ion_data.ion_alloc_fd.fd =-1; - close(ion_data.ion_device_fd); - ion_data.ion_device_fd =-1; -#endif - return NULL; - } - D("allocated pMem->fd = %lu pvirt=0x%p, pMem->phys=0x%lx, size = %d", pMem->pmem_fd, - pvirt, pMem->offset, nSize); - return pvirt; -} - -int PmemFree(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem, void* pvirt, int nSize) -{ - if (!pMem || !pvirt) - return -1; - - nSize = (nSize + 4095) & (~4095); - munmap(pvirt, nSize); - close(pMem->pmem_fd); - pMem->pmem_fd = -1; -#ifdef USE_ION - if(ioctl(ion_data.ion_device_fd,ION_IOC_FREE, - &ion_data.alloc_data.handle)) { - E("ion recon buffer free failed"); - } - ion_data.alloc_data.handle = NULL; - ion_data.ion_alloc_fd.fd =-1; - close(ion_data.ion_device_fd); - ion_data.ion_device_fd =-1; -#endif - return 0; -} -void PrintFramePackArrangement(OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement) -{ - printf("id (%lu)\n", - framePackingArrangement.id); - printf("cancel_flag (%lu)\n", - framePackingArrangement.cancel_flag); - printf("type (%lu)\n", - framePackingArrangement.type); - printf("quincunx_sampling_flag (%lu)\n", - framePackingArrangement.quincunx_sampling_flag); - printf("content_interpretation_type (%lu)\n", - framePackingArrangement.content_interpretation_type); - printf("spatial_flipping_flag (%lu)\n", - framePackingArrangement.spatial_flipping_flag); - printf("frame0_flipped_flag (%lu)\n", - framePackingArrangement.frame0_flipped_flag); - printf("field_views_flag (%lu)\n", - framePackingArrangement.field_views_flag); - printf("current_frame_is_frame0_flag (%lu)\n", - framePackingArrangement.current_frame_is_frame0_flag); - printf("frame0_self_contained_flag (%lu)\n", - framePackingArrangement.frame0_self_contained_flag); - printf("frame1_self_contained_flag (%lu)\n", - framePackingArrangement.frame1_self_contained_flag); - printf("frame0_grid_position_x (%lu)\n", - framePackingArrangement.frame0_grid_position_x); - printf("frame0_grid_position_y (%lu)\n", - framePackingArrangement.frame0_grid_position_y); - printf("frame1_grid_position_x (%lu)\n", - framePackingArrangement.frame1_grid_position_x); - printf("frame1_grid_position_y (%lu)\n", - framePackingArrangement.frame1_grid_position_y); - printf("reserved_byte (%lu)\n", - framePackingArrangement.reserved_byte); - printf("repetition_period (%lu)\n", - framePackingArrangement.repetition_period); - printf("extension_flag (%lu)\n", - framePackingArrangement.extension_flag); -} -void SetState(OMX_STATETYPE eState) -{ -#define GOTO_STATE(eState) \ - case eState: \ - { \ - D("Going to state " # eState"..."); \ - OMX_SendCommand(m_hHandle, \ - OMX_CommandStateSet, \ - (OMX_U32) eState, \ - NULL); \ - while (m_eState != eState) \ - { \ - sleep(1); \ - } \ - D("Now in state " # eState); \ - break; \ - } - - switch (eState) - { - GOTO_STATE(OMX_StateLoaded); - GOTO_STATE(OMX_StateIdle); - GOTO_STATE(OMX_StateExecuting); - GOTO_STATE(OMX_StateInvalid); - GOTO_STATE(OMX_StateWaitForResources); - GOTO_STATE(OMX_StatePause); - } -} -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE ConfigureEncoder() -{ - OMX_ERRORTYPE result = OMX_ErrorNone; - unsigned const int *profile_tbl = (unsigned int const *)mpeg4_profile_level_table; - OMX_U32 mb_per_sec, mb_per_frame; - bool profile_level_found = false; - OMX_U32 eProfile,eLevel; - - OMX_PARAM_PORTDEFINITIONTYPE portdef; // OMX_IndexParamPortDefinition -#ifdef QCOM_EXT - OMX_QCOM_PARAM_PORTDEFINITIONTYPE qPortDefnType; -#endif - portdef.nPortIndex = (OMX_U32) 0; // input - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamPortDefinition, - &portdef); - E("\n OMX_IndexParamPortDefinition Get Paramter on input port"); - CHK(result); - portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth; - portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight; - - E ("\n Height %lu width %lu bit rate %lu",portdef.format.video.nFrameHeight - ,portdef.format.video.nFrameWidth,portdef.format.video.nBitrate); - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamPortDefinition, - &portdef); - E("\n OMX_IndexParamPortDefinition Set Paramter on input port"); - CHK(result); - // once more to get proper buffer size - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamPortDefinition, - &portdef); - E("\n OMX_IndexParamPortDefinition Get Paramter on input port, 2nd pass"); - CHK(result); - // update size accordingly - m_sProfile.nFrameBytes = portdef.nBufferSize; - portdef.nPortIndex = (OMX_U32) 1; // output - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamPortDefinition, - &portdef); - E("\n OMX_IndexParamPortDefinition Get Paramter on output port"); - CHK(result); - portdef.format.video.nFrameWidth = m_sProfile.nFrameWidth; - portdef.format.video.nFrameHeight = m_sProfile.nFrameHeight; - portdef.format.video.nBitrate = m_sProfile.nBitrate; - FractionToQ16(portdef.format.video.xFramerate,(int) (m_sProfile.nFramerate * 2),2); - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamPortDefinition, - &portdef); - E("\n OMX_IndexParamPortDefinition Set Paramter on output port"); - CHK(result); - -#ifdef QCOM_EXT - -qPortDefnType.nPortIndex = PORT_INDEX_IN; -qPortDefnType.nMemRegion = OMX_QCOM_MemRegionEBI1; -qPortDefnType.nSize = sizeof(OMX_QCOM_PARAM_PORTDEFINITIONTYPE); - -result = OMX_SetParameter(m_hHandle, - (OMX_INDEXTYPE)OMX_QcomIndexPortDefn, - &qPortDefnType); - -#endif - if (!m_sProfile.nUserProfile) // profile not set by user, go ahead with table calculation - { - //validate the ht,width,fps,bitrate and set the appropriate profile and level - if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) - { - profile_tbl = (unsigned int const *)mpeg4_profile_level_table; - } - else if(m_sProfile.eCodec == OMX_VIDEO_CodingAVC) - { - profile_tbl = (unsigned int const *)h264_profile_level_table; - } - else if(m_sProfile.eCodec == OMX_VIDEO_CodingH263) - { - profile_tbl = (unsigned int const *)h263_profile_level_table; - } -#ifdef _MSM8974_ - else if(m_sProfile.eCodec == OMX_VIDEO_CodingVPX) - { - profile_tbl = (unsigned int const *)VP8_profile_level_table; - } -#endif - mb_per_frame = ((m_sProfile.nFrameHeight+15)>>4)* - ((m_sProfile.nFrameWidth+15)>>4); - - mb_per_sec = mb_per_frame*(m_sProfile.nFramerate); - - do{ - if(mb_per_frame <= (unsigned int)profile_tbl[0]) - { - if(mb_per_sec <= (unsigned int)profile_tbl[1]) - { - if(m_sProfile.nBitrate <= (unsigned int)profile_tbl[2]) - { - eLevel = (int)profile_tbl[3]; - eProfile = (int)profile_tbl[4]; - E("\n profile/level found: %lu/%lu\n",eProfile, eLevel); - profile_level_found = true; - break; - } - } - } - profile_tbl = profile_tbl + 5; - }while(profile_tbl[0] != 0); - - if ( profile_level_found != true ) - { - E("\n Error: Unsupported profile/level\n"); - return OMX_ErrorNone; - } - } - else // Profile set by user! - { - eProfile = m_sProfile.nUserProfile; - eLevel = 0; - } - if (m_sProfile.eCodec == OMX_VIDEO_CodingH263) - { - D("Configuring H263..."); - - OMX_VIDEO_PARAM_H263TYPE h263; - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoH263, - &h263); - CHK(result); - h263.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - h263.nPFrames = m_sProfile.nFramerate * 2 - 1; // intra period - h263.nBFrames = 0; - h263.eProfile = (OMX_VIDEO_H263PROFILETYPE)eProfile; - h263.eLevel = (OMX_VIDEO_H263LEVELTYPE)eLevel; - h263.bPLUSPTYPEAllowed = OMX_FALSE; - h263.nAllowedPictureTypes = 2; - h263.bForceRoundingTypeToZero = OMX_TRUE; - h263.nPictureHeaderRepetition = 0; - h263.nGOBHeaderInterval = 1; - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoH263, - &h263); - } - else - { - D("Configuring MP4/H264..."); - - OMX_VIDEO_PARAM_PROFILELEVELTYPE profileLevel; // OMX_IndexParamVideoProfileLevelCurrent - profileLevel.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - profileLevel.eProfile = eProfile; - profileLevel.eLevel = eLevel; - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoProfileLevelCurrent, - &profileLevel); - E("\n OMX_IndexParamVideoProfileLevelCurrent Set Paramter port"); - CHK(result); - //profileLevel.eLevel = (OMX_U32) m_sProfile.eLevel; - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoProfileLevelCurrent, - &profileLevel); - E("\n OMX_IndexParamVideoProfileLevelCurrent Get Paramter port"); - D ("\n Profile = %lu level = %lu",profileLevel.eProfile,profileLevel.eLevel); - CHK(result); - - if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) - { - OMX_VIDEO_PARAM_MPEG4TYPE mp4; // OMX_IndexParamVideoMpeg4 - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoMpeg4, - &mp4); - CHK(result); - mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - mp4.nTimeIncRes = 1000; - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoMpeg4, - &mp4); - CHK(result); - } - } - if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC) - { -#if 1 -/////////////C A B A C ///A N D/////D E B L O C K I N G ///////////////// - - OMX_VIDEO_PARAM_AVCTYPE avcdata; - avcdata.nPortIndex = (OMX_U32)PORT_INDEX_OUT; - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoAvc, - &avcdata); - CHK(result); -// TEST VALUES (CHANGE FOR DIFF CONFIG's) - avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterEnable; -// avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisable; -// avcdata.eLoopFilterMode = OMX_VIDEO_AVCLoopFilterDisableSliceBoundary; - avcdata.bEntropyCodingCABAC = OMX_FALSE; -// avcdata.bEntropyCodingCABAC = OMX_TRUE; - avcdata.nCabacInitIdc = 1; -/////////////////////////////////////////////// - - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoAvc, - &avcdata); - CHK(result); - -/////////////C A B A C ///A N D/////D E B L O C K I N G ///////////////// -#endif - } - - OMX_VIDEO_PARAM_BITRATETYPE bitrate; // OMX_IndexParamVideoBitrate - bitrate.nPortIndex = (OMX_U32)PORT_INDEX_OUT; - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoBitrate, - &bitrate); - E("\n OMX_IndexParamVideoBitrate Get Paramter port"); - CHK(result); - bitrate.eControlRate = m_sProfile.eControlRate; - bitrate.nTargetBitrate = m_sProfile.nBitrate; - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoBitrate, - &bitrate); - E("\n OMX_IndexParamVideoBitrate Set Paramter port"); - CHK(result); - - OMX_VIDEO_PARAM_PORTFORMATTYPE framerate; // OMX_IndexParamVidePortFormat - framerate.nPortIndex = 0; - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoPortFormat, - &framerate); - E("\n OMX_IndexParamVideoPortFormat Get Paramter port"); - CHK(result); - FractionToQ16(framerate.xFramerate,(int) (m_sProfile.nFramerate * 2),2); - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoPortFormat, - &framerate); - E("\n OMX_IndexParamVideoPortFormat Set Paramter port"); - CHK(result); - -#if 1 -///////////////////I N T R A P E R I O D /////////////////// - - QOMX_VIDEO_INTRAPERIODTYPE intra; - - intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output - result = OMX_GetConfig(m_hHandle, - (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod, - (OMX_PTR) &intra); - - if (result == OMX_ErrorNone) - { - intra.nPFrames = (OMX_U32) (2 * m_sProfile.nFramerate - 1); //setting I - //frame interval to - //2 x framerate - intra.nIDRPeriod = 1; //every I frame is an IDR - intra.nPortIndex = (OMX_U32) PORT_INDEX_OUT; - result = OMX_SetConfig(m_hHandle, - (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod, - (OMX_PTR) &intra); - } - else - { - E("failed to get state", 0, 0, 0); - } - - -///////////////////I N T R A P E R I O D /////////////////// -#endif - -#if 1 -///////////////////E R R O R C O R R E C T I O N /////////////////// - - ResyncMarkerType eResyncMarkerType = RESYNC_MARKER_NONE; - unsigned long int nResyncMarkerSpacing = 0; - OMX_BOOL enableHEC = OMX_FALSE; - -//For Testing ONLY - if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) - { -// MPEG4 -// eResyncMarkerType = RESYNC_MARKER_BYTE; -// nResyncMarkerSpacing = 1920; - eResyncMarkerType = RESYNC_MARKER_MB; - nResyncMarkerSpacing = 50; - enableHEC = OMX_TRUE; - } - else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263) - { -//H263 - //eResyncMarkerType = RESYNC_MARKER_GOB; - eResyncMarkerType = RESYNC_MARKER_NONE; - nResyncMarkerSpacing = 0; - } - else if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC) - { -//H264 -// eResyncMarkerType = RESYNC_MARKER_BYTE; -// nResyncMarkerSpacing = 1920; - - //nResyncMarkerSpacing sets the slice size in venc_set_multislice_cfg - // - //As of 9/24/10, it is known that the firmware has a bitstream - //corruption issue when RateControl and multislice are enabled for 720P - //So, disabling multislice for 720P when ratecontrol is enabled until - //the firmware issue is resolved. - - if ( ( (m_sProfile.nFrameWidth == 1280) && (m_sProfile.nFrameHeight = 720) ) && - (m_sProfile.eControlRate != OMX_Video_ControlRateDisable) ) - { - eResyncMarkerType = RESYNC_MARKER_NONE; - nResyncMarkerSpacing = 0; - } - else - { - eResyncMarkerType = RESYNC_MARKER_NONE; - nResyncMarkerSpacing = 0; - } - } - - OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE errorCorrection; //OMX_IndexParamVideoErrorCorrection - errorCorrection.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output - result = OMX_GetParameter(m_hHandle, - (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection, - (OMX_PTR) &errorCorrection); - - errorCorrection.bEnableRVLC = OMX_FALSE; - errorCorrection.bEnableDataPartitioning = OMX_FALSE; - - if ((eResyncMarkerType == RESYNC_MARKER_BYTE) && - (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4)){ - errorCorrection.bEnableResync = OMX_TRUE; - errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing; - errorCorrection.bEnableHEC = enableHEC; - } - else if ((eResyncMarkerType == RESYNC_MARKER_BYTE) && - (m_sProfile.eCodec == OMX_VIDEO_CodingAVC)){ - errorCorrection.bEnableResync = OMX_TRUE; - errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing; - } - else if ((eResyncMarkerType == RESYNC_MARKER_GOB) && - (m_sProfile.eCodec == OMX_VIDEO_CodingH263)){ - errorCorrection.bEnableResync = OMX_FALSE; - errorCorrection.nResynchMarkerSpacing = nResyncMarkerSpacing; - errorCorrection.bEnableDataPartitioning = OMX_TRUE; - } - - result = OMX_SetParameter(m_hHandle, - (OMX_INDEXTYPE) OMX_IndexParamVideoErrorCorrection, - (OMX_PTR) &errorCorrection); - CHK(result); - - if (eResyncMarkerType == RESYNC_MARKER_MB){ - if (m_sProfile.eCodec == OMX_VIDEO_CodingAVC){ - OMX_VIDEO_PARAM_AVCTYPE avcdata; - avcdata.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoAvc, - (OMX_PTR) &avcdata); - CHK(result); - if (result == OMX_ErrorNone) - { - avcdata.nSliceHeaderSpacing = nResyncMarkerSpacing; - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoAvc, - (OMX_PTR) &avcdata); - CHK(result); - - } - } - else if(m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4){ - OMX_VIDEO_PARAM_MPEG4TYPE mp4; - mp4.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoMpeg4, - (OMX_PTR) &mp4); - CHK(result); - - if (result == OMX_ErrorNone) - { - mp4.nSliceHeaderSpacing = nResyncMarkerSpacing; - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoMpeg4, - (OMX_PTR) &mp4); - CHK(result); - } - } - } - -///////////////////E R R O R C O R R E C T I O N /////////////////// -#endif - -#if 1 -///////////////////I N T R A R E F R E S H/////////////////// - bool bEnableIntraRefresh = OMX_TRUE; - - if (result == OMX_ErrorNone) - { - OMX_VIDEO_PARAM_INTRAREFRESHTYPE ir; // OMX_IndexParamVideoIntraRefresh - ir.nPortIndex = (OMX_U32) PORT_INDEX_OUT; // output - result = OMX_GetParameter(m_hHandle, - OMX_IndexParamVideoIntraRefresh, - (OMX_PTR) &ir); - if (result == OMX_ErrorNone) - { - if (bEnableIntraRefresh) - { - ir.eRefreshMode = OMX_VIDEO_IntraRefreshCyclic; - ir.nCirMBs = 5; - result = OMX_SetParameter(m_hHandle, - OMX_IndexParamVideoIntraRefresh, - (OMX_PTR) &ir); - CHK(result); - } - } - } -#endif -#if 1 -///////////////////FRAMEPACKING DATA/////////////////// - OMX_QCOM_FRAME_PACK_ARRANGEMENT framePackingArrangement; - FILE *m_pConfigFile; - char m_configFilename [128] = "/data/configFile.cfg"; - memset(&framePackingArrangement, 0, sizeof(framePackingArrangement)); - m_pConfigFile = fopen(m_configFilename, "r"); - if (m_pConfigFile != NULL) - { - //read all frame packing data - framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT; - int totalSizeToRead = FRAME_PACK_SIZE * sizeof(OMX_U32); - char *pFramePack = (char *) &(framePackingArrangement.id); - while ( ( (fscanf(m_pConfigFile, "%d", pFramePack)) != EOF ) && - (totalSizeToRead != 0) ) - { - //printf("Addr = %p, Value read = %d, sizeToRead remaining=%d\n", - // pFramePack, *pFramePack, totalSizeToRead); - pFramePack += sizeof(OMX_U32); - totalSizeToRead -= sizeof(OMX_U32); - } - //close the file. - fclose(m_pConfigFile); - - printf("Frame Packing data from config file:\n"); - PrintFramePackArrangement(framePackingArrangement); - } - else - { - D("\n Config file does not exist or could not be opened."); - //set the default values - framePackingArrangement.nPortIndex = (OMX_U32)PORT_INDEX_OUT; - framePackingArrangement.id = 123; - framePackingArrangement.cancel_flag = false; - framePackingArrangement.type = 3; - framePackingArrangement.quincunx_sampling_flag = false; - framePackingArrangement.content_interpretation_type = 0; - framePackingArrangement.spatial_flipping_flag = true; - framePackingArrangement.frame0_flipped_flag = false; - framePackingArrangement.field_views_flag = false; - framePackingArrangement.current_frame_is_frame0_flag = false; - framePackingArrangement.frame0_self_contained_flag = true; - framePackingArrangement.frame1_self_contained_flag = false; - framePackingArrangement.frame0_grid_position_x = 3; - framePackingArrangement.frame0_grid_position_y = 15; - framePackingArrangement.frame1_grid_position_x = 11; - framePackingArrangement.frame1_grid_position_y = 7; - framePackingArrangement.reserved_byte = 0; - framePackingArrangement.repetition_period = 16381; - framePackingArrangement.extension_flag = false; - - printf("Frame Packing Defaults :\n"); - PrintFramePackArrangement(framePackingArrangement); - } - result = OMX_SetConfig(m_hHandle, - (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement, - (OMX_PTR) &framePackingArrangement); - CHK(result); - -//////////////////////OMX_VIDEO_PARAM_INTRAREFRESHTYPE/////////////////// -#endif - - OMX_CONFIG_FRAMERATETYPE enc_framerate; // OMX_IndexConfigVideoFramerate - enc_framerate.nPortIndex = (OMX_U32)PORT_INDEX_OUT; - result = OMX_GetConfig(m_hHandle, - OMX_IndexConfigVideoFramerate, - &enc_framerate); - CHK(result); - FractionToQ16(enc_framerate.xEncodeFramerate,(int) (m_sProfile.nFramerate * 2),2); - result = OMX_SetConfig(m_hHandle, - OMX_IndexConfigVideoFramerate, - &enc_framerate); - CHK(result); - return OMX_ErrorNone; -} -//////////////////////////////////////////////////////////////////////////////// -void SendMessage(MsgId id, MsgData* data) -{ - pthread_mutex_lock(&m_mutex); - if (m_sMsgQ.size >= MAX_MSG) - { - E("main msg m_sMsgQ is full"); - return; - } - m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].id = id; - if (data) - m_sMsgQ.q[(m_sMsgQ.head + m_sMsgQ.size) % MAX_MSG].data = *data; - ++m_sMsgQ.size; - pthread_cond_signal(&m_signal); - pthread_mutex_unlock(&m_mutex); -} -//////////////////////////////////////////////////////////////////////////////// -void PopMessage(Msg* msg) -{ - pthread_mutex_lock(&m_mutex); - while (m_sMsgQ.size == 0) - { - pthread_cond_wait(&m_signal, &m_mutex); - } - *msg = m_sMsgQ.q[m_sMsgQ.head]; - --m_sMsgQ.size; - m_sMsgQ.head = (m_sMsgQ.head + 1) % MAX_MSG; - pthread_mutex_unlock(&m_mutex); -} -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE EVT_CB(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_EVENTTYPE eEvent, - OMX_IN OMX_U32 nData1, - OMX_IN OMX_U32 nData2, - OMX_IN OMX_PTR pEventData) -{ -#define SET_STATE(eState) \ - case eState: \ - { \ - D("" # eState " complete"); \ - m_eState = eState; \ - break; \ - } - - if (eEvent == OMX_EventCmdComplete) - { - if ((OMX_COMMANDTYPE) nData1 == OMX_CommandStateSet) - { - switch ((OMX_STATETYPE) nData2) - { - SET_STATE(OMX_StateLoaded); - SET_STATE(OMX_StateIdle); - SET_STATE(OMX_StateExecuting); - SET_STATE(OMX_StateInvalid); - SET_STATE(OMX_StateWaitForResources); - SET_STATE(OMX_StatePause); - default: - E("invalid state %d", (int) nData2); - } - } - } - - else if (eEvent == OMX_EventError) - { - E("OMX_EventError"); - } - - else - { - E("unexpected event %d", (int) eEvent); - } - return OMX_ErrorNone; -} -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE EBD_CB(OMX_IN OMX_HANDLETYPE hComponent, - OMX_IN OMX_PTR pAppData, - OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) -{ - D("Got EBD callback ts=%lld", pBuffer->nTimeStamp); - - for (int i = 0; i < num_in_buffers; i++) - { - // mark this buffer ready for use again - if (m_pInBuffers[i] == pBuffer) - { - - D("Marked input buffer idx %d as free, buf %p", i, pBuffer->pBuffer); - m_bInFrameFree[i] = OMX_TRUE; - break; - } - } - - if (m_eMode == MODE_LIVE_ENCODE) - { - CameraTest_ReleaseFrame(pBuffer->pBuffer, - ((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)pBuffer->pAppPrivate)); - } - else - { - // wake up main thread and tell it to send next frame - MsgData data; - data.sBitstreamData.pBuffer = pBuffer; - SendMessage(MSG_ID_INPUT_FRAME_DONE, - &data); - - } - return OMX_ErrorNone; -} -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE FBD_CB(OMX_OUT OMX_HANDLETYPE hComponent, - OMX_OUT OMX_PTR pAppData, - OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) -{ - D("Got FBD callback ts=%lld", pBuffer->nTimeStamp); - - static long long prevTime = 0; - long long currTime = GetTimeStamp(); - - m_bWatchDogKicked = true; - - /* Empty Buffers should not be counted */ - if(pBuffer->nFilledLen !=0) - { - /* Counting Buffers supplied from OpneMax Encoder */ - fbd_cnt++; - tot_bufsize += pBuffer->nFilledLen; - } - if (prevTime != 0) - { - long long currTime = GetTimeStamp(); - D("FBD_DELTA = %lld\n", currTime - prevTime); - } - prevTime = currTime; - - if (m_eMode == MODE_PROFILE) - { - // if we are profiling we are not doing file I/O - // so just give back to encoder - if (OMX_FillThisBuffer(m_hHandle, pBuffer) != OMX_ErrorNone) - { - E("empty buffer failed for profiling"); - } - } - else - { - // wake up main thread and tell it to write to file - MsgData data; - data.sBitstreamData.pBuffer = pBuffer; - SendMessage(MSG_ID_OUTPUT_FRAME_DONE, - &data); - } - return OMX_ErrorNone; -} -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE VencTest_Initialize() -{ - OMX_ERRORTYPE result = OMX_ErrorNone; - static OMX_CALLBACKTYPE sCallbacks = {EVT_CB, EBD_CB, FBD_CB}; - int i; - - for (i = 0; i < num_in_buffers; i++) - { - m_pInBuffers[i] = NULL; - } - - result = OMX_Init(); - CHK(result); - - if (m_sProfile.eCodec == OMX_VIDEO_CodingMPEG4) - { - result = OMX_GetHandle(&m_hHandle, - "OMX.qcom.video.encoder.mpeg4", - NULL, - &sCallbacks); - // CHK(result); - } - else if (m_sProfile.eCodec == OMX_VIDEO_CodingH263) - { - result = OMX_GetHandle(&m_hHandle, - "OMX.qcom.video.encoder.h263", - NULL, - &sCallbacks); - CHK(result); - } -#ifdef _MSM8974_ - else if (m_sProfile.eCodec == OMX_VIDEO_CodingVPX) - { - result = OMX_GetHandle(&m_hHandle, - "OMX.qcom.video.encoder.vp8", - NULL, - &sCallbacks); - CHK(result); - } -#endif - else - { - result = OMX_GetHandle(&m_hHandle, - "OMX.qcom.video.encoder.avc", - NULL, - &sCallbacks); - CHK(result); - } - - - result = ConfigureEncoder(); - CHK(result); - - return result; -} - -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE VencTest_RegisterYUVBuffer(OMX_BUFFERHEADERTYPE** ppBufferHeader, - OMX_U8 *pBuffer, - OMX_PTR pAppPrivate) -{ - OMX_ERRORTYPE result = OMX_ErrorNone; -#if 0 - D("register buffer"); - if ((result = OMX_AllocateBuffer(m_hHandle, - ppBufferHeader, - (OMX_U32) PORT_INDEX_IN, - pAppPrivate, - m_sProfile.nFrameBytes - )) != OMX_ErrorNone) - { - E("use buffer failed"); - } - else - { - E("Allocate Buffer Success %x", (*ppBufferHeader)->pBuffer); - } - #endif - D("register buffer"); - D("Calling UseBuffer for Input port"); - if ((result = OMX_UseBuffer(m_hHandle, - ppBufferHeader, - (OMX_U32) PORT_INDEX_IN, - pAppPrivate, - m_sProfile.nFrameBytes, - pBuffer)) != OMX_ErrorNone) - { - E("use buffer failed"); - } - - return result; -} -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE VencTest_EncodeFrame(void* pYUVBuff, - long long nTimeStamp) -{ - OMX_ERRORTYPE result = OMX_ErrorUndefined; - D("calling OMX empty this buffer"); - for (int i = 0; i < num_in_buffers; i++) - { - if (pYUVBuff == m_pInBuffers[i]->pBuffer) - { - m_pInBuffers[i]->nTimeStamp = nTimeStamp; - D("Sending Buffer - %x", m_pInBuffers[i]->pBuffer); - result = OMX_EmptyThisBuffer(m_hHandle, - m_pInBuffers[i]); - /* Counting Buffers supplied to OpenMax Encoder */ - if(OMX_ErrorNone == result) - ebd_cnt++; - CHK(result); - break; - } - } - return result; -} -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE VencTest_Exit(void) -{ - int i; - OMX_ERRORTYPE result = OMX_ErrorNone; - D("trying to exit venc"); - - D("going to idle state"); - SetState(OMX_StateIdle); - - - D("going to loaded state"); - //SetState(OMX_StateLoaded); - OMX_SendCommand(m_hHandle, - OMX_CommandStateSet, - (OMX_U32) OMX_StateLoaded, - NULL); - - for (i = 0; i < num_in_buffers; i++) - { - D("free buffer"); - if (m_pInBuffers[i]->pBuffer) - { - // free(m_pInBuffers[i]->pBuffer); - result = OMX_FreeBuffer(m_hHandle, - PORT_INDEX_IN, - m_pInBuffers[i]); - CHK(result); - } - else - { - E("buffer %d is null", i); - result = OMX_ErrorUndefined; - CHK(result); - } - } - for (i = 0; i < num_out_buffers; i++) - { - D("free buffer"); - if (m_pOutBuffers[i]->pBuffer) - { - free(m_pOutBuffers[i]->pBuffer); - result = OMX_FreeBuffer(m_hHandle, - PORT_INDEX_OUT, - m_pOutBuffers[i]); - CHK(result); - - } - else - { - E("buffer %d is null", i); - result = OMX_ErrorUndefined; - CHK(result); - } - } - - while (m_eState != OMX_StateLoaded) - { - sleep(1); - } - D("component_deinit..."); - result = OMX_Deinit(); - CHK(result); - - D("venc is exiting..."); - return result; -} -//////////////////////////////////////////////////////////////////////////////// - -void VencTest_ReadDynamicConfigMsg() -{ - char frame_n[8], config[16], param[8]; - char *dest = frame_n; - bool end = false; - int cntr, nparam = 0; - memset(&dynamic_config, 0, sizeof(struct DynamicConfig)); - do - { - cntr = -1; - do - { - dest[++cntr] = fgetc(m_pDynConfFile); - } while(dest[cntr] != ' ' && dest[cntr] != '\t' && dest[cntr] != '\n' && dest[cntr] != '\r' && !feof(m_pDynConfFile)); - if (dest[cntr] == '\n' || dest[cntr] == '\r') - end = true; - dest[cntr] = NULL; - if (dest == frame_n) - dest = config; - else if (dest == config) - dest = param; - else - end = true; - nparam++; - } while (!end && !feof(m_pDynConfFile)); - - if (nparam > 1) - { - dynamic_config.pending = true; - dynamic_config.frame_num = atoi(frame_n); - if (!strcmp(config, "bitrate")) - { - dynamic_config.config_param = OMX_IndexConfigVideoBitrate; - dynamic_config.config_data.bitrate.nPortIndex = PORT_INDEX_OUT; - dynamic_config.config_data.bitrate.nEncodeBitrate = strtoul(param, NULL, 10); - } - else if (!strcmp(config, "framerate")) - { - dynamic_config.config_param = OMX_IndexConfigVideoFramerate; - dynamic_config.config_data.framerate.nPortIndex = PORT_INDEX_OUT; - dynamic_config.config_data.f_framerate = atof(param); - } - else if (!strcmp(config, "iperiod")) - { - dynamic_config.config_param = (OMX_INDEXTYPE)QOMX_IndexConfigVideoIntraperiod; - dynamic_config.config_data.intraperiod.nPortIndex = PORT_INDEX_OUT; - dynamic_config.config_data.intraperiod.nPFrames = strtoul(param, NULL, 10) - 1; - dynamic_config.config_data.intraperiod.nIDRPeriod = 1; // This value is ignored in OMX component - } - else if (!strcmp(config, "ivoprefresh")) - { - dynamic_config.config_param = OMX_IndexConfigVideoIntraVOPRefresh; - dynamic_config.config_data.intravoprefresh.nPortIndex = PORT_INDEX_OUT; - dynamic_config.config_data.intravoprefresh.IntraRefreshVOP = OMX_TRUE; - } - else if (!strcmp(config, "rotation")) - { - dynamic_config.config_param = OMX_IndexConfigCommonRotate; - dynamic_config.config_data.rotation.nPortIndex = PORT_INDEX_OUT; - dynamic_config.config_data.rotation.nRotation = strtoul(param, NULL, 10); - } - else - { - E("UNKNOWN CONFIG PARAMETER: %s!", config); - dynamic_config.pending = false; - } - } - else if (feof(m_pDynConfFile)) - { - fclose(m_pDynConfFile); - m_pDynConfFile = NULL; - } -} - -void VencTest_ProcessDynamicConfigurationFile() -{ - do - { - if (dynamic_config.pending) - { - if(m_nFrameIn == dynamic_config.frame_num) - { - if (dynamic_config.config_param == OMX_IndexConfigVideoFramerate) - { - m_sProfile.nFramerate = dynamic_config.config_data.f_framerate; - FractionToQ16(dynamic_config.config_data.framerate.xEncodeFramerate, - (int)(m_sProfile.nFramerate * 2), 2); - } - if (OMX_SetConfig(m_hHandle, dynamic_config.config_param, - &dynamic_config.config_data) != OMX_ErrorNone) - E("ERROR: Setting dynamic config to OMX param[0x%x]", dynamic_config.config_param); - dynamic_config.pending = false; - } - else if (m_nFrameIn > dynamic_config.frame_num) - { - E("WARNING: Config change requested in passed frame(%d)", dynamic_config.frame_num); - dynamic_config.pending = false; - } - } - if (!dynamic_config.pending) - VencTest_ReadDynamicConfigMsg(); - } while (!dynamic_config.pending && m_pDynConfFile); -} - -//////////////////////////////////////////////////////////////////////////////// -OMX_ERRORTYPE VencTest_ReadAndEmpty(OMX_BUFFERHEADERTYPE* pYUVBuffer) -{ - OMX_ERRORTYPE result = OMX_ErrorNone; -#ifdef T_ARM -#if defined(MAX_RES_720P) && !defined(_MSM8974_) - if (read(m_nInFd, - pYUVBuffer->pBuffer, - m_sProfile.nFrameBytes) != m_sProfile.nFrameBytes) - { - return OMX_ErrorUndefined; - } -#elif _MSM8974_ - int i, lscanl, lstride, cscanl, cstride, height, width; - int bytes = 0, read_bytes = 0; - OMX_U8 *yuv = pYUVBuffer->pBuffer; - height = m_sProfile.nFrameHeight; - width = m_sProfile.nFrameWidth; - lstride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width); - lscanl = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height); - cstride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width); - cscanl = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height); - - for(i = 0; i < height; i++) { - bytes = read(m_nInFd, yuv, width); - if (bytes != width) { - E("read failed: %d != %d\n", read, width); - return OMX_ErrorUndefined; - } - read_bytes += bytes; - yuv += lstride; - } - yuv = pYUVBuffer->pBuffer + (lscanl * lstride); - for (i = 0; i < ((height + 1) >> 1); i++) { - bytes = read(m_nInFd, yuv, width); - if (bytes != width) { - E("read failed: %d != %d\n", read, width); - return OMX_ErrorUndefined; - } - read_bytes += bytes; - yuv += cstride; - } - m_sProfile.nFrameRead = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height); - E("\n\nActual read bytes: %d, NV12 buffer size: %d\n\n\n", read_bytes, m_sProfile.nFrameRead); -#else - OMX_U32 bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight; - // read Y first - if (read(m_nInFd, - pYUVBuffer->pBuffer, - bytestoread) != bytestoread) - return OMX_ErrorUndefined; - - // check alignment for offset to C - OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight; - - const OMX_U32 C_2K = (1024*2), - MASK_2K = C_2K-1, - IMASK_2K = ~MASK_2K; - - if (offset_to_c & MASK_2K) - { - // offset to C is not 2k aligned, adjustment is required - offset_to_c = (offset_to_c & IMASK_2K) + C_2K; - } - - bytestoread = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2; - // read C - if (read(m_nInFd, - pYUVBuffer->pBuffer + offset_to_c, - bytestoread)!= bytestoread) - return OMX_ErrorUndefined; -#endif -#else - { - char * pInputbuf = (char *)(pYUVBuffer->pBuffer) ; - read(m_nInFd,pInputbuf,m_sProfile.nFrameBytes) ; - - } -#endif - if (m_pDynConfFile) - VencTest_ProcessDynamicConfigurationFile(); - D("about to call VencTest_EncodeFrame..."); - pthread_mutex_lock(&m_mutex); - ++m_nFrameIn; -#ifdef _MSM8974_ - pYUVBuffer->nFilledLen = m_sProfile.nFrameRead; -#else - pYUVBuffer->nFilledLen = m_sProfile.nFrameBytes; -#endif - D("Called Buffer with Data filled length %d",pYUVBuffer->nFilledLen); - - result = VencTest_EncodeFrame(pYUVBuffer->pBuffer, - m_nTimeStamp); - - m_nTimeStamp += (1000000) / m_sProfile.nFramerate; - CHK(result); - pthread_mutex_unlock(&m_mutex); - return result; -} -//////////////////////////////////////////////////////////////////////////////// -void PreviewCallback(int nFD, - int nOffset, - void* pPhys, - void* pVirt, - long long nTimeStamp) -{ - - D("================= preview frame %d, phys=0x%x, nTimeStamp(millis)=%lld", - m_nFrameIn+1, pPhys, (nTimeStamp / 1000)); - - if (m_nFrameIn == m_nFramePlay && - m_nFramePlay != 0) - { - // we will stop camera after last frame is encoded. - // for now just ignore input frames - - CameraTest_ReleaseFrame(pPhys, pVirt); - return; - } - - // see if we should stop - pthread_mutex_lock(&m_mutex); - ++m_nFrameIn; - pthread_mutex_unlock(&m_mutex); - - - if (m_eMode == MODE_LIVE_ENCODE) - { - - OMX_ERRORTYPE result; - - // register new camera buffers with encoder - int i; - for (i = 0; i < num_in_buffers; i++) - { - if (m_pInBuffers[i] != NULL && - m_pInBuffers[i]->pBuffer == pPhys) - { - break; - } - else if (m_pInBuffers[i] == NULL) - { - D("registering buffer..."); - result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i], - (OMX_U8*) pPhys, - (OMX_PTR) pVirt); // store virt in app private field - D("register done"); - CHK(result); - break; - } - } - - if (i == num_in_buffers) - { - E("There are more camera buffers than we thought"); - CHK(1); - } - - // encode the yuv frame - - D("StartEncodeTime=%lld", GetTimeStamp()); - result = VencTest_EncodeFrame(pPhys, - nTimeStamp); - CHK(result); - // FBTest_DisplayImage(nFD, nOffset); - } - else - { - // FBTest_DisplayImage(nFD, nOffset); - CameraTest_ReleaseFrame(pPhys, pVirt); - } -} -//////////////////////////////////////////////////////////////////////////////// -void usage(char* filename) -{ - char* fname = strrchr(filename, (int) '/'); - fname = (fname == NULL) ? filename : fname; - - fprintf(stderr, "usage: %s LIVE \n", fname); - fprintf(stderr, "usage: %s FILE ", fname); - fprintf(stderr, " \n", fname); - fprintf(stderr, "usage: %s PROFILE \n", fname); - fprintf(stderr, "usage: %s PREVIEW \n", fname); - fprintf(stderr, "usage: %s DISPLAY \n", fname); - fprintf(stderr, "\n BITRATE - bitrate in kbps\n"); - fprintf(stderr, " FPS - frames per second\n"); - fprintf(stderr, " NFRAMES - number of frames to play, 0 for infinite\n"); - fprintf(stderr, " RateControl (Values 0 - 4 for RC_OFF, RC_CBR_CFR, RC_CBR_VFR, RC_VBR_CFR, RC_VBR_VFR\n"); - exit(1); -} - -bool parseWxH(char *str, OMX_U32 *width, OMX_U32 *height) -{ - bool parseOK = false; - const char delimiters[] = " x*,"; - char *token, *dupstr, *temp; - OMX_U32 w, h; - - dupstr = strdup(str); - token = strtok_r(dupstr, delimiters, &temp); - if (token) - { - w = strtoul(token, NULL, 10); - token = strtok_r(NULL, delimiters, &temp); - if (token) - { - h = strtoul(token, NULL, 10); - if (w != ULONG_MAX && h != ULONG_MAX) - { -#ifdef MAX_RES_720P - if ((w * h >> 8) <= 3600) - { - parseOK = true; - *width = w; - *height = h; - } -#else - if ((w * h >> 8) <= 8160) - { - parseOK = true; - *width = w; - *height = h; - } -#endif - else - E("\nInvalid dimensions %dx%d",w,h); - } - } - } - free(dupstr); - return parseOK; -} - -//////////////////////////////////////////////////////////////////////////////// -void parseArgs(int argc, char** argv) -{ - int dyn_file_arg = argc; - if (argc == 1) - { - usage(argv[0]); - } - else if (strcmp("PREVIEW", argv[1]) == 0 || - strcmp("preview", argv[1]) == 0) - { - m_eMode = MODE_PREVIEW; - if (argc != 5) - { - usage(argv[0]); - } - } - else if (strcmp("DISPLAY", argv[1]) == 0 || - strcmp("display", argv[1]) == 0) - { - m_eMode = MODE_DISPLAY; - if (argc != 6) - { - usage(argv[0]); - } - m_sProfile.cInFileName = argv[5]; - m_sProfile.cOutFileName = NULL; - } - else if (strcmp("LIVE", argv[1]) == 0 || - strcmp("live", argv[1]) == 0) - {//263 - m_eMode = MODE_LIVE_ENCODE; - if (argc != 8) - { - usage(argv[0]); - } - m_sProfile.cInFileName = NULL; - m_sProfile.cOutFileName = argv[7]; - } - else if (strcmp("FILE", argv[1]) == 0 || - strcmp("file", argv[1]) == 0) - {//263 - m_eMode = MODE_FILE_ENCODE; - - if(argc < 9 || argc > 13) - { - usage(argv[0]); - } - else - { - if (argc > 9) - dyn_file_arg = 9; - - if (argc > 10) - { - m_sProfile.eControlRate = OMX_Video_ControlRateVariable; - int RC = atoi(argv[10]); - - switch (RC) - { - case 0: - m_sProfile.eControlRate = OMX_Video_ControlRateDisable ;//VENC_RC_NONE - break; - case 1: - m_sProfile.eControlRate = OMX_Video_ControlRateConstant;//VENC_RC_CBR_CFR - break; - - case 2: - m_sProfile.eControlRate = OMX_Video_ControlRateConstantSkipFrames;//VENC_RC_CBR_VFR - break; - - case 3: - m_sProfile.eControlRate =OMX_Video_ControlRateVariable ;//VENC_RC_VBR_CFR - break; - - case 4: - m_sProfile.eControlRate = OMX_Video_ControlRateVariableSkipFrames;//VENC_RC_VBR_VFR - break; - - default: - E("invalid rate control selection"); - m_sProfile.eControlRate = OMX_Video_ControlRateVariable; //VENC_RC_VBR_CFR - break; - } - } - - if (argc > 11) - { - int profile_argi = 11; - if(!strcmp(argv[3], "H264") || !strcmp(argv[3], "h264")) - { - profile_argi = 12; - D("\nSetting AVCSliceMode ... "); - int AVCSliceMode = atoi(argv[11]); - switch(AVCSliceMode) - { - case 0: - m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; - break; - - case 1: - m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCMBSlice; - break; - - case 2: - m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCByteSlice; - break; - - default: - E("invalid Slice Mode"); - m_sProfile.eSliceMode = OMX_VIDEO_SLICEMODE_AVCDefault; - break; - } - } - if (profile_argi < argc) - { - if (!strncmp(argv[profile_argi], "0x", 2) || !strncmp(argv[profile_argi], "0x", 2)) - { - m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 16); - } - else - { - m_sProfile.nUserProfile = strtoul(argv[profile_argi], NULL, 10); - } - if (!m_sProfile.nUserProfile || m_sProfile.nUserProfile == ULONG_MAX) - { - E("invalid specified Profile %s, using default", argv[profile_argi]); - m_sProfile.nUserProfile = 0; - } - } - } - } - m_sProfile.cInFileName = argv[7]; - m_sProfile.cOutFileName = argv[8]; - } - else if (strcmp("PROFILE", argv[1]) == 0 || - strcmp("profile", argv[1]) == 0) - {//263 - m_eMode = MODE_PROFILE; - if (argc != 8) - { - usage(argv[0]); - } - m_sProfile.cInFileName = argv[7]; - m_sProfile.cOutFileName = NULL; - } - else - { - usage(argv[0]); - } - - - if (strcmp("QCIF", argv[2]) == 0 || - strcmp("qcif", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 176; - m_sProfile.nFrameHeight = 144; - m_sProfile.nFrameBytes = 176*144*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level0; - } - else if (strcmp("QVGA", argv[2]) == 0 || - strcmp("qvga", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 320; - m_sProfile.nFrameHeight = 240; - m_sProfile.nFrameBytes = 320*240*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } - - - else if (strcmp("VGA", argv[2]) == 0 || - strcmp("vga", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 640; - m_sProfile.nFrameHeight = 480; - m_sProfile.nFrameBytes = 640*480*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } - - else if (strcmp("WVGA", argv[2]) == 0 || - strcmp("wvga", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 800; - m_sProfile.nFrameHeight = 480; - m_sProfile.nFrameBytes = 800*480*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } - else if (strcmp("CIF", argv[2]) == 0 || - strcmp("cif", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 352; - m_sProfile.nFrameHeight = 288; - m_sProfile.nFrameBytes = 352*288*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } - else if (strcmp("720", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 1280; - m_sProfile.nFrameHeight = 720; - m_sProfile.nFrameBytes = 720*1280*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } - else if (strcmp("1080", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 1920; - m_sProfile.nFrameHeight = 1080; - m_sProfile.nFrameBytes = 1920*1080*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } -#ifdef _MSM8974_ - else if (strcmp("4K2K", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 4096; - m_sProfile.nFrameHeight = 2160; - m_sProfile.nFrameBytes = 4096*2160*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } - else if (strcmp("2160P", argv[2]) == 0) - { - m_sProfile.nFrameWidth = 3840; - m_sProfile.nFrameHeight = 2160; - m_sProfile.nFrameBytes = 3840*2160*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } -#endif - else if (parseWxH(argv[2], &m_sProfile.nFrameWidth, &m_sProfile.nFrameHeight)) - { - m_sProfile.nFrameBytes = m_sProfile.nFrameWidth*m_sProfile.nFrameHeight*3/2; - m_sProfile.eLevel = OMX_VIDEO_MPEG4Level1; - } - else - { - usage(argv[0]); - } - -#ifdef _MSM8974_ - m_sProfile.nFramestride = (m_sProfile.nFrameWidth + 31) & (~31); - m_sProfile.nFrameScanlines = (m_sProfile.nFrameHeight + 31) & (~31); - m_sProfile.nFrameBytes = ((m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2) + 4095) & (~4095); - m_sProfile.nFrameRead = m_sProfile.nFramestride * m_sProfile.nFrameScanlines * 3/2; -#endif - if (m_eMode == MODE_DISPLAY || - m_eMode == MODE_PREVIEW) - { - m_sProfile.nFramerate = atof(argv[3]); - m_nFramePlay = atoi(argv[4]); - - } - else if (m_eMode == MODE_LIVE_ENCODE || - m_eMode == MODE_FILE_ENCODE || - m_eMode == MODE_PROFILE) - { - if ((!strcmp(argv[3], "MP4")) || (!strcmp(argv[3], "mp4"))) - { - m_sProfile.eCodec = OMX_VIDEO_CodingMPEG4; - } - else if ((!strcmp(argv[3], "H263")) || (!strcmp(argv[3], "h263"))) - { - m_sProfile.eCodec = OMX_VIDEO_CodingH263; - } - else if ((!strcmp(argv[3], "H264")) || (!strcmp(argv[3], "h264"))) - { - m_sProfile.eCodec = OMX_VIDEO_CodingAVC; - } -#ifdef _MSM8974_ - else if ((!strcmp(argv[3], "VP8")) || (!strcmp(argv[3], "vp8"))) - { - m_sProfile.eCodec = OMX_VIDEO_CodingVPX; - } -#endif - else - { - usage(argv[0]); - } - - m_sProfile.nFramerate = atof(argv[4]); - m_sProfile.nBitrate = atoi(argv[5]); -// m_sProfile.eControlRate = OMX_Video_ControlRateVariable; - m_nFramePlay = atoi(argv[6]); - if (dyn_file_arg < argc) - { - m_pDynConfFile = fopen(argv[dyn_file_arg], "r"); - if (!m_pDynConfFile) - E("ERROR: Cannot open dynamic config file: %s", argv[dyn_file_arg]); - else - { - memset(&dynamic_config, 0, sizeof(struct DynamicConfig)); - } - } - } -} - -void* Watchdog(void* data) -{ - while (1) - { - sleep(1000); - if (m_bWatchDogKicked == true) - m_bWatchDogKicked = false; - else - E("watchdog has not been kicked. we may have a deadlock"); - } - return NULL; -} - -int main(int argc, char** argv) -{ - OMX_U8* pvirt = NULL; - int result; - float enc_time_sec=0.0,enc_time_usec=0.0; - - m_nInFd = -1; - m_nOutFd = -1; - m_nTimeStamp = 0; - m_nFrameIn = 0; - m_nFrameOut = 0; - - memset(&m_sMsgQ, 0, sizeof(MsgQ)); - memset(&m_sProfile, 0, sizeof(m_sProfile)); - parseArgs(argc, argv); - - D("fps=%f, bitrate=%u, width=%u, height=%u, frame bytes=%u", - m_sProfile.nFramerate, - m_sProfile.nBitrate, - m_sProfile.nFrameWidth, - m_sProfile.nFrameHeight, - m_sProfile.nFrameBytes); -#ifdef _MSM8974_ - D("Frame stride=%u, scanlines=%u, read=%u", - m_sProfile.nFramestride, - m_sProfile.nFrameScanlines, - m_sProfile.nFrameRead); -#endif - - - //if (m_eMode != MODE_PREVIEW && m_eMode != MODE_DISPLAY) - //{ - // pthread_t wd; - // pthread_create(&wd, NULL, Watchdog, NULL); - //} - - for (int x = 0; x < num_in_buffers; x++) - { - // mark all buffers as ready to use - m_bInFrameFree[x] = OMX_TRUE; - } - - - if (m_eMode != MODE_PROFILE) - { - #if T_ARM - m_nOutFd = open(m_sProfile.cOutFileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); - #else - m_nOutFd = open(m_sProfile.cOutFileName,0); - #endif - if (m_nOutFd < 0) - { - E("could not open output file %s", m_sProfile.cOutFileName); - CHK(1); - } - } - - pthread_mutex_init(&m_mutex, NULL); - pthread_cond_init(&m_signal, NULL); - - if (m_eMode != MODE_PREVIEW) - { - VencTest_Initialize(); - } - - //////////////////////////////////////// - // Camera + Encode - //////////////////////////////////////// - if (m_eMode == MODE_LIVE_ENCODE) - { - CameraTest_Initialize(m_sProfile.nFramerate, - m_sProfile.nFrameWidth, - m_sProfile.nFrameHeight, - PreviewCallback); - CameraTest_Run(); - } - - if (m_eMode == MODE_FILE_ENCODE || - m_eMode == MODE_PROFILE) - { - int i; - #if T_ARM - m_nInFd = open(m_sProfile.cInFileName, O_RDONLY); - #else - m_nInFd = open(m_sProfile.cInFileName,1); - #endif - if (m_nInFd < 0) - { - E("could not open input file"); - CHK(1); - - } - D("going to idle state"); - //SetState(OMX_StateIdle); - OMX_SendCommand(m_hHandle, - OMX_CommandStateSet, - (OMX_U32) OMX_StateIdle, - NULL); - - OMX_PARAM_PORTDEFINITIONTYPE portDef; - - portDef.nPortIndex = 0; - result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef); - CHK(result); - - D("allocating Input buffers"); - num_in_buffers = portDef.nBufferCountActual; - for (i = 0; i < portDef.nBufferCountActual; i++) - { - OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO* pMem = new OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO; - pvirt = (OMX_U8*)PmemMalloc(pMem, m_sProfile.nFrameBytes); - - if(pvirt == NULL) - { - CHK(1); - } - result = VencTest_RegisterYUVBuffer(&m_pInBuffers[i], - (OMX_U8*) pvirt, - (OMX_PTR) pMem); - CHK(result); - } - } - else if (m_eMode == MODE_LIVE_ENCODE) - { - D("going to idle state"); - //SetState(OMX_StateIdle); - OMX_SendCommand(m_hHandle, - OMX_CommandStateSet, - (OMX_U32) OMX_StateIdle, - NULL); - } - - int i; - OMX_PARAM_PORTDEFINITIONTYPE portDef; - - portDef.nPortIndex = 1; - result = OMX_GetParameter(m_hHandle, OMX_IndexParamPortDefinition, &portDef); - CHK(result); - - D("allocating & calling usebuffer for Output port"); - num_out_buffers = portDef.nBufferCountActual; - for (i = 0; i < portDef.nBufferCountActual; i++) - { - void* pBuff; - - pBuff = malloc(portDef.nBufferSize); - D("portDef.nBufferSize = %d ",portDef.nBufferSize); - result = OMX_UseBuffer(m_hHandle, - &m_pOutBuffers[i], - (OMX_U32) PORT_INDEX_OUT, - NULL, - portDef.nBufferSize, - (OMX_U8*) pBuff); - CHK(result); - } - D("allocate done"); - - // D("Going to state " # eState"..."); - - while (m_eState != OMX_StateIdle) - { - sleep(1); - } - //D("Now in state " # eState); - - - D("going to executing state"); - SetState(OMX_StateExecuting); - for (i = 0; i < num_out_buffers; i++) - { - D("filling buffer %d", i); - result = OMX_FillThisBuffer(m_hHandle, m_pOutBuffers[i]); - //sleep(1000); - CHK(result); - } - - if (m_eMode == MODE_FILE_ENCODE) - { - // encode the first frame to kick off the whole process - VencTest_ReadAndEmpty(m_pInBuffers[0]); - // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[0]->pAppPrivate)->fd,0); - } - - if (m_eMode == MODE_PROFILE) - { - int i; - - // read several frames into memory - D("reading frames into memory"); - for (i = 0; i < num_in_buffers; i++) - { - D("[%d] address 0x%x",i, m_pInBuffers[i]->pBuffer); -#ifdef MAX_RES_720P - read(m_nInFd, - m_pInBuffers[i]->pBuffer, - m_sProfile.nFrameBytes); -#else - // read Y first - read(m_nInFd, - m_pInBuffers[i]->pBuffer, - m_sProfile.nFrameWidth*m_sProfile.nFrameHeight); - - // check alignment for offset to C - OMX_U32 offset_to_c = m_sProfile.nFrameWidth * m_sProfile.nFrameHeight; - - const OMX_U32 C_2K = (1024*2), - MASK_2K = C_2K-1, - IMASK_2K = ~MASK_2K; - - if (offset_to_c & MASK_2K) - { - // offset to C is not 2k aligned, adjustment is required - offset_to_c = (offset_to_c & IMASK_2K) + C_2K; - } - - // read C - read(m_nInFd, - m_pInBuffers[i]->pBuffer + offset_to_c, - m_sProfile.nFrameWidth*m_sProfile.nFrameHeight/2); -#endif - - } - - // FBTest_Initialize(m_sProfile.nFrameWidth, m_sProfile.nFrameHeight); - - // loop over the mem-resident frames and encode them - D("beging playing mem-resident frames..."); - for (i = 0; m_nFramePlay == 0 || i < m_nFramePlay; i++) - { - int idx = i % num_in_buffers; - if (m_bInFrameFree[idx] == OMX_FALSE) - { - int j; - E("the expected buffer is not free, but lets find another"); - - idx = -1; - - // lets see if we can find another free buffer - for (j = 0; j < num_in_buffers; j++) - { - if(m_bInFrameFree[j]) - { - idx = j; - break; - } - } - } - - // if we have a free buffer let's encode it - if (idx >= 0) - { - D("encode frame %d...m_pInBuffers[idx]->pBuffer=0x%x", i,m_pInBuffers[idx]->pBuffer); - m_bInFrameFree[idx] = OMX_FALSE; - VencTest_EncodeFrame(m_pInBuffers[idx]->pBuffer, - m_nTimeStamp); - D("display frame %d...", i); - // FBTest_DisplayImage(((PmemBuffer*) m_pInBuffers[idx]->pAppPrivate)->fd,0); - m_nTimeStamp += 1000000 / m_sProfile.nFramerate; - } - else - { - E("wow, no buffers are free, performance " - "is not so good. lets just sleep some more"); - - } - D("sleep for %d microsec", 1000000/m_sProfile.nFramerate); - sleep (1000000 / m_sProfile.nFramerate); - } - // FBTest_Exit(); - } - - Msg msg; - bool bQuit = false; - while ((m_eMode == MODE_FILE_ENCODE || m_eMode == MODE_LIVE_ENCODE) && - !bQuit) - { - PopMessage(&msg); - switch (msg.id) - { - ////////////////////////////////// - // FRAME IS ENCODED - ////////////////////////////////// - case MSG_ID_INPUT_FRAME_DONE: - /*pthread_mutex_lock(&m_mutex); - ++m_nFrameOut; - if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0) - { - bQuit = true; - } - pthread_mutex_unlock(&m_mutex);*/ - - if (!bQuit && m_eMode == MODE_FILE_ENCODE) - { - D("pushing another frame down to encoder"); - if (VencTest_ReadAndEmpty(msg.data.sBitstreamData.pBuffer)) - { - // we have read the last frame - D("main is exiting..."); - bQuit = true; - } - } - break; - case MSG_ID_OUTPUT_FRAME_DONE: - D("================ writing frame %d = %d bytes to output file", - m_nFrameOut+1, - msg.data.sBitstreamData.pBuffer->nFilledLen); - D("StopEncodeTime=%lld", GetTimeStamp()); - - - write(m_nOutFd, - msg.data.sBitstreamData.pBuffer->pBuffer, - msg.data.sBitstreamData.pBuffer->nFilledLen); - - - result = OMX_FillThisBuffer(m_hHandle, - msg.data.sBitstreamData.pBuffer); - - if (result != OMX_ErrorNone) - { - CHK(result); - } - - pthread_mutex_lock(&m_mutex); - ++m_nFrameOut; - if (m_nFrameOut == m_nFramePlay && m_nFramePlay != 0) - { - bQuit = true; - } - pthread_mutex_unlock(&m_mutex); - break; - - default: - E("invalid msg id %d", (int) msg.id); - } // end switch (msg.id) - -/* // TO UNCOMMENT FOR PAUSE TESTINGS - if(m_nFrameOut == 10) - { - E("\nGoing to Pause state\n"); - SetState(OMX_StatePause); - sleep(3); -//REQUEST AN I FRAME AFTER PAUSE - OMX_CONFIG_INTRAREFRESHVOPTYPE voprefresh; - voprefresh.nPortIndex = (OMX_U32)PORT_INDEX_OUT; - voprefresh.IntraRefreshVOP = OMX_TRUE; - result = OMX_SetConfig(m_hHandle, - OMX_IndexConfigVideoIntraVOPRefresh, - &voprefresh); - E("\n OMX_IndexConfigVideoIntraVOPRefresh Set Paramter port"); - CHK(result); - E("\nGoing to executing state\n"); - SetState(OMX_StateExecuting); - } -*/ - } // end while (!bQuit) - - - if (m_eMode == MODE_LIVE_ENCODE) - { - CameraTest_Exit(); - close(m_nOutFd); - } - else if (m_eMode == MODE_FILE_ENCODE || - m_eMode == MODE_PROFILE) - { - // deallocate pmem buffers - for (int i = 0; i < num_in_buffers; i++) - { - PmemFree((OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*)m_pInBuffers[i]->pAppPrivate, - m_pInBuffers[i]->pBuffer, - m_sProfile.nFrameBytes); - delete (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*) m_pInBuffers[i]->pAppPrivate; - } - close(m_nInFd); - - if (m_eMode == MODE_FILE_ENCODE) - { - close(m_nOutFd); - } - if (m_pDynConfFile) - { - fclose(m_pDynConfFile); - m_pDynConfFile = NULL; - } - } - - if (m_eMode != MODE_PREVIEW) - { - D("exit encoder test"); - VencTest_Exit(); - } - - pthread_mutex_destroy(&m_mutex); - pthread_cond_destroy(&m_signal); - - /* Time Statistics Logging */ - if(0 != m_sProfile.nFramerate) - { - enc_time_usec = m_nTimeStamp - (1000000 / m_sProfile.nFramerate); - enc_time_sec =enc_time_usec/1000000; - if(0 != enc_time_sec) - { - printf("Total Frame Rate: %f",ebd_cnt/enc_time_sec); - printf("\nEncoder Bitrate :%lf Kbps",(tot_bufsize*8)/(enc_time_sec*1000)); - } - } - else - { - printf("\n\n Encode Time is zero"); - } - printf("\nTotal Number of Frames :%d",ebd_cnt); - printf("\nNumber of dropped frames during encoding:%d\n",ebd_cnt-fbd_cnt); - /* End of Time Statistics Logging */ - - D("main has exited"); - return 0; -} diff --git a/mm-video/vidc/venc/test/venc_util.c b/mm-video/vidc/venc/test/venc_util.c deleted file mode 100755 index 4e4688e8..00000000 --- a/mm-video/vidc/venc/test/venc_util.c +++ /dev/null @@ -1,51 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -/*============================================================================ - V E N C _ U T I L. C - -DESCRIPTION - - -REFERENCES - -============================================================================*/ - -#include "venc_util.h" -#include -#include - -long long GetTimeStamp() -{ - struct timeval tv; - long long microsec; - gettimeofday(&tv, NULL); - microsec = (tv.tv_sec * 1000000) + (tv.tv_usec); - return microsec; - -} - diff --git a/mm-video/vidc/venc/test/video_encoder_test.c b/mm-video/vidc/venc/test/video_encoder_test.c deleted file mode 100755 index 567d081b..00000000 --- a/mm-video/vidc/venc/test/video_encoder_test.c +++ /dev/null @@ -1,1064 +0,0 @@ -/*-------------------------------------------------------------------------- -Copyright (c) 2010-2011, The Linux Foundation. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of The Linux Foundation nor - the names of its contributors may be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------*/ -#include "video_encoder_test.h" - -#define DEBUG_PRINT printf -/************************************************************************/ -/* #DEFINES */ -/************************************************************************/ - -#define VOP_START_CODE 0x000001B6 -#define SHORT_HEADER_START_CODE 0x00008000 -#define H264_START_CODE 0x00000001 - -/************************************************************************/ -/* STATIC VARIABLES */ -/************************************************************************/ - -static int Code_type; -static int total_frames = 0; -static unsigned int header_code = 0; -static pthread_mutex_t read_lock; - -static unsigned int read_frame ( unsigned char *dataptr,unsigned int length, - FILE * inputBufferFile - ); -static unsigned clp2(unsigned x) -{ - x = x - 1; - x = x | (x >> 1); - x = x | (x >> 2); - x = x | (x >> 4); - x = x | (x >> 8); - x = x | (x >>16); - return x + 1; -} - - -static void* video_thread (void *); -static void* async_thread (void *); - - - -int main (int argc, char **argv) -{ - struct video_encoder_context *encoder_context = NULL; - char *file_name = NULL; - FILE *file_ptr = NULL; - int temp1 =0,temp2 =0; - int error = 1; - unsigned int i = 0; - - file_name = argv [1]; - file_ptr = fopen (file_name,"rb"); - - if (file_ptr == NULL) - { - DEBUG_PRINT("\n File is not located "); - return -1; - } - - - encoder_context = (struct video_encoder_context *) \ - calloc (sizeof (struct video_encoder_context),1); - if (encoder_context == NULL) - { - return -1; - } - encoder_context->outputBufferFile = NULL; - encoder_context->inputBufferFile = NULL; - encoder_context->video_driver_fd = -1; - encoder_context->inputBufferFile = file_ptr; - encoder_context->input_width = 176; - encoder_context->input_height = 144; - encoder_context->codectype = VEN_CODEC_MPEG4; - encoder_context->fps_num = 60; - encoder_context->fps_den = 2; - encoder_context->inputformat = VEN_INPUTFMT_NV12; - encoder_context->targetbitrate = 128000; - - file_ptr = fopen ("/data/output.m4v","wb"); - if (file_ptr == NULL) - { - DEBUG_PRINT("\n File can't be created"); - free (encoder_context); - return -1; - } - encoder_context->outputBufferFile = file_ptr; - - switch (atoi(argv[2])) - { - case 0: - DEBUG_PRINT("\n MPEG4 codec selected"); - encoder_context->codectype = VEN_CODEC_MPEG4; - Code_type = 0; - break; - case 1: - DEBUG_PRINT("\n H.263"); - encoder_context->codectype = VEN_CODEC_H263; - Code_type = 0; - break; - case 2: - DEBUG_PRINT("\n H.264"); - encoder_context->codectype = VEN_CODEC_H264; - Code_type = 1; - break; - default: - DEBUG_PRINT("\n Wrong codec type"); - error = -1; - break; - } - - if (error != -1) - { - temp1 = atoi(argv[3]); - temp2 = atoi(argv[4]); - - if (((temp1%16) != 0) || ((temp2%16) != 0)) - { - error = -1; - } - else - { - encoder_context->input_width = temp1; - encoder_context->input_height = temp2; - } - } - - switch (atoi(argv[5])) - { - case 0: - DEBUG_PRINT("\n No Sink"); - encoder_context->outputBufferFile = NULL; - break; - } - - if (error != -1) - { - encoder_context->targetbitrate = atoi (argv[6]); - } - - if ( error != -1 && (init_encoder (encoder_context) == -1 )) - { - DEBUG_PRINT("\n Init decoder fails "); - error = -1; - } - DEBUG_PRINT("\n Decoder open successfull"); - - - /*Allocate input and output buffers*/ - if (error != -1 && (allocate_buffer (0,encoder_context)== -1)) - { - DEBUG_PRINT("\n Error in input Buffer allocation"); - error = -1; - } - - if (error != -1 && (allocate_buffer (1,encoder_context)== -1)) - { - DEBUG_PRINT("\n Error in output Buffer allocation"); - error = -1; - } - - - if (error != -1 && (start_encoding (encoder_context) == -1)) - { - DEBUG_PRINT("\n Error in start decoding call"); - error = -1; - } - - if (error != -1 && (stop_encoding (encoder_context) == -1)) - { - DEBUG_PRINT("\n Error in stop decoding call"); - error = -1; - } - - DEBUG_PRINT("\n De-init the decoder"); - if ((deinit_encoder (encoder_context) == -1)) - { - error = -1; - } - - - (void)free_buffer (INPUT_BUFFER,encoder_context); - (void)free_buffer (OUTPUT_BUFFER,encoder_context); - - if (encoder_context->inputBufferFile != NULL) - { - fclose (encoder_context->inputBufferFile); - } - if (encoder_context->outputBufferFile != NULL) - { - fclose (encoder_context->outputBufferFile); - } - DEBUG_PRINT ("\n Total Number of frames decoded %d",total_frames); - DEBUG_PRINT("\n closing the driver"); - free (encoder_context); - - return error; -} - -int init_encoder ( struct video_encoder_context *init_decode ) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_basecfg basecfg; - struct video_queue_context *queue_ptr = NULL; - struct venc_ratectrlcfg ratecrl; - pthread_mutexattr_t init_values; - struct venc_profile profile; - struct ven_profilelevel profilelevel; - - DEBUG_PRINT("\n Before calling the open"); - - init_decode->video_driver_fd = open ("/dev/msm_vidc_enc", \ - O_RDWR | O_NONBLOCK); - - - - if (init_decode->video_driver_fd < 0) - { - DEBUG_PRINT("\n Open failed"); - return -1; - } - - basecfg.codectype = init_decode->codectype; - basecfg.dvs_height = 0; - basecfg.dvs_width = 0; - basecfg.fps_den = init_decode->fps_den; - basecfg.fps_num = init_decode->fps_num; - basecfg.input_height = init_decode->input_height; - basecfg.input_width = init_decode->input_width; - basecfg.inputformat = init_decode->inputformat; - basecfg.targetbitrate = init_decode->targetbitrate; - - /*Initialize Decoder with codec type and resolution*/ - ioctl_msg.in = &basecfg; - ioctl_msg.out = NULL; - - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_BASE_CFG, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set base config type failed"); - return -1; - } - - /*Initialize Decoder with codec type and resolution*/ - DEBUG_PRINT ("\n Switch off rate control"); - ioctl_msg.in = &ratecrl; - ioctl_msg.out = NULL; - ratecrl.rcmode = VEN_RC_OFF; - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_RATE_CTRL_CFG, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set rate control failed"); - return -1; - } - - if (basecfg.codectype == VEN_CODEC_H264) - { - DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); - ioctl_msg.in = &profile; - ioctl_msg.out = NULL; - profile.profile = VEN_PROFILE_H264_BASELINE; - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); - return -1; - } - - DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); - ioctl_msg.in = &profilelevel; - ioctl_msg.out = NULL; - profilelevel.level = VEN_LEVEL_H264_1p1; - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); - return -1; - } - - if (basecfg.input_width > 720) - { - DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); - ioctl_msg.in = &profile; - ioctl_msg.out = NULL; - profile.profile = VEN_PROFILE_H264_HIGH; - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_CODEC_PROFILE, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); - return -1; - } - - DEBUG_PRINT ("\n Set the VEN_IOCTL_SET_CODEC_PROFILE High"); - ioctl_msg.in = &profilelevel; - ioctl_msg.out = NULL; - profilelevel.level = VEN_LEVEL_H264_3p1; - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_PROFILE_LEVEL, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set VEN_IOCTL_SET_CODEC_PROFILE failed"); - return -1; - } - } - } - - DEBUG_PRINT("\n Query Input bufffer requirements"); - /*Get the Buffer requirements for input and output ports*/ - - - - ioctl_msg.in = NULL; - ioctl_msg.out = &init_decode->input_buffer; - - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_INPUT_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Requesting for input buffer requirements failed"); - return -1; - } - - DEBUG_PRINT("\n input Size=%d min count =%d actual count = %d", \ - (int)init_decode->input_buffer.datasize,\ - (int)init_decode->input_buffer.mincount,\ - (int)init_decode->input_buffer.actualcount); - - - ioctl_msg.in = &init_decode->input_buffer; - ioctl_msg.out = NULL; - init_decode->input_buffer.actualcount = init_decode->input_buffer.mincount + 2; - - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Set Buffer Requirements Failed"); - return -1; - } - - - DEBUG_PRINT("\n Query output bufffer requirements"); - ioctl_msg.in = NULL; - ioctl_msg.out = &init_decode->output_buffer; - - if (ioctl (init_decode->video_driver_fd,VEN_IOCTL_GET_OUTPUT_BUFFER_REQ, - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Requesting for output buffer requirements failed"); - return -1; - } - - DEBUG_PRINT("\n output Size=%d min count =%d actual count = %d", \ - (int)init_decode->output_buffer.datasize,\ - (int)init_decode->output_buffer.mincount,\ - (int)init_decode->output_buffer.actualcount); - - /*Create Queue related data structures*/ - queue_ptr = &init_decode->queue_context; - queue_ptr->commandq_size = 50; - queue_ptr->dataq_size = 50; - - sem_init(&queue_ptr->sem_message,0, 0); - sem_init(&init_decode->sem_synchronize,0, 0); - - pthread_mutexattr_init (&init_values); - pthread_mutex_init (&queue_ptr->mutex,&init_values); - pthread_mutex_init (&read_lock,&init_values); - DEBUG_PRINT("\n create Queues"); - queue_ptr->ptr_cmdq = (struct video_msgq*) \ - calloc (sizeof (struct video_msgq), - queue_ptr->commandq_size); - queue_ptr->ptr_dataq = (struct video_msgq*) \ - calloc (sizeof (struct video_msgq), - queue_ptr->dataq_size - ); - - if ( queue_ptr->ptr_cmdq == NULL || - queue_ptr->ptr_dataq == NULL - ) - { - return -1; - } - DEBUG_PRINT("\n create Threads"); - /*Create two threads*/ - if ( (pthread_create (&init_decode->videothread_id,NULL,video_thread, - init_decode) < 0) || - (pthread_create (&init_decode->asyncthread_id,NULL,async_thread, - init_decode) < 0) - ) - { - return -1; - } - - return 1; -} - - - -int free_buffer ( unsigned int buffer_dir, - struct video_encoder_context *encoder_context - ) -{ - unsigned int buffercount = 0,i=0; - struct venc_bufferpayload **ptemp = NULL; - - if (encoder_context == NULL) - { - return -1; - } - - if (buffer_dir == INPUT_BUFFER && encoder_context->ptr_inputbuffer) - { - buffercount = encoder_context->input_buffer.actualcount; - ptemp = encoder_context->ptr_inputbuffer; - - for (i=0;ifd != -1) - { - munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size); - ptemp [i]->pbuffer = NULL; - close (ptemp [i]->fd); - } - free (ptemp [i]); - ptemp [i] = NULL; - } - } - free (encoder_context->ptr_inputbuffer); - encoder_context->ptr_inputbuffer = NULL; - } - else if ( buffer_dir == OUTPUT_BUFFER && encoder_context->ptr_outputbuffer ) - { - buffercount = encoder_context->output_buffer.actualcount; - ptemp = encoder_context->ptr_outputbuffer; - - if (ptemp) - { - for (i=0;ifd != -1) - { - munmap ( ptemp [i]->pbuffer,ptemp [i]->maped_size); - ptemp [i]->pbuffer = NULL; - close (ptemp [i]->fd); - } - free (ptemp [i]); - ptemp [i] = NULL; - } - } - free (ptemp); - encoder_context->ptr_outputbuffer = NULL; - } - } - - return 1; -} - -int allocate_buffer ( unsigned int buffer_dir, - struct video_encoder_context *encoder_context - ) -{ - struct venc_bufferpayload **ptemp = NULL; - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - unsigned int buffercount = 0,i=0,alignedsize=0; - unsigned int buffersize = 0; - - if ( encoder_context == NULL) - { - DEBUG_PRINT ("\nallocate_buffer: context is NULL"); - return -1; - } - - if ( buffer_dir == INPUT_BUFFER ) - { - /*Check if buffers are allocated*/ - if (encoder_context->ptr_inputbuffer != NULL) - { - DEBUG_PRINT ("\nallocate_buffer: encoder_context->ptr_inputbuffer is set"); - return -1; - } - - buffercount = encoder_context->input_buffer.actualcount; - alignedsize = encoder_context->input_buffer.alignment; - buffersize = encoder_context->input_buffer.datasize; - buffersize = (buffersize + alignedsize) & (~alignedsize); - } - else if (buffer_dir == OUTPUT_BUFFER) - { - /*Check if buffers are allocated*/ - if (encoder_context->ptr_outputbuffer != NULL) - { - DEBUG_PRINT ("\nallocate_buffer: Double allcoate output"); - return -1; - } - - buffercount = encoder_context->output_buffer.actualcount; - alignedsize = encoder_context->output_buffer.alignment; - buffersize = encoder_context->output_buffer.datasize; - buffersize = (buffersize + alignedsize) & (~alignedsize); - - } - else - { - DEBUG_PRINT ("\nallocate_buffer: Wrong buffer directions"); - return -1; - } - - ptemp = (struct venc_bufferpayload **)\ - calloc (sizeof (struct venc_bufferpayload *),buffercount); - - if (ptemp == NULL) - { - DEBUG_PRINT ("\nallocate_buffer: venc_bufferpayload failure"); - return -1; - } - - - if (buffer_dir == OUTPUT_BUFFER) - { - DEBUG_PRINT ("\nallocate_buffer: OUT"); - encoder_context->ptr_outputbuffer = ptemp; - } - else - { - DEBUG_PRINT ("\nallocate_buffer: IN"); - encoder_context->ptr_inputbuffer = ptemp; - } - - /*Allocate buffer headers*/ - for (i=0; i< buffercount; i++) - { - ptemp [i] = (struct venc_bufferpayload*)\ - calloc (sizeof (struct venc_bufferpayload),1); - - if (ptemp [i] == NULL) - { - DEBUG_PRINT ("\nallocate_buffer: ptemp [i] calloc failure"); - return -1; - } - ptemp [i]->fd = -1; - } - - for (i=0; i< buffercount; i++) - { - ptemp [i]->fd = open ("/dev/pmem_adsp",O_RDWR); - - if (ptemp [i]->fd < 0) - { - DEBUG_PRINT ("\nallocate_buffer: open pmem_adsp failed"); - return -1; - } - - ptemp [i]->pbuffer = mmap(NULL,clp2(buffersize),PROT_READ|PROT_WRITE, - MAP_SHARED,ptemp [i]->fd,0); - DEBUG_PRINT ("\n pmem fd = %d virt addr = %p",ptemp [i]->fd,\ - ptemp [i]->pbuffer); - if (ptemp [i]->pbuffer == MAP_FAILED) - { - ptemp [i]->pbuffer = NULL; - DEBUG_PRINT ("\nallocate_buffer: MMAP failed"); - return -1; - } - ptemp [i]->sz = buffersize; - ptemp [i]->maped_size = clp2 (buffersize); - - ioctl_msg.in = ptemp [i]; - ioctl_msg.out = NULL; - - if (buffer_dir == OUTPUT_BUFFER) - { - if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_OUTPUT_BUFFER, - &ioctl_msg) < 0) - { - DEBUG_PRINT ("\nallocate_buffer: Set Output Buffer IOCTL failed"); - return -1; - } - } - else - { - if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_SET_INPUT_BUFFER, - &ioctl_msg) < 0) - { - DEBUG_PRINT ("\nallocate_buffer: Set input Buffer IOCTL failed"); - return -1; - } - } - - } - DEBUG_PRINT ("\nallocate_buffer: Success"); - return 1; -} - - - -int start_encoding (struct video_encoder_context *encoder_context) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_buffer enc_buffer; - unsigned int i = 0; - unsigned int data_len =0; - - - if (encoder_context == NULL) - { - return -1; - } - - if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_START, - NULL) < 0) - { - DEBUG_PRINT("\n Start failed"); - return -1; - } - - DEBUG_PRINT("\n Start Issued successfully waiting for Start Done"); - /*Wait for Start command response*/ - sem_wait (&encoder_context->sem_synchronize); - - /*Push output Buffers*/ - i = 0; - while (i < encoder_context->output_buffer.actualcount) - { - enc_buffer.clientdata = (void *)encoder_context->ptr_outputbuffer [i]; - enc_buffer.flags = 0; - enc_buffer.sz = encoder_context->ptr_outputbuffer [i]->sz; - enc_buffer.len = 0; - enc_buffer.ptrbuffer = encoder_context->ptr_outputbuffer [i]->pbuffer; - enc_buffer.offset = 0; - enc_buffer.timestamp = 0; - - DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata); - ioctl_msg.in = &enc_buffer; - ioctl_msg.out = NULL; - - if (ioctl (encoder_context->video_driver_fd, - VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT("\n fill output frame failed"); - return -1; - } - i++; - } - - - /*push input buffers*/ - i = 0; - while (i < encoder_context->input_buffer.actualcount) - { - DEBUG_PRINT("\n Read Frame from File"); - - enc_buffer.clientdata = (void *)encoder_context->ptr_inputbuffer [i]; - enc_buffer.flags = 0; - enc_buffer.sz = encoder_context->ptr_inputbuffer [i]->sz; - enc_buffer.len = 0; - enc_buffer.ptrbuffer = encoder_context->ptr_inputbuffer [i]->pbuffer; - enc_buffer.offset = 0; - enc_buffer.timestamp = total_frames * - ((encoder_context->fps_den * 1000000)/encoder_context->fps_num); - enc_buffer.len = (encoder_context->input_height * - encoder_context->input_width *3)/2; - data_len = read_frame ( enc_buffer.ptrbuffer, - enc_buffer.len, - encoder_context->inputBufferFile); - if (data_len == 0) - { - DEBUG_PRINT("\n Length is zero error"); - return -1; - } - enc_buffer.len = data_len; - DEBUG_PRINT("\n Read Frame from File szie = %d",(int)data_len); - - DEBUG_PRINT ("\n Client Data on output = %p",(void *)enc_buffer.clientdata); - ioctl_msg.in = &enc_buffer; - ioctl_msg.out = NULL; - - if (ioctl (encoder_context->video_driver_fd, - VEN_IOCTL_CMD_ENCODE_FRAME,&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Encode input frame failed"); - return -1; - } - total_frames++; - i++; - } - DEBUG_PRINT ("\n Wait for EOS"); - /*Wait for EOS or Error condition*/ - sem_wait (&encoder_context->sem_synchronize); - DEBUG_PRINT ("\n Reached EOS"); - - return 1; -} - -int stop_encoding (struct video_encoder_context *encoder_context) -{ - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_bufferflush buffer_flush; - - if (encoder_context == NULL) - { - return -1; - } - buffer_flush.flush_mode = VEN_FLUSH_INPUT; - ioctl_msg.in = &buffer_flush; - ioctl_msg.out = NULL; - - if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH, - &ioctl_msg) < 0) - { - DEBUG_PRINT("\n Flush input failed"); - } - else - { - sem_wait (&encoder_context->sem_synchronize); - } - - buffer_flush.flush_mode = VEN_FLUSH_OUTPUT; - ioctl_msg.in = &buffer_flush; - ioctl_msg.out = NULL; - - if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_FLUSH, - &ioctl_msg) < 0) - { - DEBUG_PRINT("\n Flush output failed"); - } - else - { - sem_wait (&encoder_context->sem_synchronize); - } - - DEBUG_PRINT("\n Stop VEN_IOCTL_CMD_STOP"); - if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_STOP,NULL) < 0) - { - DEBUG_PRINT("\n Stop failed"); - } - else - { - sem_wait (&encoder_context->sem_synchronize); - } - return 1; -} - -int deinit_encoder (struct video_encoder_context *init_decode) -{ - if (init_decode == NULL) - { - return -1; - } - - /*Close the driver*/ - if (init_decode->video_driver_fd != -1) - { - close (init_decode->video_driver_fd); - } - - if (init_decode->queue_context.ptr_cmdq) - { - free (init_decode->queue_context.ptr_cmdq); - init_decode->queue_context.ptr_cmdq = NULL; - } - - if (init_decode->queue_context.ptr_dataq) - { - free (init_decode->queue_context.ptr_dataq); - init_decode->queue_context.ptr_dataq = NULL; - } - - sem_destroy (&init_decode->queue_context.sem_message); - sem_destroy (&init_decode->sem_synchronize); - - pthread_mutex_destroy(&init_decode->queue_context.mutex); - pthread_mutex_destroy (&read_lock); - - return 1; -} - -static void* video_thread (void *context) -{ - struct video_encoder_context *encoder_context = NULL; - struct video_msgq *queueitem = NULL; - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - struct venc_bufferpayload *tempbuffer = NULL; - struct venc_buffer enc_buffer; - unsigned int data_len =0; - - - if (context == NULL) - { - DEBUG_PRINT("\n video thread recieved NULL context"); - return NULL; - } - encoder_context = (struct video_encoder_context *) context; - - /* Thread function which will accept commands from async thread - * or main thread - */ - while (1) - { - queueitem = queue_get_cmd (&encoder_context ->queue_context); - if (queueitem != NULL) - { - switch (queueitem->cmd) - { - case VEN_MSG_START: - DEBUG_PRINT("\n recived start done command"); - sem_post (&encoder_context->sem_synchronize); - break; - - case VEN_MSG_STOP: - DEBUG_PRINT("\n recieved stop done"); - sem_post (&encoder_context->sem_synchronize); - break; - - case VEN_MSG_INPUT_BUFFER_DONE: - - tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata; - if (tempbuffer == NULL) - { - DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); - sem_post (&encoder_context->sem_synchronize); - break; - } - tempbuffer->filled_len = (encoder_context->input_height * - encoder_context->input_width *3)/2; - - data_len = read_frame ( tempbuffer->pbuffer, - tempbuffer->filled_len, - encoder_context->inputBufferFile); - - if (data_len == 0) - { - DEBUG_PRINT ("\n End of stream reached"); - sem_post (&encoder_context->sem_synchronize); - break; - } - enc_buffer.clientdata = (void *)tempbuffer; - enc_buffer.flags = 0; - enc_buffer.ptrbuffer = tempbuffer->pbuffer; - enc_buffer.sz = tempbuffer->sz; - enc_buffer.len = tempbuffer->filled_len; - enc_buffer.offset = 0; - enc_buffer.timestamp = total_frames * - ((encoder_context->fps_den * 1000000)/encoder_context->fps_num); - - /*TODO: Time stamp needs to be updated*/ - ioctl_msg.in = &enc_buffer; - ioctl_msg.out = NULL; - total_frames++; - if (ioctl(encoder_context->video_driver_fd,VEN_IOCTL_CMD_ENCODE_FRAME, - &ioctl_msg) < 0) - { - DEBUG_PRINT("\n Decoder frame failed"); - sem_post (&encoder_context->sem_synchronize); - } - DEBUG_PRINT("\n Input buffer done send next buffer current value = %d",\ - total_frames); - break; - - case VEN_MSG_OUTPUT_BUFFER_DONE: - - tempbuffer = (struct venc_bufferpayload *)queueitem->clientdata; - if (tempbuffer == NULL) - { - DEBUG_PRINT("\n FATAL ERROR input buffer address is bad"); - sem_post (&encoder_context->sem_synchronize); - break; - } - - if (encoder_context->outputBufferFile != NULL) - { - fwrite (tempbuffer->pbuffer,1,tempbuffer->filled_len, - encoder_context->outputBufferFile); - } - - - DEBUG_PRINT("\n recieved output buffer consume outbuffer"); - DEBUG_PRINT("\nValues outputbuffer->bufferaddr = %p",\ - tempbuffer->pbuffer); - enc_buffer.clientdata = (void *)tempbuffer; - enc_buffer.flags = 0; - enc_buffer.sz = tempbuffer->sz; - enc_buffer.len = 0; - enc_buffer.ptrbuffer = tempbuffer->pbuffer; - enc_buffer.offset = 0; - enc_buffer.timestamp = 0; - - ioctl_msg.in = &enc_buffer; - ioctl_msg.out = NULL; - - if (ioctl (encoder_context->video_driver_fd, - VEN_IOCTL_CMD_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Decoder frame failed"); - return NULL; - } - - break; - - case VEN_MSG_FLUSH_INPUT_DONE: - DEBUG_PRINT("\n Flush input complete"); - sem_post (&encoder_context->sem_synchronize); - break; - - case VEN_MSG_FLUSH_OUPUT_DONE: - DEBUG_PRINT("\n Flush output complete"); - sem_post (&encoder_context->sem_synchronize); - break; - } - - if (queueitem->cmd == VEN_MSG_STOP) - { - DEBUG_PRINT("\n Playback has ended thread will exit"); - return NULL; - } - } - else - { - DEBUG_PRINT("\n Error condition recieved NULL from Queue"); - } - - } -} - -static void* async_thread (void *context) -{ - struct video_encoder_context *encoder_context = NULL; - struct video_msgq queueitem ; - struct venc_msg venc_msg; - struct venc_bufferpayload *tempbuffer = NULL; - struct venc_ioctl_msg ioctl_msg = {NULL,NULL}; - int result = -1; - - if (context == NULL) - { - DEBUG_PRINT("\n aynsc thread recieved NULL context"); - return NULL; - } - encoder_context = (struct video_encoder_context *) context; - DEBUG_PRINT("\n Entering the async thread"); - - while (1) - { - ioctl_msg.in = NULL; - ioctl_msg.out = (void*)&venc_msg; - DEBUG_PRINT ("\n Sizeof venc_msginfo = %d ",sizeof (venc_msg)); - DEBUG_PRINT("\n Address of Venc msg in async thread %p",\ - ioctl_msg.out); - if (ioctl (encoder_context->video_driver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,\ - (void*)&ioctl_msg) < 0) - { - DEBUG_PRINT("\n Error in ioctl read next msg"); - } - else - { - switch (venc_msg.msgcode) - { - case VEN_MSG_START: - case VEN_MSG_STOP: - case VEN_MSG_INDICATION: - DEBUG_PRINT("\nSTOP/START Indiacation"); - queueitem.cmd = venc_msg.msgcode; - queueitem.status = venc_msg.statuscode; - queueitem.clientdata = NULL; - break; - - case VEN_MSG_INPUT_BUFFER_DONE: - DEBUG_PRINT("\nINPUT buffer done Indiacation"); - queueitem.cmd = venc_msg.msgcode; - queueitem.status = venc_msg.statuscode; - queueitem.clientdata = (void *)venc_msg.buf.clientdata; - DEBUG_PRINT("\nInput Client data pointer is %p",queueitem.clientdata); - tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata; - DEBUG_PRINT ("\n Input Address of tempbuffer %p",tempbuffer); - tempbuffer->filled_len = venc_msg.buf.len; - DEBUG_PRINT ("\n Input value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len); - break; - case VEN_MSG_OUTPUT_BUFFER_DONE: - DEBUG_PRINT("\nOUPUT buffer done Indiacation"); - queueitem.cmd = venc_msg.msgcode; - queueitem.status = venc_msg.statuscode; - queueitem.clientdata = (void *)venc_msg.buf.clientdata; - DEBUG_PRINT("\nOutput Client data pointer is %p",queueitem.clientdata); - tempbuffer = (struct venc_bufferpayload *) queueitem.clientdata; - DEBUG_PRINT ("\n Output Address of tempbuffer %p",tempbuffer); - tempbuffer->filled_len = venc_msg.buf.len; - DEBUG_PRINT ("\n Output value of tempbuffer tempbuffer->filled_len %d",(int)tempbuffer->filled_len); - break; - - default: - DEBUG_PRINT("\nIn Default of get next message %d",(int)venc_msg.msgcode); - queueitem.cmd = venc_msg.msgcode; - queueitem.status = venc_msg.statuscode; - queueitem.clientdata = NULL; - break; - } - result = queue_post_cmdq (&encoder_context->queue_context,&queueitem); - while (result == 0) - { - result = queue_post_cmdq (&encoder_context->queue_context,&queueitem); - } - - if (result == -1) - { - DEBUG_PRINT("\n FATAL ERROR WITH Queue"); - } - } - if (venc_msg.msgcode == VEN_MSG_STOP) - { - /*Thread can exit at this point*/ - return NULL; - } - } -} - - -static unsigned int read_frame (unsigned char *dataptr, unsigned int length, - FILE * inputBufferFile) -{ - - unsigned int readOffset = 0; - int bytes_read = 0; - unsigned int code = 0; - int found = 0; - - DEBUG_PRINT ("\n Inside the readframe"); - - if (dataptr == NULL && length == 0) - { - DEBUG_PRINT ("\n dataptr = %p length = %d",dataptr,(int)length); - return 0; - } - - pthread_mutex_lock(&read_lock); - bytes_read = fread(&dataptr[readOffset],1,length,inputBufferFile); - pthread_mutex_unlock(&read_lock); - - return bytes_read; -} -- cgit v1.2.3