summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.mk15
-rw-r--r--msm8974/mm-core/inc/OMX_IndexExt.h2
-rw-r--r--msm8974/mm-core/inc/OMX_VideoExt.h89
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h4
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h2
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h15
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp21
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp32
-rw-r--r--msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp152
-rw-r--r--msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp13
-rw-r--r--msmcobalt/Android.mk16
-rw-r--r--msmcobalt/NOTICE85
-rw-r--r--msmcobalt/conf_files/config.mk5
-rw-r--r--msmcobalt/conf_files/msm8937/media_codecs_8937.xml236
-rw-r--r--msmcobalt/conf_files/msm8937/media_codecs_performance_8937.xml113
-rw-r--r--msmcobalt/conf_files/msm8937/media_profiles_8937.xml698
-rw-r--r--msmcobalt/libc2dcolorconvert/Android.mk25
-rw-r--r--msmcobalt/libc2dcolorconvert/C2DColorConverter.cpp780
-rw-r--r--msmcobalt/libc2dcolorconvert/C2DColorConverter.h121
-rw-r--r--msmcobalt/libstagefrighthw/Android.mk56
-rw-r--r--msmcobalt/libstagefrighthw/MODULE_LICENSE_APACHE20
-rw-r--r--msmcobalt/libstagefrighthw/NOTICE189
-rw-r--r--msmcobalt/libstagefrighthw/QComOMXMetadata.h48
-rw-r--r--msmcobalt/libstagefrighthw/QComOMXPlugin.cpp155
-rw-r--r--msmcobalt/libstagefrighthw/QComOMXPlugin.h76
-rw-r--r--msmcobalt/mm-core/Android.mk137
-rw-r--r--msmcobalt/mm-core/inc/OMX_Audio.h1321
-rw-r--r--msmcobalt/mm-core/inc/OMX_Component.h579
-rw-r--r--msmcobalt/mm-core/inc/OMX_ContentPipe.h195
-rw-r--r--msmcobalt/mm-core/inc/OMX_Core.h1440
-rw-r--r--msmcobalt/mm-core/inc/OMX_CoreExt.h66
-rw-r--r--msmcobalt/mm-core/inc/OMX_IVCommon.h933
-rw-r--r--msmcobalt/mm-core/inc/OMX_Image.h328
-rw-r--r--msmcobalt/mm-core/inc/OMX_Index.h260
-rw-r--r--msmcobalt/mm-core/inc/OMX_IndexExt.h99
-rw-r--r--msmcobalt/mm-core/inc/OMX_Other.h337
-rw-r--r--msmcobalt/mm-core/inc/OMX_QCOMExtns.h2023
-rw-r--r--msmcobalt/mm-core/inc/OMX_Skype_VideoExtensions.h155
-rw-r--r--msmcobalt/mm-core/inc/OMX_Types.h359
-rw-r--r--msmcobalt/mm-core/inc/OMX_Video.h1082
-rw-r--r--msmcobalt/mm-core/inc/OMX_VideoExt.h271
-rw-r--r--msmcobalt/mm-core/inc/QCMediaDefs.h74
-rw-r--r--msmcobalt/mm-core/inc/QCMetaData.h106
-rw-r--r--msmcobalt/mm-core/inc/QOMX_AudioExtensions.h617
-rw-r--r--msmcobalt/mm-core/inc/QOMX_AudioIndexExtensions.h85
-rw-r--r--msmcobalt/mm-core/inc/QOMX_CoreExtensions.h164
-rw-r--r--msmcobalt/mm-core/inc/QOMX_FileFormatExtensions.h155
-rw-r--r--msmcobalt/mm-core/inc/QOMX_IVCommonExtensions.h486
-rw-r--r--msmcobalt/mm-core/inc/QOMX_SourceExtensions.h157
-rw-r--r--msmcobalt/mm-core/inc/QOMX_StreamingExtensions.h486
-rw-r--r--msmcobalt/mm-core/inc/QOMX_VideoExtensions.h582
-rw-r--r--msmcobalt/mm-core/inc/drmplay_version.h34
-rw-r--r--msmcobalt/mm-core/inc/qc_omx_common.h65
-rw-r--r--msmcobalt/mm-core/inc/qc_omx_component.h183
-rw-r--r--msmcobalt/mm-core/inc/qc_omx_msg.h86
-rwxr-xr-xmsmcobalt/mm-core/src/7627A/qc_registry_table.c812
-rwxr-xr-xmsmcobalt/mm-core/src/7627A/qc_registry_table_android.c711
-rw-r--r--msmcobalt/mm-core/src/7630/qc_registry_table.c746
-rw-r--r--msmcobalt/mm-core/src/7630/qc_registry_table_android.c552
-rw-r--r--msmcobalt/mm-core/src/8084/qc_registry_table.c463
-rw-r--r--msmcobalt/mm-core/src/8084/qc_registry_table_android.c574
-rw-r--r--msmcobalt/mm-core/src/8092/qc_registry_table.c479
-rw-r--r--msmcobalt/mm-core/src/8092/qc_registry_table_android.c574
-rw-r--r--msmcobalt/mm-core/src/8226/qc_registry_table.c411
-rw-r--r--msmcobalt/mm-core/src/8226/qc_registry_table_android.c476
-rw-r--r--msmcobalt/mm-core/src/8610/qc_registry_table.c425
-rw-r--r--msmcobalt/mm-core/src/8610/qc_registry_table_android.c437
-rwxr-xr-xmsmcobalt/mm-core/src/8660/qc_registry_table.c671
-rwxr-xr-xmsmcobalt/mm-core/src/8660/qc_registry_table_android.c468
-rw-r--r--msmcobalt/mm-core/src/8909/registry_table.c255
-rw-r--r--msmcobalt/mm-core/src/8909/registry_table_android.c320
-rw-r--r--msmcobalt/mm-core/src/8916/registry_table.c411
-rw-r--r--msmcobalt/mm-core/src/8916/registry_table_android.c489
-rwxr-xr-xmsmcobalt/mm-core/src/8937/registry_table.c466
-rwxr-xr-xmsmcobalt/mm-core/src/8937/registry_table_android.c514
-rw-r--r--msmcobalt/mm-core/src/8952/registry_table.c544
-rw-r--r--msmcobalt/mm-core/src/8952/registry_table_android.c609
-rwxr-xr-xmsmcobalt/mm-core/src/8960/qc_registry_table.c272
-rw-r--r--msmcobalt/mm-core/src/8960/qc_registry_table_android.c479
-rw-r--r--msmcobalt/mm-core/src/8974/qc_registry_table.c425
-rw-r--r--msmcobalt/mm-core/src/8974/qc_registry_table_android.c501
-rwxr-xr-xmsmcobalt/mm-core/src/common/omx_core_cmp.cpp407
-rwxr-xr-xmsmcobalt/mm-core/src/common/omx_core_cmp.h160
-rw-r--r--msmcobalt/mm-core/src/common/qc_omx_core.c932
-rw-r--r--msmcobalt/mm-core/src/common/qc_omx_core.h72
-rw-r--r--msmcobalt/mm-core/src/default/qc_registry_table.c62
-rw-r--r--msmcobalt/mm-core/src/default/qc_registry_table_android.c59
-rwxr-xr-xmsmcobalt/mm-core/src/msm8953/registry_table.c679
-rwxr-xr-xmsmcobalt/mm-core/src/msm8953/registry_table_android.c770
-rw-r--r--msmcobalt/mm-core/src/msm8992/registry_table.c479
-rw-r--r--msmcobalt/mm-core/src/msm8992/registry_table_android.c574
-rw-r--r--msmcobalt/mm-core/src/msm8994/registry_table.c463
-rw-r--r--msmcobalt/mm-core/src/msm8994/registry_table_android.c638
-rw-r--r--msmcobalt/mm-core/src/msm8996/registry_table.c573
-rw-r--r--msmcobalt/mm-core/src/msm8996/registry_table_android.c797
-rw-r--r--msmcobalt/mm-core/src/msmcobalt/registry_table.c559
-rw-r--r--msmcobalt/mm-core/src/msmcobalt/registry_table_android.c813
-rw-r--r--msmcobalt/mm-video-v4l2/Android.mk2
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/Android.mk2
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/common/Android.mk51
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/common/inc/extra_data_handler.h84
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_color_converter.h55
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_debug.h113
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp551
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp189
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/Android.mk161
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/Map.h244
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h69
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/frameparser.h103
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h480
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/hevc_utils.h146
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/message_queue.h76
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/mp4_utils.h169
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec.h459
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec_utils.h145
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h1280
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h934
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h1104
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/power_module.h42
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/qtypes.h90
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/queue.h39
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/inc/ts_parser.h106
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/frameparser.cpp638
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp1587
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp221
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/message_queue.c163
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp340
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp6418
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec_utils.cpp353
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp8435
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp10961
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp12700
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp325
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/Android.mk156
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/camera_test.h58
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/fb_test.h48
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_hevc.h113
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h165
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_base.h712
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_common.h112
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h123
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/queue.h78
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/venc_util.h53
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h177
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h663
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_test.h75
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_hevc.cpp1554
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp2982
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp5402
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp2698
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp3149
-rw-r--r--msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp8199
-rw-r--r--msmcobalt/videopp/Android.mk74
-rw-r--r--msmcobalt/videopp/inc/omx_vdpp.h949
-rw-r--r--msmcobalt/videopp/src/omx_vdpp.cpp7595
155 files changed, 120895 insertions, 9 deletions
diff --git a/Android.mk b/Android.mk
index 80a91fc..7b951b0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,14 +1,15 @@
# TODO: Find a better way to separate build configs for ADP vs non-ADP devices
ifneq ($(TARGET_BOARD_AUTO),true)
- # for msm8996 targets, use the msm8996 directory, for all other targets
- # use the msm8974 directory.
+
+ QCOM_MEDIA_ROOT := $(call my-dir)/msm8974
ifneq ($(filter msm8996, $(TARGET_BOARD_PLATFORM)),)
QCOM_MEDIA_ROOT := $(call my-dir)/msm8996
- else
- QCOM_MEDIA_ROOT := $(call my-dir)/msm8974
+ endif
+ ifneq ($(filter msmcobalt, $(TARGET_BOARD_PLATFORM)),)
+ QCOM_MEDIA_ROOT := $(call my-dir)/msmcobalt
endif
- ifneq ($(filter msm8610 msm8226 msm8960 msm8660 msm7627a msm7630_surf msm8084 msm8952 msm8992 msm8994 msm8996,$(TARGET_BOARD_PLATFORM)),)
+ ifneq ($(filter msm8610 msm8226 msm8960 msm8660 msm7627a msm7630_surf msm8084 msm8952 msm8992 msm8994 msm8996 msmcobalt,$(TARGET_BOARD_PLATFORM)),)
include $(QCOM_MEDIA_ROOT)/mm-core/Android.mk
include $(QCOM_MEDIA_ROOT)/libstagefrighthw/Android.mk
endif
@@ -17,11 +18,11 @@ ifneq ($(TARGET_BOARD_AUTO),true)
include $(QCOM_MEDIA_ROOT)/mm-video-legacy/Android.mk
endif
- ifneq ($(filter msm8610 msm8226 msm8084 msm8952 msm8992 msm8994 msm8996,$(TARGET_BOARD_PLATFORM)),)
+ ifneq ($(filter msm8610 msm8226 msm8084 msm8952 msm8992 msm8994 msm8996 msmcobalt,$(TARGET_BOARD_PLATFORM)),)
include $(QCOM_MEDIA_ROOT)/mm-video-v4l2/Android.mk
endif
- ifneq ($(filter msm8610 msm8226 msm8960 msm8084 msm8952 msm8992 msm8994 msm8996,$(TARGET_BOARD_PLATFORM)),)
+ ifneq ($(filter msm8610 msm8226 msm8960 msm8084 msm8952 msm8992 msm8994 msm8996 msmcobalt,$(TARGET_BOARD_PLATFORM)),)
include $(QCOM_MEDIA_ROOT)/libc2dcolorconvert/Android.mk
endif
endif
diff --git a/msm8974/mm-core/inc/OMX_IndexExt.h b/msm8974/mm-core/inc/OMX_IndexExt.h
index 3f278ba..c584c08 100644
--- a/msm8974/mm-core/inc/OMX_IndexExt.h
+++ b/msm8974/mm-core/inc/OMX_IndexExt.h
@@ -73,6 +73,8 @@ typedef enum OMX_INDEXEXTTYPE {
OMX_IndexParamVideoHevc, /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */
OMX_IndexParamSliceSegments, /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */
OMX_IndexConfigAndroidIntraRefresh, /**< reference: OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE */
+ OMX_IndexParamAndroidVideoTemporalLayering, /**< reference: OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE */
+ OMX_IndexConfigAndroidVideoTemporalLayering, /**< reference: OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE */
/* Image & Video common configurations */
OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,
diff --git a/msm8974/mm-core/inc/OMX_VideoExt.h b/msm8974/mm-core/inc/OMX_VideoExt.h
index 30fe514..9ea4828 100644
--- a/msm8974/mm-core/inc/OMX_VideoExt.h
+++ b/msm8974/mm-core/inc/OMX_VideoExt.h
@@ -174,6 +174,95 @@ typedef struct OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE {
OMX_U32 nRefreshPeriod;
} OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE;
+/** Maximum number of temporal layers supported by AVC/HEVC */
+#define OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS 8
+
+/** temporal layer patterns */
+typedef enum OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE {
+ OMX_VIDEO_AndroidTemporalLayeringPatternNone = 0,
+ // pattern as defined by WebRTC
+ OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC = 1 << 0,
+ // pattern where frames in any layer other than the base layer only depend on at most the very
+ // last frame from each preceding layer (other than the base layer.)
+ OMX_VIDEO_AndroidTemporalLayeringPatternAndroid = 1 << 1,
+} OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE;
+
+/**
+ * Android specific param for configuration of temporal layering.
+ * Android only supports temporal layering where successive layers each double the
+ * previous layer's framerate.
+ * NOTE: Reading this parameter at run-time SHALL return actual run-time values.
+ *
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to (output port for encoders)
+ * eSupportedPatterns : A bitmask of supported layering patterns
+ * nLayerCountMax : Max number of temporal coding layers supported
+ * by the encoder (must be at least 1, 1 meaning temporal layering
+ * is NOT supported)
+ * nBLayerCountMax : Max number of layers that can contain B frames
+ * (0) to (nLayerCountMax - 1)
+ * ePattern : Layering pattern.
+ * nPLayerCountActual : Number of temporal layers to be coded with non-B frames,
+ * starting from and including the base-layer.
+ * (1 to nLayerCountMax - nBLayerCountActual)
+ * If nPLayerCountActual is 1 and nBLayerCountActual is 0, temporal
+ * layering is disabled. Otherwise, it is enabled.
+ * nBLayerCountActual : Number of temporal layers to be coded with B frames,
+ * starting after non-B layers.
+ * (0 to nBLayerCountMax)
+ * bBitrateRatiosSpecified : Flag to indicate if layer-wise bitrate
+ * distribution is specified.
+ * nBitrateRatios : Bitrate ratio (100 based) per layer (index 0 is base layer).
+ * Honored if bBitrateRatiosSpecified is set.
+ * i.e for 4 layers with desired distribution (25% 25% 25% 25%),
+ * nBitrateRatio = {25, 50, 75, 100, ... }
+ * Values in indices not less than 'the actual number of layers
+ * minus 1' MAY be ignored and assumed to be 100.
+*/
+typedef struct OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE eSupportedPatterns;
+ OMX_U32 nLayerCountMax;
+ OMX_U32 nBLayerCountMax;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+ OMX_U32 nPLayerCountActual;
+ OMX_U32 nBLayerCountActual;
+ OMX_BOOL bBitrateRatiosSpecified;
+ OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE;
+
+/**
+ * Android specific config for changing the temporal-layer count or
+ * bitrate-distribution at run-time.
+ *
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to (output port for encoders)
+ * ePattern : Layering pattern.
+ * nPLayerCountActual : Number of temporal layers to be coded with non-B frames.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ * nBLayerCountActual : Number of temporal layers to be coded with B frames.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ * bBitrateRatiosSpecified : Flag to indicate if layer-wise bitrate
+ * distribution is specified.
+ * nBitrateRatios : Bitrate ratio (100 based, Q16 values) per layer (0 is base layer).
+ * Honored if bBitrateRatiosSpecified is set.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ */
+typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+ OMX_U32 nPLayerCountActual;
+ OMX_U32 nBLayerCountActual;
+ OMX_BOOL bBitrateRatiosSpecified;
+ OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE;
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
index 5916582..e75bfcb 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -240,6 +240,8 @@ class omx_video: public qc_omx_component
virtual bool dev_get_performance_level(OMX_U32 *) = 0;
virtual bool dev_get_vui_timing_info(OMX_U32 *) = 0;
virtual bool dev_get_peak_bitrate(OMX_U32 *) = 0;
+ virtual bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/) = 0;
#ifdef _ANDROID_ICS_
void omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer);
#endif
@@ -616,6 +618,8 @@ class omx_video: public qc_omx_component
OMX_VIDEO_VP8REFERENCEFRAMETYPE m_sConfigVp8ReferenceFrame;
QOMX_VIDEO_HIERARCHICALLAYERS m_sHierLayers;
QOMX_EXTNINDEX_VIDEO_INITIALQP m_sParamInitqp;
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE m_sParamTemporalLayers;
+ OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE m_sConfigTemporalLayers;
OMX_U32 m_sExtraData;
OMX_U32 m_input_msg_id;
OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE m_sConfigIntraRefresh;
diff --git a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
index d7b21db..73a5d33 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
+++ b/msm8974/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
@@ -87,6 +87,8 @@ class omx_venc: public omx_video
bool dev_get_performance_level(OMX_U32 *);
bool dev_get_vui_timing_info(OMX_U32 *);
bool dev_get_peak_bitrate(OMX_U32 *);
+ bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/);
bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height);
bool dev_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
OMX_U32 height);
diff --git a/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
index e2bdaf7..94d68ee 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
+++ b/msm8974/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -219,6 +219,16 @@ struct msm_venc_priority {
OMX_U32 priority;
};
+struct msm_venc_temporal_layers {
+ enum hier_type hier_mode;
+ OMX_U32 nMaxLayers;
+ OMX_U32 nMaxBLayers;
+ OMX_U32 nPLayers;
+ OMX_U32 nBLayers;
+ OMX_BOOL bIsBitrateRatioValid;
+ OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+};
+
enum v4l2_ports {
CAPTURE_PORT,
OUTPUT_PORT,
@@ -288,6 +298,8 @@ class venc_dev
bool venc_get_performance_level(OMX_U32 *perflevel);
bool venc_get_vui_timing_info(OMX_U32 *enabled);
bool venc_get_peak_bitrate(OMX_U32 *peakbitrate);
+ bool venc_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/);
bool venc_get_output_log_flag();
int venc_output_log_buffers(const char *buffer_addr, int buffer_len);
int venc_input_log_buffers(OMX_BUFFERHEADERTYPE *buffer, int fd, int plane_offset);
@@ -358,6 +370,7 @@ class venc_dev
struct msm_venc_vpx_error_resilience vpx_err_resilience;
struct msm_venc_priority sess_priority;
OMX_U32 operating_rate;
+ msm_venc_temporal_layers temporal_layers_config;
bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel);
bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames);
@@ -400,6 +413,8 @@ class venc_dev
bool venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode);
bool venc_set_session_priority(OMX_U32 priority);
bool venc_set_operatingrate(OMX_U32 rate);
+ OMX_ERRORTYPE venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams);
+ OMX_ERRORTYPE venc_set_temporal_layers_internal();
#ifdef MAX_RES_1080P
OMX_U32 pmem_free();
diff --git a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
index 24a0c53..90e2425 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -1910,6 +1910,19 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
memcpy(initqp, &m_sParamInitqp, sizeof(m_sParamInitqp));
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pLayerInfo =
+ reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*>(paramData);
+ if (!dev_get_temporal_layer_caps(&m_sParamTemporalLayers.nLayerCountMax,
+ &m_sParamTemporalLayers.nBLayerCountMax)) {
+ DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities");
+ eRet = OMX_ErrorHardware;
+ }
+ memcpy(pLayerInfo, &m_sParamTemporalLayers, sizeof(m_sParamTemporalLayers));
+ break;
+ }
case OMX_IndexParamVideoSliceFMO:
default:
{
@@ -2042,6 +2055,14 @@ OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp,
memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh));
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
+ OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *layerConfig =
+ (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)configData;
+ memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers));
+ break;
+ }
default:
DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
return OMX_ErrorUnsupportedIndex;
diff --git a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
index 162503b..047273a 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/msm8974/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -470,6 +470,13 @@ OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role)
m_sHierLayers.nNumLayers = 0;
m_sHierLayers.eHierarchicalCodingType = QOMX_HIERARCHICALCODING_P;
+ memset(&m_sParamTemporalLayers, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+ OMX_INIT_STRUCT(&m_sParamTemporalLayers, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ m_sParamTemporalLayers.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+
+ memset(&m_sConfigTemporalLayers, 0x0, sizeof(OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE));
+ OMX_INIT_STRUCT(&m_sConfigTemporalLayers, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
+
m_state = OMX_StateLoaded;
m_sExtraData = 0;
@@ -1490,6 +1497,26 @@ OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
}
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering)) {
+ DEBUG_PRINT_ERROR("Failed to configure temporal layers");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ // save the actual configuration applied
+ memcpy(&m_sParamTemporalLayers, paramData, sizeof(m_sParamTemporalLayers));
+ // keep the config data in sync
+ m_sConfigTemporalLayers.ePattern = m_sParamTemporalLayers.ePattern;
+ m_sConfigTemporalLayers.nBLayerCountActual = m_sParamTemporalLayers.nBLayerCountActual;
+ m_sConfigTemporalLayers.nPLayerCountActual = m_sParamTemporalLayers.nPLayerCountActual;
+ m_sConfigTemporalLayers.bBitrateRatiosSpecified = m_sParamTemporalLayers.bBitrateRatiosSpecified;
+ memcpy(&m_sConfigTemporalLayers.nBitrateRatios[0],
+ &m_sParamTemporalLayers.nBitrateRatios[0],
+ OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS * sizeof(OMX_U32));
+ break;
+ }
case OMX_IndexParamVideoSliceFMO:
default:
{
@@ -2087,6 +2114,11 @@ bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
#endif
}
+bool omx_venc::dev_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
+ OMX_U32 *nMaxBLayers) {
+ return handle->venc_get_temporal_layer_caps(nMaxLayers, nMaxBLayers);
+}
+
bool omx_venc::dev_loaded_start()
{
return handle->venc_loaded_start();
diff --git a/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
index cd3ba9f..cc8d6ae 100644
--- a/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/msm8974/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -255,6 +255,7 @@ venc_dev::venc_dev(class omx_venc *venc_class)
memset(&ltrinfo, 0, sizeof(ltrinfo));
sess_priority.priority = 1;
operating_rate = 0;
+ memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
char property_value[PROPERTY_VALUE_MAX] = {0};
property_get("vidc.enc.log.in", property_value, "0");
@@ -1913,6 +1914,15 @@ bool venc_dev::venc_set_param(void *paramData,OMX_INDEXTYPE index )
}
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ if (venc_set_temporal_layers(
+ (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
+ return false;
+ }
+ break;
+ }
case OMX_IndexParamVideoSliceFMO:
default:
DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
@@ -2163,6 +2173,11 @@ bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
}
break;
}
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
+ return false;
+ }
default:
DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
break;
@@ -2300,6 +2315,26 @@ unsigned venc_dev::venc_start(void)
__func__, codec_profile.profile, profile_level.level);
}
+ // re-configure the temporal layers as RC-mode and key-frame interval
+ // might have changed since the client last configured the layers.
+ if (temporal_layers_config.nPLayers) {
+ if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
+ } else {
+ // request buffers on capture port again since internal (scratch)-
+ // buffer requirements may change (i.e if we switch from non-hybrid
+ // to hybrid mode and vice-versa)
+ struct v4l2_requestbuffers bufreq;
+
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = m_sOutput_buff_property.actualcount;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
+ DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
+ }
+ }
+ }
+
venc_config_print();
if(resume_in_stopped){
@@ -2398,8 +2433,16 @@ void venc_dev::venc_config_print()
DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
ltrinfo.enabled, ltrinfo.count);
- DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
- hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
+ if (hier_layers.numlayers) {
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
+ hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
+ }
+
+ if (temporal_layers_config.nPLayers) {
+ DEBUG_PRINT_INFO("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %u",
+ temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
+ intra_period.num_pframes + intra_period.num_bframes + 1);
+ }
DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
@@ -4790,6 +4833,111 @@ bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
return true;
}
+bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
+ OMX_U32 *nMaxBLayers) {
+ temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
+ temporal_layers_config.nMaxBLayers = 0;
+
+ *nMaxLayers = temporal_layers_config.nMaxLayers;
+ *nMaxBLayers = temporal_layers_config.nMaxBLayers;
+ return true;
+}
+
+OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
+
+ if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
+ || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
+ || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
+ DEBUG_PRINT_ERROR("Temporal layers not supported for %ld", m_sVenc_cfg.codectype);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
+ (pTemporalParams->nBLayerCountActual != 0 ||
+ pTemporalParams->nPLayerCountActual != 1)) {
+ return OMX_ErrorBadParameter;
+ } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
+ pTemporalParams->nPLayerCountActual < 1) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
+ DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers (%u) exceeds supported max(%u)",
+ pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
+ return OMX_ErrorBadParameter;
+ } else if (pTemporalParams->nPLayerCountActual >
+ temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
+ DEBUG_PRINT_ERROR("TemporalLayer: Requested layers (%u) exceeds supported max(%u)",
+ pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
+ temporal_layers_config.nMaxLayers);
+ return OMX_ErrorBadParameter;
+ }
+
+ // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
+ // use hybrid-HP for best results
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 &&
+ pTemporalParams->nBLayerCountActual == 0 &&
+ (rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR)) {
+ if (!venc_set_hybrid_hierp(pTemporalParams->nPLayerCountActual)) {
+ DEBUG_PRINT_ERROR("Failed to enable (hybrid) Hier-P with %u layers",
+ pTemporalParams->nPLayerCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ temporal_layers_config.hier_mode = HIER_P_HYBRID;
+ temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
+ temporal_layers_config.nBLayers = 0;
+
+ // we ignore layer-size bitrate request for this mode
+ temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
+ pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
+
+ } else {
+ if (pTemporalParams->nBLayerCountActual == 0) {
+ if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, pTemporalParams->nPLayerCountActual)) {
+ DEBUG_PRINT_ERROR("Failed to enable Hier-P with %u layers",
+ pTemporalParams->nPLayerCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ temporal_layers_config.hier_mode = HIER_P;
+ temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
+ temporal_layers_config.nBLayers = 0;
+
+ // TODO: handle layer-wise bitrate request. For now, disregard the setting
+ temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
+ pTemporalParams->bBitrateRatiosSpecified = OMX_FALSE;
+
+ } else {
+ // we do not support B-frames with enhancement layers for now
+ }
+ }
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
+ memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+
+ if (!temporal_layers_config.nPLayers) {
+ return OMX_ErrorNone;
+ }
+ pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+ pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
+ pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
+ pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+ pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
+ pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
+ pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
+ if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
+ for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
+ pTemporalParams.nBitrateRatios[i] =
+ temporal_layers_config.nTemporalLayerBitrateRatio[i];
+ }
+ }
+ return venc_set_temporal_layers(&pTemporalParams);
+}
+
bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
{
bool status = true;
diff --git a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
index 7661b6c..9d041e9 100644
--- a/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/msm8996/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -4635,7 +4635,20 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
}
break;
case OMX_GoogleAndroidIndexAllocateNativeHandle: {
+
AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
+ VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
+
+ if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on input port!");
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ } else if (m_inp_mem_ptr) {
+ DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
+ eRet = OMX_ErrorInvalidState;
+ break;
+ }
+
if (allocateNativeHandleParams != NULL) {
allocate_native_handle = allocateNativeHandleParams->enable;
}
diff --git a/msmcobalt/Android.mk b/msmcobalt/Android.mk
new file mode 100644
index 0000000..2e7f2c4
--- /dev/null
+++ b/msmcobalt/Android.mk
@@ -0,0 +1,16 @@
+QCOM_MEDIA_ROOT := $(call my-dir)
+
+#Compile these for all targets under QCOM_BOARD_PLATFORMS list.
+ifeq ($(call is-board-platform-in-list, $(QCOM_BOARD_PLATFORMS)),true)
+include $(QCOM_MEDIA_ROOT)/mm-core/Android.mk
+include $(QCOM_MEDIA_ROOT)/libstagefrighthw/Android.mk
+endif
+
+ifeq ($(call is-board-platform-in-list, $(MSM_VIDC_TARGET_LIST)),true)
+include $(QCOM_MEDIA_ROOT)/mm-video-v4l2/Android.mk
+
+ifeq ($(BOARD_USES_ADRENO), true)
+include $(QCOM_MEDIA_ROOT)/libc2dcolorconvert/Android.mk
+endif
+
+endif
diff --git a/msmcobalt/NOTICE b/msmcobalt/NOTICE
new file mode 100644
index 0000000..5b4b46e
--- /dev/null
+++ b/msmcobalt/NOTICE
@@ -0,0 +1,85 @@
+Copyright (c) 2009-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.
+
+---
+Copyright (C) 2010 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+---
+Copyright (c) 2008 The Khronos Group Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject
+to the following conditions:
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ Microsoft Skype Engineering
+ Copyright (C) 2014 Microsoft Corporation.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
diff --git a/msmcobalt/conf_files/config.mk b/msmcobalt/conf_files/config.mk
new file mode 100644
index 0000000..948b536
--- /dev/null
+++ b/msmcobalt/conf_files/config.mk
@@ -0,0 +1,5 @@
+ifeq ($(TARGET_BOARD_PLATFORM),msm8937)
+PRODUCT_COPY_FILES += $(QCOM_MEDIA_ROOT)/conf_files/msm8937/media_profiles_8937.xml:system/etc/media_profiles.xml \
+ $(QCOM_MEDIA_ROOT)/conf_files/msm8937/media_codecs_8937.xml:system/etc/media_codecs.xml \
+ $(QCOM_MEDIA_ROOT)/conf_files/msm8937/media_codecs_performance_8937.xml:system/etc/media_codecs_performance.xml
+endif #TARGET_BOARD_PLATFORM
diff --git a/msmcobalt/conf_files/msm8937/media_codecs_8937.xml b/msmcobalt/conf_files/msm8937/media_codecs_8937.xml
new file mode 100644
index 0000000..b511af9
--- /dev/null
+++ b/msmcobalt/conf_files/msm8937/media_codecs_8937.xml
@@ -0,0 +1,236 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+ Copyright (C) 2015 The Linux Foundation. All rights reserved.
+ Not a contribution.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<!--
+<!DOCTYPE MediaCodecs [
+<!ELEMENT Include EMPTY>
+<!ATTLIST Include href CDATA #REQUIRED>
+<!ELEMENT MediaCodecs (Decoders|Encoders|Include)*>
+<!ELEMENT Decoders (MediaCodec|Include)*>
+<!ELEMENT Encoders (MediaCodec|Include)*>
+<!ELEMENT MediaCodec (Type|Quirk|Include)*>
+<!ATTLIST MediaCodec name CDATA #REQUIRED>
+<!ATTLIST MediaCodec type CDATA>
+<!ELEMENT Type EMPTY>
+<!ATTLIST Type name CDATA #REQUIRED>
+<!ELEMENT Quirk EMPTY>
+<!ATTLIST Quirk name CDATA #REQUIRED>
+]>
+
+There's a simple and a complex syntax to declare the availability of a
+media codec:
+
+A codec that properly follows the OpenMax spec and therefore doesn't have any
+quirks and that only supports a single content type can be declared like so:
+
+ <MediaCodec name="OMX.foo.bar" type="something/interesting" />
+
+If a codec has quirks OR supports multiple content types, the following syntax
+can be used:
+
+ <MediaCodec name="OMX.foo.bar" >
+ <Type name="something/interesting" />
+ <Type name="something/else" />
+ ...
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="output-buffers-are-unreadable" />
+ </MediaCodec>
+
+Only the three quirks included above are recognized at this point:
+
+"requires-allocate-on-input-ports"
+ must be advertised if the component does not properly support specification
+ of input buffers using the OMX_UseBuffer(...) API but instead requires
+ OMX_AllocateBuffer to be used.
+
+"requires-allocate-on-output-ports"
+ must be advertised if the component does not properly support specification
+ of output buffers using the OMX_UseBuffer(...) API but instead requires
+ OMX_AllocateBuffer to be used.
+
+"output-buffers-are-unreadable"
+ must be advertised if the emitted output buffers of a decoder component
+ are not readable, i.e. use a custom format even though abusing one of
+ the official OMX colorspace constants.
+ Clients of such decoders will not be able to access the decoded data,
+ naturally making the component much less useful. The only use for
+ a component with this quirk is to render the output to the screen.
+ Audio decoders MUST NOT advertise this quirk.
+ Video decoders that advertise this quirk must be accompanied by a
+ corresponding color space converter for thumbnail extraction,
+ matching surfaceflinger support that can render the custom format to
+ a texture and possibly other code, so just DON'T USE THIS QUIRK.
+
+
+-->
+
+<!--
+ Decoder capabilities for thorium
+ _________________________________________________________________________
+ | Codec | W H fps Mbps MB/s | Encode Secure-dec |
+ |__________|_________________________________________|___________________|
+ | h264 | 1920 1088 30 20 244800 | Y Y |
+ | hevc | 1920 1088 30 20 244800 | N N |
+ | mpeg4 | 1920 1088 30 6 244800 | Y N |
+ | vp8 | 1920 1088 30 20 244800 | N N |
+ | div4/5/6 | 1920 1088 30 6 244800 | N N |
+ | h263 | 864 480 30 2 48600 | Y N |
+ |__________|_________________________________________|___________________|
+
+-->
+
+<!--
+ Encoder capabilities for thorium
+ ____________________________________________________
+ | Codec | W H fps Mbps MB/s |
+ |__________|_________________________________________|
+ | h264 | 1920 1088 30 20 244800 |
+ | mpeg4 | 864 480 30 2 48600 |
+ | h263 | 864 480 30 2 48600 |
+ |____________________________________________________|
+-->
+
+<MediaCodecs>
+ <Include href="media_codecs_google_audio.xml" />
+ <Include href="media_codecs_google_telephony.xml" />
+ <Settings>
+ <Setting name="max-video-encoder-input-buffers" value="9" />
+ </Settings>
+ <Encoders>
+ <!-- Video Hardware -->
+ <MediaCodec name="OMX.qcom.video.encoder.avc" type="video/avc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="requires-loaded-to-idle-after-allocation" />
+ <Limit name="size" min="96x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-20000000" />
+ <Limit name="concurrent-instances" max="8" />
+ </MediaCodec>
+ <!-- Video Software -->
+ <MediaCodec name="OMX.qcom.video.encoder.mpeg4sw" type="video/mp4v-es" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="requires-loaded-to-idle-after-allocation" />
+ <Limit name="size" min="32x32" max="864x480" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="48600" />
+ <Limit name="bitrate" range="1-2000000" />
+ <Limit name="concurrent-instances" max="1" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.encoder.h263sw" type="video/3gpp" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="requires-loaded-to-idle-after-allocation" />
+ <Limit name="size" min="32x32" max="864x480" />
+ <Limit name="alignment" value="4x4" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="48600" />
+ <Limit name="bitrate" range="1-2000000" />
+ <Limit name="concurrent-instances" max="1" />
+ </MediaCodec>
+ </Encoders>
+ <Decoders>
+ <!-- Audio Software -->
+ <MediaCodec name="OMX.qti.audio.decoder.flac" type="audio/flac" />
+ <!-- Video Hardware -->
+ <MediaCodec name="OMX.qcom.video.decoder.avc" type="video/avc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="defers-output-buffer-allocation" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-20000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="8" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.vp8" type="video/x-vnd.on2.vp8" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="defers-output-buffer-allocation" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-20000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="8" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.hevc" type="video/hevc" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Quirk name="defers-output-buffer-allocation" />
+ <Limit name="size" min="64x64" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-20000000" />
+ <Feature name="adaptive-playback" />
+ <Limit name="concurrent-instances" max="8" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qti.video.decoder.divxsw" type="video/divx" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="16x16" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-6000000" />
+ <Limit name="concurrent-instances" max="1" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qti.video.decoder.divx4sw" type="video/divx4" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="16x16" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-6000000" />
+ <Limit name="concurrent-instances" max="1" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qti.video.decoder.mpeg4sw">
+ <Type name="video/mp4v-es" />
+ <Type name="video/mp4v-esdp" />
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="16x16" max="1920x1088" />
+ <Limit name="alignment" value="2x2" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="244800" />
+ <Limit name="bitrate" range="1-6000000" />
+ <Limit name="concurrent-instances" max="1" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qti.video.decoder.h263sw" type="video/3gpp" >
+ <Quirk name="requires-allocate-on-input-ports" />
+ <Quirk name="requires-allocate-on-output-ports" />
+ <Limit name="size" min="16x16" max="864x480" />
+ <Limit name="alignment" value="4x4" />
+ <Limit name="block-size" value="16x16" />
+ <Limit name="blocks-per-second" min="1" max="48600" />
+ <Limit name="bitrate" range="1-2000000" />
+ <Limit name="concurrent-instances" max="1" />
+ </MediaCodec>
+ </Decoders>
+ <Include href="media_codecs_google_video.xml" />
+</MediaCodecs>
diff --git a/msmcobalt/conf_files/msm8937/media_codecs_performance_8937.xml b/msmcobalt/conf_files/msm8937/media_codecs_performance_8937.xml
new file mode 100644
index 0000000..3415ac2
--- /dev/null
+++ b/msmcobalt/conf_files/msm8937/media_codecs_performance_8937.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!-- Copyright (c) 2015, The Linux Foundation. All rights reserved.
+
+ Not a Contribution.
+
+ Copyright 2015 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<MediaCodecs>
+ <Encoders>
+ <MediaCodec name="OMX.qcom.video.encoder.avc" type="video/avc" update="true">
+ <Limit name="measured-frame-rate-320x240" range="377-377" />
+ <Limit name="measured-frame-rate-720x480" range="113-113" />
+ <Limit name="measured-frame-rate-1280x720" range="76-76" />
+ <Limit name="measured-frame-rate-1920x1080" range="44-44" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.encoder.h263sw" type="video/3gpp" update="true">
+ <Limit name="measured-frame-rate-176x144" range="160-160" />
+ <Limit name="measured-frame-rate-352x288" range="86-86" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.encoder.mpeg4sw" type="video/mp4v-es" update="true">
+ <Limit name="measured-frame-rate-176x144" range="179-179" />
+ <Limit name="measured-frame-rate-352x288" range="84-84" />
+ <Limit name="measured-frame-rate-640x480" range="54-54" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.h264.encoder" type="video/avc" update="true">
+ <Limit name="measured-frame-rate-320x240" range="208-208" />
+ <Limit name="measured-frame-rate-720x480" range="98-98" />
+ <Limit name="measured-frame-rate-1280x720" range="44-44" />
+ <Limit name="measured-frame-rate-1920x1080" range="21-21" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.h263.encoder" type="video/3gpp" update="true">
+ <Limit name="measured-frame-rate-176x144" range="397-397" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.mpeg4.encoder" type="video/mp4v-es" update="true">
+ <Limit name="measured-frame-rate-176x144" range="413-413" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.vp8.encoder" type="video/x-vnd.on2.vp8" update="true">
+ <Limit name="measured-frame-rate-320x180" range="328-328" />
+ <Limit name="measured-frame-rate-640x360" range="158-158" />
+ <Limit name="measured-frame-rate-1280x720" range="65-65" />
+ <Limit name="measured-frame-rate-1920x1080" range="29-29" />
+ </MediaCodec>
+ </Encoders>
+ <Decoders>
+ <MediaCodec name="OMX.qcom.video.decoder.avc" type="video/avc" update="true">
+ <Limit name="measured-frame-rate-320x240" range="570-570" />
+ <Limit name="measured-frame-rate-720x480" range="280-280" />
+ <Limit name="measured-frame-rate-1280x720" range="155-155" />
+ <Limit name="measured-frame-rate-1920x1088" range="57-57" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.hevc" type="video/hevc" update="true">
+ <Limit name="measured-frame-rate-352x288" range="578-578" />
+ <Limit name="measured-frame-rate-720x480" range="390-390" />
+ <Limit name="measured-frame-rate-1280x720" range="157-157" />
+ <Limit name="measured-frame-rate-1920x1088" range="63-63" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qti.video.decoder.h263sw" type="video/3gpp" update="true">
+ <Limit name="measured-frame-rate-176x144" range="889-889" />
+ <Limit name="measured-frame-rate-352x288" range="580-580" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qti.video.decoder.mpeg4sw" type="video/mp4v-es" update="true">
+ <Limit name="measured-frame-rate-480x360" range="519-519" />
+ </MediaCodec>
+ <MediaCodec name="OMX.qcom.video.decoder.vp8" type="video/x-vnd.on2.vp8" update="true">
+ <Limit name="measured-frame-rate-320x240" range="659-659" />
+ <Limit name="measured-frame-rate-640x360" range="509-509" />
+ <Limit name="measured-frame-rate-1280x720" range="162-162" />
+ <Limit name="measured-frame-rate-1920x1080" range="87-87" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.h264.decoder" type="video/avc" update="true">
+ <Limit name="measured-frame-rate-320x240" range="586-586" />
+ <Limit name="measured-frame-rate-720x480" range="287-287" />
+ <Limit name="measured-frame-rate-1280x720" range="186-186" />
+ <Limit name="measured-frame-rate-1920x1080" range="80-80" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.hevc.decoder" type="video/hevc" update="true">
+ <Limit name="measured-frame-rate-352x288" range="525-525" />
+ <Limit name="measured-frame-rate-720x480" range="333-333" />
+ <Limit name="measured-frame-rate-1280x720" range="189-189" />
+ <Limit name="measured-frame-rate-1920x1080" range="104-104" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.h263.decoder" type="video/3gpp" update="true">
+ <Limit name="measured-frame-rate-176x144" range="1292-1292" />
+ <Limit name="measured-frame-rate-352x288" range="834-834" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.vp8.decoder" type="video/x-vnd.on2.vp8" update="true">
+ <Limit name="measured-frame-rate-320x240" range="1330-1330" />
+ <Limit name="measured-frame-rate-640x360" range="340-340" />
+ <Limit name="measured-frame-rate-1280x720" range="59-59" />
+ <Limit name="measured-frame-rate-1920x1080" range="44-44" />
+ </MediaCodec>
+ <MediaCodec name="OMX.google.vp9.decoder" type="video/x-vnd.on2.vp9" update="true">
+ <Limit name="measured-frame-rate-320x240" range="511-511" />
+ <Limit name="measured-frame-rate-640x360" range="421-421" />
+ <Limit name="measured-frame-rate-1280x720" range="111-111" />
+ <Limit name="measured-frame-rate-1920x1080" range="76-76" />
+ </MediaCodec>
+ </Decoders>
+</MediaCodecs>
+
diff --git a/msmcobalt/conf_files/msm8937/media_profiles_8937.xml b/msmcobalt/conf_files/msm8937/media_profiles_8937.xml
new file mode 100644
index 0000000..e48043e
--- /dev/null
+++ b/msmcobalt/conf_files/msm8937/media_profiles_8937.xml
@@ -0,0 +1,698 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+ Copyright (C) 2015 The Linux Foundation. All rights reserved.
+ Not a contribution.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!DOCTYPE MediaSettings [
+<!ELEMENT MediaSettings (CamcorderProfiles,
+ EncoderOutputFileFormat+,
+ VideoEncoderCap+,
+ AudioEncoderCap+,
+ VideoDecoderCap,
+ AudioDecoderCap)>
+<!ELEMENT CamcorderProfiles (EncoderProfile+, ImageEncoding+, ImageDecoding, Camera)>
+<!ELEMENT EncoderProfile (Video, Audio)>
+<!ATTLIST EncoderProfile quality (high|low) #REQUIRED>
+<!ATTLIST EncoderProfile fileFormat (mp4|3gp) #REQUIRED>
+<!ATTLIST EncoderProfile duration (30|60) #REQUIRED>
+<!ATTLIST EncoderProfile cameraId (0|1) #REQUIRED>
+<!ELEMENT Video EMPTY>
+<!ATTLIST Video codec (h264|h263|m4v) #REQUIRED>
+<!ATTLIST Video bitRate CDATA #REQUIRED>
+<!ATTLIST Video width CDATA #REQUIRED>
+<!ATTLIST Video height CDATA #REQUIRED>
+<!ATTLIST Video frameRate CDATA #REQUIRED>
+<!ELEMENT Audio EMPTY>
+<!ATTLIST Audio codec (amrnb|amrwb|aac|lpcm) #REQUIRED>
+<!ATTLIST Audio bitRate CDATA #REQUIRED>
+<!ATTLIST Audio sampleRate CDATA #REQUIRED>
+<!ATTLIST Audio channels (1|2|6) #REQUIRED>
+<!ELEMENT ImageEncoding EMPTY>
+<!ATTLIST ImageEncoding quality (90|80|70|60|50|40) #REQUIRED>
+<!ELEMENT ImageDecoding EMPTY>
+<!ATTLIST ImageDecoding memCap CDATA #REQUIRED>
+<!ELEMENT Camera EMPTY>
+<!ELEMENT EncoderOutputFileFormat EMPTY>
+<!ATTLIST EncoderOutputFileFormat name (mp4|3gp) #REQUIRED>
+<!ELEMENT VideoEncoderCap EMPTY>
+<!ATTLIST VideoEncoderCap name (h264|h263|m4v) #REQUIRED>
+<!ATTLIST VideoEncoderCap enabled (true|false) #REQUIRED>
+<!ATTLIST VideoEncoderCap minBitRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxBitRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap minFrameRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxFrameRate CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxHFRFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxHFRFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEncoderCap maxHFRMode CDATA #REQUIRED>
+<!ELEMENT AudioEncoderCap EMPTY>
+<!ATTLIST AudioEncoderCap name (amrnb|amrwb|aac|wma|lpcm) #REQUIRED>
+<!ATTLIST AudioEncoderCap enabled (true|false) #REQUIRED>
+<!ATTLIST AudioEncoderCap minBitRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap maxBitRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap minSampleRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap maxSampleRate CDATA #REQUIRED>
+<!ATTLIST AudioEncoderCap minChannels (1|2|6) #REQUIRED>
+<!ATTLIST AudioEncoderCap maxChannels (1|2|6) #REQUIRED>
+<!ELEMENT VideoDecoderCap EMPTY>
+<!ATTLIST VideoDecoderCap name (wmv) #REQUIRED>
+<!ATTLIST VideoDecoderCap enabled (true|false) #REQUIRED>
+<!ELEMENT AudioDecoderCap EMPTY>
+<!ATTLIST AudioDecoderCap name (wma) #REQUIRED>
+<!ATTLIST AudioDecoderCap enabled (true|false) #REQUIRED>
+<!ELEMENT VideoEditorCap EMPTY>
+<!ATTLIST VideoEditorCap maxInputFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxInputFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxOutputFrameWidth CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxOutputFrameHeight CDATA #REQUIRED>
+<!ATTLIST VideoEditorCap maxPrefetchYUVFrames CDATA #REQUIRED>
+<!ELEMENT ExportVideoProfile EMPTY>
+<!ATTLIST ExportVideoProfile name (h264) #REQUIRED>
+<!ATTLIST ExportVideoProfile profile CDATA #REQUIRED>
+<!ATTLIST ExportVideoProfile level CDATA #REQUIRED>
+]>
+<!--
+ This file is used to declare the multimedia profiles and capabilities
+ on an android-powered device.
+-->
+<MediaSettings>
+ <!-- Each camcorder profile defines a set of predefined configuration parameters -->
+ <!-- Back Camera -->
+ <CamcorderProfiles cameraId="0" startOffsetMs="300">
+
+ <EncoderProfile quality="low" fileFormat="3gp" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="high" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+ <Video codec="h264"
+ bitRate="512000"
+ width="320"
+ height="240"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="cif" fileFormat="3gp" duration="30">
+ <Video codec="h264"
+ bitRate="720000"
+ width="352"
+ height="288"
+ frameRate="30" />
+
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="480p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="2000000"
+ width="720"
+ height="480"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="720p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="14000000"
+ width="1280"
+ height="720"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="1080p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="qcif" fileFormat="3gp" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="vga" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="2000000"
+ width="640"
+ height="480"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapselow" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapsehigh" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapsecif" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="720000"
+ width="352"
+ height="288"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+
+ <EncoderProfile quality="timelapseqvga" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="512000"
+ width="320"
+ height="240"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapsevga" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="2000000"
+ width="640"
+ height="480"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapse480p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="2000000"
+ width="640"
+ height="480"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapse720p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="14000000"
+ width="1280"
+ height="720"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapse1080p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <ImageEncoding quality="95" />
+ <ImageEncoding quality="80" />
+ <ImageEncoding quality="70" />
+ <ImageDecoding memCap="20000000" />
+
+ </CamcorderProfiles>
+ <!-- Front Camera -->
+ <CamcorderProfiles cameraId="1" startOffsetMs="300">
+
+ <EncoderProfile quality="low" fileFormat="3gp" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="high" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="qvga" fileFormat="mp4" duration="60">
+ <Video codec="h264"
+ bitRate="512000"
+ width="320"
+ height="240"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="cif" fileFormat="3gp" duration="30">
+ <Video codec="h264"
+ bitRate="720000"
+ width="352"
+ height="288"
+ frameRate="30" />
+
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="480p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="2000000"
+ width="720"
+ height="480"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="720p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="14000000"
+ width="1280"
+ height="720"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="1080p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="qcif" fileFormat="3gp" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="vga" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="2000000"
+ width="640"
+ height="480"
+ frameRate="30" />
+
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapselow" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapsehigh" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+ <EncoderProfile quality="timelapseqcif" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="192000"
+ width="176"
+ height="144"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapsecif" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="1200000"
+ width="352"
+ height="288"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="96000"
+ sampleRate="48000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapseqvga" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="512000"
+ width="320"
+ height="240"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapsevga" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="2000000"
+ width="640"
+ height="480"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="amrnb"
+ bitRate="12200"
+ sampleRate="8000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapse480p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="5000000"
+ width="720"
+ height="480"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="96000"
+ sampleRate="48000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapse720p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="8000000"
+ width="1280"
+ height="720"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="96000"
+ sampleRate="48000"
+ channels="1" />
+ </EncoderProfile>
+
+ <EncoderProfile quality="timelapse1080p" fileFormat="mp4" duration="30">
+ <Video codec="h264"
+ bitRate="20000000"
+ width="1920"
+ height="1080"
+ frameRate="30" />
+
+ <!-- audio setting is ignored -->
+ <Audio codec="aac"
+ bitRate="156000"
+ sampleRate="48000"
+ channels="2" />
+ </EncoderProfile>
+
+ <ImageEncoding quality="95" />
+ <ImageEncoding quality="80" />
+ <ImageEncoding quality="70" />
+ <ImageDecoding memCap="20000000" />
+
+ </CamcorderProfiles>
+
+ <EncoderOutputFileFormat name="3gp" />
+ <EncoderOutputFileFormat name="mp4" />
+
+ <!--
+ If a codec is not enabled, it is invisible to the applications
+ In other words, the applications won't be able to use the codec
+ or query the capabilities of the codec at all if it is disabled
+ -->
+ <VideoEncoderCap name="h264" enabled="true"
+ minBitRate="64000" maxBitRate="20000000"
+ minFrameWidth="176" maxFrameWidth="1920"
+ minFrameHeight="144" maxFrameHeight="1080"
+ minFrameRate="15" maxFrameRate="30"
+ maxHFRFrameWidth="1280" maxHFRFrameHeight="720"
+ maxHFRMode="60" />
+
+ <VideoEncoderCap name="h263" enabled="true"
+ minBitRate="64000" maxBitRate="2000000"
+ minFrameWidth="176" maxFrameWidth="864"
+ minFrameHeight="144" maxFrameHeight="480"
+ minFrameRate="15" maxFrameRate="30"
+ maxHFRFrameWidth="0" maxHFRFrameHeight="0"
+ maxHFRMode="0" />
+
+ <VideoEncoderCap name="m4v" enabled="true"
+ minBitRate="64000" maxBitRate="2000000"
+ minFrameWidth="176" maxFrameWidth="864"
+ minFrameHeight="144" maxFrameHeight="480"
+ minFrameRate="15" maxFrameRate="30"
+ maxHFRFrameWidth="0" maxHFRFrameHeight="0"
+ maxHFRMode="0" />
+
+ <AudioEncoderCap name="aac" enabled="true"
+ minBitRate="8000" maxBitRate="96000"
+ minSampleRate="8000" maxSampleRate="48000"
+ minChannels="1" maxChannels="6" />
+
+ <AudioEncoderCap name="heaac" enabled="true"
+ minBitRate="8000" maxBitRate="64000"
+ minSampleRate="16000" maxSampleRate="48000"
+ minChannels="1" maxChannels="1" />
+
+ <AudioEncoderCap name="aaceld" enabled="true"
+ minBitRate="16000" maxBitRate="192000"
+ minSampleRate="16000" maxSampleRate="48000"
+ minChannels="1" maxChannels="1" />
+
+ <AudioEncoderCap name="amrwb" enabled="true"
+ minBitRate="6600" maxBitRate="23850"
+ minSampleRate="16000" maxSampleRate="16000"
+ minChannels="1" maxChannels="1" />
+
+ <AudioEncoderCap name="amrnb" enabled="true"
+ minBitRate="5525" maxBitRate="12200"
+ minSampleRate="8000" maxSampleRate="8000"
+ minChannels="1" maxChannels="1" />
+
+<!-- <AudioEncoderCap name="lpcm" enabled="true"
+ minBitRate="768000" maxBitRate="4608000"
+ minSampleRate="48000" maxSampleRate="48000"
+ minChannels="1" maxChannels="6" />-->
+
+ <!--
+ FIXME:
+ We do not check decoder capabilities at present
+ At present, we only check whether windows media is visible
+ for TEST applications. For other applications, we do
+ not perform any checks at all.
+ -->
+ <VideoDecoderCap name="wmv" enabled="true"/>
+ <AudioDecoderCap name="wma" enabled="true"/>
+
+ <!--
+ The VideoEditor Capability configuration:
+ - maxInputFrameWidth: maximum video width of imported video clip.
+ - maxInputFrameHeight: maximum video height of imported video clip.
+ - maxOutputFrameWidth: maximum video width of exported video clip.
+ - maxOutputFrameHeight: maximum video height of exported video clip.
+ - maxPrefetchYUVFrames: maximum prefetch YUV frames for encoder,
+ used to limit the amount of memory for prefetched YUV frames.
+ For this platform, it allows maximum 30MB(3MB per 1080p frame x 10
+ frames) memory.
+ -->
+ <VideoEditorCap maxInputFrameWidth="1920"
+ maxInputFrameHeight="1080" maxOutputFrameWidth="1920"
+ maxOutputFrameHeight="1080" maxPrefetchYUVFrames="10"/>
+ <!--
+ The VideoEditor Export codec profile and level values
+ correspond to the values in OMX_Video.h.
+ E.g. for h264, profile value 1 means OMX_VIDEO_AVCProfileBaseline
+ and level 4096 means OMX_VIDEO_AVCLevel41.
+ Please note that the values are in decimal.
+ These values are for video encoder.
+ -->
+ <!--
+ Codec = h.264, Baseline profile, level 4
+ -->
+ <ExportVideoProfile name="h264" profile= "1" level="2048"/>
+</MediaSettings>
diff --git a/msmcobalt/libc2dcolorconvert/Android.mk b/msmcobalt/libc2dcolorconvert/Android.mk
new file mode 100644
index 0000000..a505afc
--- /dev/null
+++ b/msmcobalt/libc2dcolorconvert/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ C2DColorConverter.cpp
+
+LOCAL_C_INCLUDES := \
+ $(TARGET_OUT_HEADERS)/adreno
+LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/qcom/display
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+endif
+
+LOCAL_SHARED_LIBRARIES := liblog libdl
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE := libc2dcolorconvert
+
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/msmcobalt/libc2dcolorconvert/C2DColorConverter.cpp b/msmcobalt/libc2dcolorconvert/C2DColorConverter.cpp
new file mode 100644
index 0000000..c9681c7
--- /dev/null
+++ b/msmcobalt/libc2dcolorconvert/C2DColorConverter.cpp
@@ -0,0 +1,780 @@
+/* Copyright (c) 2012 - 2016, 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 <C2DColorConverter.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <linux/msm_kgsl.h>
+#include <sys/ioctl.h>
+#include <utils/Log.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <errno.h>
+#include <media/msm_media_info.h>
+#include <gralloc_priv.h>
+
+#undef LOG_TAG
+#define LOG_TAG "C2DColorConvert"
+#define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
+#define ALIGN8K 8192
+#define ALIGN4K 4096
+#define ALIGN2K 2048
+#define ALIGN128 128
+#define ALIGN32 32
+#define ALIGN16 16
+
+//-----------------------------------------------------
+namespace android {
+
+class C2DColorConverter : public C2DColorConverterBase {
+
+public:
+ C2DColorConverter(size_t srcWidth, size_t srcHeight, size_t dstWidth, size_t dstHeight, ColorConvertFormat srcFormat, ColorConvertFormat dstFormat, int32_t flags,size_t srcStride);
+ int32_t getBuffReq(int32_t port, C2DBuffReq *req);
+ int32_t dumpOutput(char * filename, char mode);
+protected:
+ virtual ~C2DColorConverter();
+ virtual int convertC2D(int srcFd, void *srcBase, void * srcData, int dstFd, void *dstBase, void * dstData);
+
+private:
+ bool isYUVSurface(ColorConvertFormat format);
+ void *getDummySurfaceDef(ColorConvertFormat format, size_t width, size_t height, bool isSource);
+ C2D_STATUS updateYUVSurfaceDef(int fd, void *base, void * data, bool isSource);
+ C2D_STATUS updateRGBSurfaceDef(int fd, void * data, bool isSource);
+ uint32_t getC2DFormat(ColorConvertFormat format);
+ size_t calcStride(ColorConvertFormat format, size_t width);
+ size_t calcYSize(ColorConvertFormat format, size_t width, size_t height);
+ size_t calcSize(ColorConvertFormat format, size_t width, size_t height);
+ void *getMappedGPUAddr(int bufFD, void *bufPtr, size_t bufLen);
+ bool unmapGPUAddr(unsigned long gAddr);
+ size_t calcLumaAlign(ColorConvertFormat format);
+ size_t calcSizeAlign(ColorConvertFormat format);
+ C2DBytesPerPixel calcBytesPerPixel(ColorConvertFormat format);
+
+ void *mC2DLibHandle;
+ LINK_c2dCreateSurface mC2DCreateSurface;
+ LINK_c2dUpdateSurface mC2DUpdateSurface;
+ LINK_c2dReadSurface mC2DReadSurface;
+ LINK_c2dDraw mC2DDraw;
+ LINK_c2dFlush mC2DFlush;
+ LINK_c2dFinish mC2DFinish;
+ LINK_c2dWaitTimestamp mC2DWaitTimestamp;
+ LINK_c2dDestroySurface mC2DDestroySurface;
+ LINK_c2dMapAddr mC2DMapAddr;
+ LINK_c2dUnMapAddr mC2DUnMapAddr;
+
+ void *mAdrenoUtilsHandle;
+ LINK_AdrenoComputeAlignedWidthAndHeight mAdrenoComputeAlignedWidthAndHeight;
+
+ uint32_t mSrcSurface, mDstSurface;
+ void * mSrcSurfaceDef;
+ void * mDstSurfaceDef;
+
+ C2D_OBJECT mBlit;
+ size_t mSrcWidth;
+ size_t mSrcHeight;
+ size_t mSrcStride;
+ size_t mDstWidth;
+ size_t mDstHeight;
+ size_t mSrcSize;
+ size_t mDstSize;
+ size_t mSrcYSize;
+ size_t mDstYSize;
+ enum ColorConvertFormat mSrcFormat;
+ enum ColorConvertFormat mDstFormat;
+ int32_t mFlags;
+
+ int mError;
+};
+
+C2DColorConverter::C2DColorConverter(size_t srcWidth, size_t srcHeight, size_t dstWidth, size_t dstHeight, ColorConvertFormat srcFormat, ColorConvertFormat dstFormat, int32_t flags, size_t srcStride)
+ : mC2DLibHandle(NULL),
+ mAdrenoUtilsHandle(NULL)
+{
+ mError = 0;
+ if (NV12_UBWC == dstFormat) {
+ ALOGE("%s: FATAL ERROR: could not support UBWC output formats ", __FUNCTION__);
+ mError = -1;
+ return;
+ }
+ mC2DLibHandle = dlopen("libC2D2.so", RTLD_NOW);
+ if (!mC2DLibHandle) {
+ ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
+ mError = -1;
+ return;
+ }
+ mC2DCreateSurface = (LINK_c2dCreateSurface)dlsym(mC2DLibHandle, "c2dCreateSurface");
+ mC2DUpdateSurface = (LINK_c2dUpdateSurface)dlsym(mC2DLibHandle, "c2dUpdateSurface");
+ mC2DReadSurface = (LINK_c2dReadSurface)dlsym(mC2DLibHandle, "c2dReadSurface");
+ mC2DDraw = (LINK_c2dDraw)dlsym(mC2DLibHandle, "c2dDraw");
+ mC2DFlush = (LINK_c2dFlush)dlsym(mC2DLibHandle, "c2dFlush");
+ mC2DFinish = (LINK_c2dFinish)dlsym(mC2DLibHandle, "c2dFinish");
+ mC2DWaitTimestamp = (LINK_c2dWaitTimestamp)dlsym(mC2DLibHandle, "c2dWaitTimestamp");
+ mC2DDestroySurface = (LINK_c2dDestroySurface)dlsym(mC2DLibHandle, "c2dDestroySurface");
+ mC2DMapAddr = (LINK_c2dMapAddr)dlsym(mC2DLibHandle, "c2dMapAddr");
+ mC2DUnMapAddr = (LINK_c2dUnMapAddr)dlsym(mC2DLibHandle, "c2dUnMapAddr");
+
+ if (!mC2DCreateSurface || !mC2DUpdateSurface || !mC2DReadSurface
+ || !mC2DDraw || !mC2DFlush || !mC2DFinish || !mC2DWaitTimestamp
+ || !mC2DDestroySurface || !mC2DMapAddr || !mC2DUnMapAddr) {
+ ALOGE("%s: dlsym ERROR", __FUNCTION__);
+ mError = -1;
+ return;
+ }
+
+ mAdrenoUtilsHandle = dlopen("libadreno_utils.so", RTLD_NOW);
+ if (!mAdrenoUtilsHandle) {
+ ALOGE("FATAL ERROR: could not dlopen libadreno_utils.so: %s", dlerror());
+ mError = -1;
+ return;
+ }
+
+ mAdrenoComputeAlignedWidthAndHeight = (LINK_AdrenoComputeAlignedWidthAndHeight)dlsym(mAdrenoUtilsHandle, "compute_aligned_width_and_height");
+ if (!mAdrenoComputeAlignedWidthAndHeight) {
+ ALOGE("%s: dlsym ERROR", __FUNCTION__);
+ mError = -1;
+ return;
+ }
+
+ mSrcWidth = srcWidth;
+ mSrcHeight = srcHeight;
+ mSrcStride = srcStride;;
+ mDstWidth = dstWidth;
+ mDstHeight = dstHeight;
+ mSrcFormat = srcFormat;
+ mDstFormat = dstFormat;
+ mSrcSize = calcSize(srcFormat, srcWidth, srcHeight);
+ mDstSize = calcSize(dstFormat, dstWidth, dstHeight);
+ mSrcYSize = calcYSize(srcFormat, srcWidth, srcHeight);
+ mDstYSize = calcYSize(dstFormat, dstWidth, dstHeight);
+
+ mFlags = flags; // can be used for rotation
+
+ mSrcSurfaceDef = getDummySurfaceDef(srcFormat, srcWidth, srcHeight, true);
+ mDstSurfaceDef = getDummySurfaceDef(dstFormat, dstWidth, dstHeight, false);
+
+ memset((void*)&mBlit,0,sizeof(C2D_OBJECT));
+ mBlit.source_rect.x = 0 << 16;
+ mBlit.source_rect.y = 0 << 16;
+ mBlit.source_rect.width = srcWidth << 16;
+ mBlit.source_rect.height = srcHeight << 16;
+ mBlit.target_rect.x = 0 << 16;
+ mBlit.target_rect.y = 0 << 16;
+ mBlit.target_rect.width = dstWidth << 16;
+ mBlit.target_rect.height = dstHeight << 16;
+ mBlit.config_mask = C2D_ALPHA_BLEND_NONE | C2D_NO_BILINEAR_BIT | C2D_NO_ANTIALIASING_BIT | C2D_TARGET_RECT_BIT;
+ mBlit.surface_id = mSrcSurface;
+}
+
+C2DColorConverter::~C2DColorConverter()
+{
+ if (!mError && mC2DLibHandle) {
+
+ mC2DDestroySurface(mDstSurface);
+ mC2DDestroySurface(mSrcSurface);
+ if (isYUVSurface(mSrcFormat)) {
+ delete ((C2D_YUV_SURFACE_DEF *)mSrcSurfaceDef);
+ } else {
+ delete ((C2D_RGB_SURFACE_DEF *)mSrcSurfaceDef);
+ }
+
+ if (isYUVSurface(mDstFormat)) {
+ delete ((C2D_YUV_SURFACE_DEF *)mDstSurfaceDef);
+ } else {
+ delete ((C2D_RGB_SURFACE_DEF *)mDstSurfaceDef);
+ }
+ }
+
+ if (mC2DLibHandle) {
+ dlclose(mC2DLibHandle);
+ }
+ if (mAdrenoUtilsHandle) {
+ dlclose(mAdrenoUtilsHandle);
+ }
+}
+
+int C2DColorConverter::convertC2D(int srcFd, void *srcBase, void * srcData, int dstFd, void *dstBase, void * dstData)
+{
+ C2D_STATUS ret;
+
+ if (mError) {
+ ALOGE("C2D library initialization failed\n");
+ return mError;
+ }
+
+ if ((srcFd < 0) || (dstFd < 0) || (srcData == NULL) || (dstData == NULL)) {
+ ALOGE("Incorrect input parameters\n");
+ return -1;
+ }
+
+ if (isYUVSurface(mSrcFormat)) {
+ ret = updateYUVSurfaceDef(srcFd, srcBase, srcData, true);
+ } else {
+ ret = updateRGBSurfaceDef(srcFd, srcData, true);
+ }
+
+ if (ret != C2D_STATUS_OK) {
+ ALOGE("Update src surface def failed\n");
+ return -ret;
+ }
+
+ if (isYUVSurface(mDstFormat)) {
+ ret = updateYUVSurfaceDef(dstFd, dstBase, dstData, false);
+ } else {
+ ret = updateRGBSurfaceDef(dstFd, dstData, false);
+ }
+
+ if (ret != C2D_STATUS_OK) {
+ ALOGE("Update dst surface def failed\n");
+ return -ret;
+ }
+
+ mBlit.surface_id = mSrcSurface;
+ ret = mC2DDraw(mDstSurface, C2D_TARGET_ROTATE_0, 0, 0, 0, &mBlit, 1);
+ mC2DFinish(mDstSurface);
+
+ bool unmappedSrcSuccess;
+ if (isYUVSurface(mSrcFormat)) {
+ unmappedSrcSuccess = unmapGPUAddr((unsigned long)((C2D_YUV_SURFACE_DEF *)mSrcSurfaceDef)->phys0);
+ } else {
+ unmappedSrcSuccess = unmapGPUAddr((unsigned long)((C2D_RGB_SURFACE_DEF *)mSrcSurfaceDef)->phys);
+ }
+
+ bool unmappedDstSuccess;
+ if (isYUVSurface(mDstFormat)) {
+ unmappedDstSuccess = unmapGPUAddr((unsigned long)((C2D_YUV_SURFACE_DEF *)mDstSurfaceDef)->phys0);
+ } else {
+ unmappedDstSuccess = unmapGPUAddr((unsigned long)((C2D_RGB_SURFACE_DEF *)mDstSurfaceDef)->phys);
+ }
+
+ if (ret != C2D_STATUS_OK) {
+ ALOGE("C2D Draw failed\n");
+ return -ret; //c2d err values are positive
+ } else {
+ if (!unmappedSrcSuccess || !unmappedDstSuccess) {
+ ALOGE("unmapping GPU address failed\n");
+ return -1;
+ }
+ return ret;
+ }
+}
+
+bool C2DColorConverter::isYUVSurface(ColorConvertFormat format)
+{
+ switch (format) {
+ case YCbCr420Tile:
+ case YCbCr420SP:
+ case YCbCr420P:
+ case YCrCb420P:
+ case NV12_2K:
+ case NV12_128m:
+ case NV12_UBWC:
+ return true;
+ case RGB565:
+ case RGBA8888:
+ default:
+ return false;
+ }
+}
+
+void* C2DColorConverter::getDummySurfaceDef(ColorConvertFormat format, size_t width, size_t height, bool isSource)
+{
+ if (isYUVSurface(format)) {
+ C2D_YUV_SURFACE_DEF * surfaceDef = new C2D_YUV_SURFACE_DEF;
+ surfaceDef->format = getC2DFormat(format);
+ surfaceDef->width = width;
+ surfaceDef->height = height;
+ surfaceDef->plane0 = (void *)0xaaaaaaaa;
+ surfaceDef->phys0 = (void *)0xaaaaaaaa;
+ surfaceDef->stride0 = calcStride(format, width);
+ surfaceDef->plane1 = (void *)0xaaaaaaaa;
+ surfaceDef->phys1 = (void *)0xaaaaaaaa;
+ surfaceDef->stride1 = calcStride(format, width);
+ surfaceDef->stride2 = calcStride(format, width);
+ surfaceDef->phys2 = NULL;
+ surfaceDef->plane2 = NULL;
+
+ if (format == YCbCr420P ||
+ format == YCrCb420P) {
+ printf("half stride for Cb Cr planes \n");
+ surfaceDef->stride1 = calcStride(format, width) / 2;
+ surfaceDef->phys2 = (void *)0xaaaaaaaa;
+ surfaceDef->stride2 = calcStride(format, width) / 2;
+ }
+ mC2DCreateSurface(isSource ? &mSrcSurface : &mDstSurface, isSource ? C2D_SOURCE : C2D_TARGET,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY),
+ &(*surfaceDef));
+ return ((void *)surfaceDef);
+ } else {
+ C2D_RGB_SURFACE_DEF * surfaceDef = new C2D_RGB_SURFACE_DEF;
+ surfaceDef->format = getC2DFormat(format);
+ if (mFlags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED)
+ surfaceDef->format |= C2D_FORMAT_UBWC_COMPRESSED;
+ surfaceDef->width = width;
+ surfaceDef->height = height;
+ surfaceDef->buffer = (void *)0xaaaaaaaa;
+ surfaceDef->phys = (void *)0xaaaaaaaa;
+ surfaceDef->stride = calcStride(format, width);
+ mC2DCreateSurface(isSource ? &mSrcSurface : &mDstSurface, isSource ? C2D_SOURCE : C2D_TARGET,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY),
+ &(*surfaceDef));
+ return ((void *)surfaceDef);
+ }
+}
+
+C2D_STATUS C2DColorConverter::updateYUVSurfaceDef(int fd, void *base, void *data, bool isSource)
+{
+ if (isSource) {
+ C2D_YUV_SURFACE_DEF * srcSurfaceDef = (C2D_YUV_SURFACE_DEF *)mSrcSurfaceDef;
+ srcSurfaceDef->plane0 = data;
+ srcSurfaceDef->phys0 = (uint8_t *)getMappedGPUAddr(fd, data, mSrcSize) + ((uint8_t *)data - (uint8_t *)base);
+ srcSurfaceDef->plane1 = (uint8_t *)data + mSrcYSize;
+ srcSurfaceDef->phys1 = (uint8_t *)srcSurfaceDef->phys0 + mSrcYSize;
+ if (srcSurfaceDef->format & C2D_COLOR_FORMAT_420_I420 ||
+ srcSurfaceDef->format & C2D_COLOR_FORMAT_420_YV12) {
+ srcSurfaceDef->plane2 = (uint8_t *)srcSurfaceDef->plane1 + mSrcYSize/4;
+ srcSurfaceDef->phys2 = (uint8_t *)srcSurfaceDef->phys1 + mSrcYSize/4;
+ }
+ return mC2DUpdateSurface(mSrcSurface, C2D_SOURCE,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS),
+ &(*srcSurfaceDef));
+ } else {
+ C2D_YUV_SURFACE_DEF * dstSurfaceDef = (C2D_YUV_SURFACE_DEF *)mDstSurfaceDef;
+ dstSurfaceDef->plane0 = data;
+ dstSurfaceDef->phys0 = (uint8_t *)getMappedGPUAddr(fd, data, mDstSize) + ((uint8_t *)data - (uint8_t *)base);
+ dstSurfaceDef->plane1 = (uint8_t *)data + mDstYSize;
+ dstSurfaceDef->phys1 = (uint8_t *)dstSurfaceDef->phys0 + mDstYSize;
+ if (dstSurfaceDef->format & C2D_COLOR_FORMAT_420_I420 ||
+ dstSurfaceDef->format & C2D_COLOR_FORMAT_420_YV12) {
+ dstSurfaceDef->plane2 = (uint8_t *)dstSurfaceDef->plane1 + mDstYSize/4;
+ dstSurfaceDef->phys2 = (uint8_t *)dstSurfaceDef->phys1 + mDstYSize/4;
+ }
+
+ return mC2DUpdateSurface(mDstSurface, C2D_TARGET,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS),
+ &(*dstSurfaceDef));
+ }
+}
+
+C2D_STATUS C2DColorConverter::updateRGBSurfaceDef(int fd, void * data, bool isSource)
+{
+ if (isSource) {
+ C2D_RGB_SURFACE_DEF * srcSurfaceDef = (C2D_RGB_SURFACE_DEF *)mSrcSurfaceDef;
+ srcSurfaceDef->buffer = data;
+ srcSurfaceDef->phys = getMappedGPUAddr(fd, data, mSrcSize);
+ return mC2DUpdateSurface(mSrcSurface, C2D_SOURCE,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS),
+ &(*srcSurfaceDef));
+ } else {
+ C2D_RGB_SURFACE_DEF * dstSurfaceDef = (C2D_RGB_SURFACE_DEF *)mDstSurfaceDef;
+ dstSurfaceDef->buffer = data;
+ ALOGV("dstSurfaceDef->buffer = %p\n", data);
+ dstSurfaceDef->phys = getMappedGPUAddr(fd, data, mDstSize);
+ return mC2DUpdateSurface(mDstSurface, C2D_TARGET,
+ (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS),
+ &(*dstSurfaceDef));
+ }
+}
+
+uint32_t C2DColorConverter::getC2DFormat(ColorConvertFormat format)
+{
+ switch (format) {
+ case RGB565:
+ return C2D_COLOR_FORMAT_565_RGB;
+ case RGBA8888:
+ return C2D_COLOR_FORMAT_8888_RGBA | C2D_FORMAT_SWAP_ENDIANNESS | C2D_FORMAT_PREMULTIPLIED;
+ case YCbCr420Tile:
+ return (C2D_COLOR_FORMAT_420_NV12 | C2D_FORMAT_MACROTILED);
+ case YCbCr420SP:
+ case NV12_2K:
+ case NV12_128m:
+ return C2D_COLOR_FORMAT_420_NV12;
+ case YCbCr420P:
+ return C2D_COLOR_FORMAT_420_I420;
+ case YCrCb420P:
+ return C2D_COLOR_FORMAT_420_YV12;
+ case NV12_UBWC:
+ return C2D_COLOR_FORMAT_420_NV12 | C2D_FORMAT_UBWC_COMPRESSED;
+ default:
+ ALOGE("Format not supported , %d\n", format);
+ return -1;
+ }
+}
+
+size_t C2DColorConverter::calcStride(ColorConvertFormat format, size_t width)
+{
+ switch (format) {
+ case RGB565:
+ return ALIGN(width, ALIGN32) * 2; // RGB565 has width as twice
+ case RGBA8888:
+ if (mSrcStride)
+ return mSrcStride * 4;
+ else
+ return ALIGN(width, ALIGN32) * 4;
+ case YCbCr420Tile:
+ return ALIGN(width, ALIGN128);
+ case YCbCr420SP:
+ return ALIGN(width, ALIGN16);
+ case NV12_2K:
+ return ALIGN(width, ALIGN16);
+ case NV12_128m:
+ return ALIGN(width, ALIGN128);
+ case YCbCr420P:
+ return ALIGN(width, ALIGN16);
+ case YCrCb420P:
+ return ALIGN(width, ALIGN16);
+ case NV12_UBWC:
+ return VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width);
+ default:
+ return 0;
+ }
+}
+
+size_t C2DColorConverter::calcYSize(ColorConvertFormat format, size_t width, size_t height)
+{
+ switch (format) {
+ case YCbCr420SP:
+ return (ALIGN(width, ALIGN16) * height);
+ case YCbCr420P:
+ return ALIGN(width, ALIGN16) * height;
+ case YCrCb420P:
+ return ALIGN(width, ALIGN16) * height;
+ case YCbCr420Tile:
+ return ALIGN(ALIGN(width, ALIGN128) * ALIGN(height, ALIGN32), ALIGN8K);
+ case NV12_2K: {
+ size_t alignedw = ALIGN(width, ALIGN16);
+ size_t lumaSize = ALIGN(alignedw * height, ALIGN2K);
+ return lumaSize;
+ }
+ case NV12_128m:
+ return ALIGN(width, ALIGN128) * ALIGN(height, ALIGN32);
+ case NV12_UBWC:
+ return ALIGN( VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, width) *
+ VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, height), ALIGN4K) +
+ ALIGN( VENUS_Y_META_STRIDE(COLOR_FMT_NV12_UBWC, width) *
+ VENUS_Y_META_SCANLINES(COLOR_FMT_NV12_UBWC, height), ALIGN4K);
+ default:
+ return 0;
+ }
+}
+
+size_t C2DColorConverter::calcSize(ColorConvertFormat format, size_t width, size_t height)
+{
+ int32_t alignedw = 0;
+ int32_t alignedh = 0;
+ int32_t size = 0;
+ int32_t tile_mode = 0;
+ int32_t raster_mode = 0;
+ int32_t padding_threshold = 512; /* hardcode for RGB formats */
+ int32_t bpp = 0;
+
+ switch (format) {
+ case RGB565:
+ bpp = 2;
+ mAdrenoComputeAlignedWidthAndHeight(width, height, bpp, tile_mode, raster_mode, padding_threshold,
+ &alignedw, &alignedh);
+ size = alignedw * alignedh * bpp;
+ size = ALIGN(size, ALIGN4K);
+ break;
+ case RGBA8888:
+ bpp = 4;
+ mAdrenoComputeAlignedWidthAndHeight(width, height, bpp, tile_mode, raster_mode, padding_threshold,
+ &alignedw, &alignedh);
+ if (mSrcStride)
+ size = mSrcStride * alignedh * bpp;
+ else
+ size = alignedw * alignedh * bpp;
+ size = ALIGN(size, ALIGN4K);
+ break;
+ case YCbCr420SP:
+ alignedw = ALIGN(width, ALIGN16);
+ size = ALIGN((alignedw * height) + (ALIGN(width/2, ALIGN32) * (height/2) * 2), ALIGN4K);
+ break;
+ case YCbCr420P:
+ alignedw = ALIGN(width, ALIGN16);
+ size = ALIGN((alignedw * height) + (ALIGN(width/2, ALIGN16) * (height/2) * 2), ALIGN4K);
+ break;
+ case YCrCb420P:
+ alignedw = ALIGN(width, ALIGN16);
+ size = ALIGN((alignedw * height) + (ALIGN(width/2, ALIGN16) * (height/2) * 2), ALIGN4K);
+ break;
+ case YCbCr420Tile:
+ alignedw = ALIGN(width, ALIGN128);
+ alignedh = ALIGN(height, ALIGN32);
+ size = ALIGN(alignedw * alignedh, ALIGN8K) + ALIGN(alignedw * ALIGN(height/2, ALIGN32), ALIGN8K);
+ break;
+ case NV12_2K: {
+ alignedw = ALIGN(width, ALIGN16);
+ size_t lumaSize = ALIGN(alignedw * height, ALIGN2K);
+ size_t chromaSize = ALIGN((alignedw * height)/2, ALIGN2K);
+ size = ALIGN(lumaSize + chromaSize, ALIGN4K);
+ ALOGV("NV12_2k, width = %zu, height = %zu, size = %d", width, height, size);
+ }
+ break;
+ case NV12_128m:
+ alignedw = ALIGN(width, ALIGN128);
+ alignedh = ALIGN(height, ALIGN32);
+ size = ALIGN(alignedw * alignedh + (alignedw * ALIGN(height/2, ALIGN16)), ALIGN4K);
+ break;
+ case NV12_UBWC:
+ size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12_UBWC, width, height);
+ default:
+ break;
+ }
+ return size;
+}
+/*
+ * Tells GPU to map given buffer and returns a physical address of mapped buffer
+ */
+void * C2DColorConverter::getMappedGPUAddr(int bufFD, void *bufPtr, size_t bufLen)
+{
+ C2D_STATUS status;
+ void *gpuaddr = NULL;
+
+ status = mC2DMapAddr(bufFD, bufPtr, bufLen, 0, KGSL_USER_MEM_TYPE_ION,
+ &gpuaddr);
+ if (status != C2D_STATUS_OK) {
+ ALOGE("c2dMapAddr failed: status %d fd %d ptr %p len %zu flags %d\n",
+ status, bufFD, bufPtr, bufLen, KGSL_USER_MEM_TYPE_ION);
+ return NULL;
+ }
+ ALOGV("c2d mapping created: gpuaddr %p fd %d ptr %p len %zu\n",
+ gpuaddr, bufFD, bufPtr, bufLen);
+
+ return gpuaddr;
+}
+
+bool C2DColorConverter::unmapGPUAddr(unsigned long gAddr)
+{
+
+ C2D_STATUS status = mC2DUnMapAddr((void*)gAddr);
+
+ if (status != C2D_STATUS_OK)
+ ALOGE("c2dUnMapAddr failed: status %d gpuaddr %08lx\n", status, gAddr);
+
+ return (status == C2D_STATUS_OK);
+}
+
+int32_t C2DColorConverter::getBuffReq(int32_t port, C2DBuffReq *req) {
+ if (!req) return -1;
+
+ if (port != C2D_INPUT && port != C2D_OUTPUT) return -1;
+
+ memset(req, 0, sizeof(C2DBuffReq));
+ if (port == C2D_INPUT) {
+ req->width = mSrcWidth;
+ req->height = mSrcHeight;
+ req->stride = calcStride(mSrcFormat, mSrcWidth);
+ req->sliceHeight = mSrcHeight;
+ req->lumaAlign = calcLumaAlign(mSrcFormat);
+ req->sizeAlign = calcSizeAlign(mSrcFormat);
+ req->size = calcSize(mSrcFormat, mSrcWidth, mSrcHeight);
+ req->bpp = calcBytesPerPixel(mSrcFormat);
+ ALOGV("input req->size = %d\n", req->size);
+ } else if (port == C2D_OUTPUT) {
+ req->width = mDstWidth;
+ req->height = mDstHeight;
+ req->stride = calcStride(mDstFormat, mDstWidth);
+ req->sliceHeight = mDstHeight;
+ req->lumaAlign = calcLumaAlign(mDstFormat);
+ req->sizeAlign = calcSizeAlign(mDstFormat);
+ req->size = calcSize(mDstFormat, mDstWidth, mDstHeight);
+ req->bpp = calcBytesPerPixel(mDstFormat);
+ ALOGV("output req->size = %d\n", req->size);
+ }
+ return 0;
+}
+
+size_t C2DColorConverter::calcLumaAlign(ColorConvertFormat format) {
+ if (!isYUVSurface(format)) return 1; //no requirement
+
+ switch (format) {
+ case NV12_2K:
+ return ALIGN2K;
+ case NV12_128m:
+ return 1;
+ case NV12_UBWC:
+ return ALIGN4K;
+ default:
+ ALOGE("unknown format passed for luma alignment number");
+ return 1;
+ }
+}
+
+size_t C2DColorConverter::calcSizeAlign(ColorConvertFormat format) {
+ if (!isYUVSurface(format)) return 1; //no requirement
+
+ switch (format) {
+ case YCbCr420SP: //OR NV12
+ case YCbCr420P:
+ case NV12_2K:
+ case NV12_128m:
+ case NV12_UBWC:
+ return ALIGN4K;
+ default:
+ ALOGE("unknown format passed for size alignment number");
+ return 1;
+ }
+}
+
+C2DBytesPerPixel C2DColorConverter::calcBytesPerPixel(ColorConvertFormat format) {
+ C2DBytesPerPixel bpp;
+ bpp.numerator = 0;
+ bpp.denominator = 1;
+
+ switch (format) {
+ case RGB565:
+ bpp.numerator = 2;
+ break;
+ case RGBA8888:
+ bpp.numerator = 4;
+ break;
+ case YCbCr420SP:
+ case YCbCr420P:
+ case YCrCb420P:
+ case YCbCr420Tile:
+ case NV12_2K:
+ case NV12_128m:
+ case NV12_UBWC:
+ bpp.numerator = 3;
+ bpp.denominator = 2;
+ break;
+ default:
+ break;
+ }
+ return bpp;
+}
+
+int32_t C2DColorConverter::dumpOutput(char * filename, char mode) {
+ int fd;
+ size_t stride, sliceHeight;
+ if (!filename) return -1;
+
+ int flags = O_RDWR | O_CREAT;
+ if (mode == 'a') {
+ flags |= O_APPEND;
+ }
+
+ if ((fd = open(filename, flags)) < 0) {
+ ALOGE("open dump file failed w/ errno %s", strerror(errno));
+ return -1;
+ }
+
+ int ret = 0;
+ if (isYUVSurface(mDstFormat)) {
+ C2D_YUV_SURFACE_DEF * dstSurfaceDef = (C2D_YUV_SURFACE_DEF *)mDstSurfaceDef;
+ uint8_t * base = (uint8_t *)dstSurfaceDef->plane0;
+ stride = dstSurfaceDef->stride0;
+ sliceHeight = dstSurfaceDef->height;
+ /* dump luma */
+ for (size_t i = 0; i < sliceHeight; i++) {
+ ret = write(fd, base, mDstWidth); //will work only for the 420 ones
+ if (ret < 0) goto cleanup;
+ base += stride;
+ }
+
+ if (mDstFormat == YCbCr420P ||
+ mDstFormat == YCrCb420P) {
+ printf("Dump Cb and Cr separately for Planar\n");
+ //dump Cb/Cr
+ base = (uint8_t *)dstSurfaceDef->plane1;
+ stride = dstSurfaceDef->stride1;
+ for (size_t i = 0; i < sliceHeight/2;i++) { //will work only for the 420 ones
+ ret = write(fd, base, mDstWidth/2);
+ if (ret < 0) goto cleanup;
+ base += stride;
+ }
+
+ //dump Cr/Cb
+ base = (uint8_t *)dstSurfaceDef->plane2;
+ stride = dstSurfaceDef->stride2;
+
+ for (size_t i = 0; i < sliceHeight/2;i++) { //will work only for the 420 ones
+ ret = write(fd, base, mDstWidth/2);
+ if (ret < 0) goto cleanup;
+ base += stride;
+ }
+
+ } else {
+ /* dump chroma */
+ base = (uint8_t *)dstSurfaceDef->plane1;
+ stride = dstSurfaceDef->stride1;
+ for (size_t i = 0; i < sliceHeight/2;i++) { //will work only for the 420 ones
+ ret = write(fd, base, mDstWidth);
+ if (ret < 0) goto cleanup;
+ base += stride;
+ }
+ }
+ } else {
+ C2D_RGB_SURFACE_DEF * dstSurfaceDef = (C2D_RGB_SURFACE_DEF *)mDstSurfaceDef;
+ uint8_t * base = (uint8_t *)dstSurfaceDef->buffer;
+ stride = dstSurfaceDef->stride;
+ sliceHeight = dstSurfaceDef->height;
+
+ printf("rgb surface base is %p", base);
+ printf("rgb surface dumpsslice height is %lu\n", (unsigned long)sliceHeight);
+ printf("rgb surface dump stride is %lu\n", (unsigned long)stride);
+
+ int bpp = 1; //bytes per pixel
+ if (mDstFormat == RGB565) {
+ bpp = 2;
+ } else if (mDstFormat == RGBA8888) {
+ bpp = 4;
+ }
+
+ int count = 0;
+ for (size_t i = 0; i < sliceHeight; i++) {
+ ret = write(fd, base, mDstWidth*bpp);
+ if (ret < 0) {
+ printf("write failed, count = %d\n", count);
+ goto cleanup;
+ }
+ base += stride;
+ count += stride;
+ }
+ }
+ cleanup:
+ if (ret < 0) {
+ ALOGE("file write failed w/ errno %s", strerror(errno));
+ }
+ close(fd);
+ return ret < 0 ? ret : 0;
+}
+
+extern "C" C2DColorConverterBase* createC2DColorConverter(size_t srcWidth, size_t srcHeight, size_t dstWidth, size_t dstHeight, ColorConvertFormat srcFormat, ColorConvertFormat dstFormat, int32_t flags, size_t srcStride)
+{
+ return new C2DColorConverter(srcWidth, srcHeight, dstWidth, dstHeight, srcFormat, dstFormat, flags, srcStride);
+}
+
+extern "C" void destroyC2DColorConverter(C2DColorConverterBase* C2DCC)
+{
+ delete C2DCC;
+}
+
+}
diff --git a/msmcobalt/libc2dcolorconvert/C2DColorConverter.h b/msmcobalt/libc2dcolorconvert/C2DColorConverter.h
new file mode 100644
index 0000000..1885f1e
--- /dev/null
+++ b/msmcobalt/libc2dcolorconvert/C2DColorConverter.h
@@ -0,0 +1,121 @@
+/* Copyright (c) 2012 - 2013, 2015 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 C2D_ColorConverter_H_
+#define C2D_ColorConverter_H_
+
+#include <c2d2.h>
+#include <sys/types.h>
+
+typedef C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
+ uint32 surface_bits,
+ C2D_SURFACE_TYPE surface_type,
+ void *surface_definition );
+
+typedef C2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
+ uint32 surface_bits,
+ C2D_SURFACE_TYPE surface_type,
+ void *surface_definition );
+
+typedef C2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
+ C2D_SURFACE_TYPE surface_type,
+ void *surface_definition,
+ int32 x, int32 y );
+
+typedef C2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
+ uint32 target_config, C2D_RECT *target_scissor,
+ uint32 target_mask_id, uint32 target_color_key,
+ C2D_OBJECT *objects_list, uint32 num_objects );
+
+typedef C2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
+
+typedef C2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
+
+typedef C2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
+
+typedef C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
+
+typedef C2D_STATUS (*LINK_c2dMapAddr)( int mem_fd, void * hostptr, uint32 len, uint32 offset, uint32 flags, void ** gpuaddr);
+
+typedef C2D_STATUS (*LINK_c2dUnMapAddr)(void * gpuaddr);
+
+typedef void (*LINK_AdrenoComputeAlignedWidthAndHeight) (int width, int height, int bpp, int tile_mode, int raster_mode,
+ int padding_threshold, int *aligned_width, int * aligned_height);
+
+namespace android {
+
+/*TODO: THIS NEEDS TO ENABLED FOR JB PLUS*/
+enum ColorConvertFormat {
+ RGB565 = 1,
+ YCbCr420Tile,
+ YCbCr420SP,
+ YCbCr420P,
+ YCrCb420P,
+ RGBA8888,
+ NV12_2K,
+ NV12_128m,
+ NV12_UBWC,
+};
+
+typedef struct {
+ int32_t numerator;
+ int32_t denominator;
+} C2DBytesPerPixel;
+
+typedef struct {
+ int32_t width;
+ int32_t height;
+ int32_t stride;
+ int32_t sliceHeight;
+ int32_t lumaAlign;
+ int32_t sizeAlign;
+ int32_t size;
+ C2DBytesPerPixel bpp;
+} C2DBuffReq;
+
+typedef enum {
+ C2D_INPUT = 0,
+ C2D_OUTPUT,
+} C2D_PORT;
+
+class C2DColorConverterBase {
+
+public:
+ virtual ~C2DColorConverterBase(){};
+ virtual int convertC2D(int srcFd, void *srcBase, void * srcData, int dstFd, void *dstBase, void * dstData) = 0;
+ virtual int32_t getBuffReq(int32_t port, C2DBuffReq *req) = 0;
+ virtual int32_t dumpOutput(char * filename, char mode) = 0;
+};
+
+typedef C2DColorConverterBase* createC2DColorConverter_t(size_t srcWidth, size_t srcHeight, size_t dstWidth, size_t dstHeight, ColorConvertFormat srcFormat, ColorConvertFormat dstFormat, int32_t flags, size_t srcStride);
+typedef void destroyC2DColorConverter_t(C2DColorConverterBase*);
+
+}
+
+#endif // C2D_ColorConverter_H_
diff --git a/msmcobalt/libstagefrighthw/Android.mk b/msmcobalt/libstagefrighthw/Android.mk
new file mode 100644
index 0000000..2e6a94c
--- /dev/null
+++ b/msmcobalt/libstagefrighthw/Android.mk
@@ -0,0 +1,56 @@
+#
+# Copyright (C) 2009 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+#===============================================================================
+# Deploy the headers that can be exposed
+#===============================================================================
+
+LOCAL_COPY_HEADERS_TO := mm-core/omxcore
+LOCAL_COPY_HEADERS := QComOMXMetadata.h \
+ QComOMXPlugin.h
+
+LOCAL_SRC_FILES := \
+ QComOMXPlugin.cpp \
+
+LOCAL_CFLAGS := $(PV_CFLAGS_MINUS_VISIBILITY)
+
+ifeq ($(PLATFORM_SDK_VERSION), 18) #JB_MR2
+LOCAL_CFLAGS += -DANDROID_JELLYBEAN_MR2=1
+endif
+
+ifeq ($(TARGET_USES_MEDIA_EXTENSIONS),true)
+LOCAL_CFLAGS += -DUSE_NATIVE_HANDLE_SOURCE
+endif
+
+LOCAL_C_INCLUDES:= \
+ frameworks/native/include/media/openmax \
+ $(TARGET_OUT_HEADERS)/mm-core/omxcore/ \
+ frameworks/native/include/media/hardware
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libutils \
+ libcutils \
+ libdl \
+ libui \
+
+LOCAL_MODULE := libstagefrighthw
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/msmcobalt/libstagefrighthw/MODULE_LICENSE_APACHE2 b/msmcobalt/libstagefrighthw/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/msmcobalt/libstagefrighthw/MODULE_LICENSE_APACHE2
diff --git a/msmcobalt/libstagefrighthw/NOTICE b/msmcobalt/libstagefrighthw/NOTICE
new file mode 100644
index 0000000..a94ca1f
--- /dev/null
+++ b/msmcobalt/libstagefrighthw/NOTICE
@@ -0,0 +1,189 @@
+ Copyright (c) 2009, The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/msmcobalt/libstagefrighthw/QComOMXMetadata.h b/msmcobalt/libstagefrighthw/QComOMXMetadata.h
new file mode 100644
index 0000000..e6b4579
--- /dev/null
+++ b/msmcobalt/libstagefrighthw/QComOMXMetadata.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2011-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef QCOM_OMX_METADATA_H_
+#define QCOM_OMX_METADATA_H_
+
+#include <system/window.h>
+#include <media/hardware/MetadataBufferType.h>
+
+namespace android {
+
+#ifdef USE_NATIVE_HANDLE_SOURCE
+ typedef struct encoder_nativehandle_buffer_type {
+ MetadataBufferType buffer_type;
+ buffer_handle_t meta_handle;
+ } encoder_nativehandle_buffer_type;
+#endif
+
+ typedef struct encoder_media_buffer_type {
+ MetadataBufferType buffer_type;
+ buffer_handle_t meta_handle;
+ } encoder_media_buffer_type;
+
+#ifdef ANDROID_JELLYBEAN_MR2
+ // Meta data buffer layout used to transport output frames to the decoder for
+ // dynamic buffer handling.
+ struct VideoDecoderOutputMetaData {
+ MetadataBufferType eType;
+ buffer_handle_t pHandle;
+ };
+#endif
+}
+
+#endif
diff --git a/msmcobalt/libstagefrighthw/QComOMXPlugin.cpp b/msmcobalt/libstagefrighthw/QComOMXPlugin.cpp
new file mode 100644
index 0000000..7f8933b
--- /dev/null
+++ b/msmcobalt/libstagefrighthw/QComOMXPlugin.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "QComOMXPlugin.h"
+
+#include <dlfcn.h>
+
+#include <media/hardware/HardwareAPI.h>
+
+namespace android {
+
+OMXPluginBase *createOMXPlugin() {
+ return new QComOMXPlugin;
+}
+
+QComOMXPlugin::QComOMXPlugin()
+ : mLibHandle(dlopen("libOmxCore.so", RTLD_NOW)),
+ mInit(NULL),
+ mDeinit(NULL),
+ mComponentNameEnum(NULL),
+ mGetHandle(NULL),
+ mFreeHandle(NULL),
+ mGetRolesOfComponentHandle(NULL) {
+ if (mLibHandle != NULL) {
+ mInit = (InitFunc)dlsym(mLibHandle, "OMX_Init");
+ mDeinit = (DeinitFunc)dlsym(mLibHandle, "OMX_Deinit");
+
+ mComponentNameEnum =
+ (ComponentNameEnumFunc)dlsym(mLibHandle, "OMX_ComponentNameEnum");
+
+ mGetHandle = (GetHandleFunc)dlsym(mLibHandle, "OMX_GetHandle");
+ mFreeHandle = (FreeHandleFunc)dlsym(mLibHandle, "OMX_FreeHandle");
+
+ mGetRolesOfComponentHandle =
+ (GetRolesOfComponentFunc)dlsym(
+ mLibHandle, "OMX_GetRolesOfComponent");
+
+ if (!mInit || !mDeinit || !mComponentNameEnum || !mGetHandle ||
+ !mFreeHandle || !mGetRolesOfComponentHandle) {
+ dlclose(mLibHandle);
+ mLibHandle = NULL;
+ } else
+ (*mInit)();
+ }
+}
+
+QComOMXPlugin::~QComOMXPlugin() {
+ if (mLibHandle != NULL) {
+ (*mDeinit)();
+
+ dlclose(mLibHandle);
+ mLibHandle = NULL;
+ }
+}
+
+OMX_ERRORTYPE QComOMXPlugin::makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component) {
+ if (mLibHandle == NULL) {
+ return OMX_ErrorUndefined;
+ }
+
+ return (*mGetHandle)(
+ reinterpret_cast<OMX_HANDLETYPE *>(component),
+ const_cast<char *>(name),
+ appData, const_cast<OMX_CALLBACKTYPE *>(callbacks));
+}
+
+OMX_ERRORTYPE QComOMXPlugin::destroyComponentInstance(
+ OMX_COMPONENTTYPE *component) {
+ if (mLibHandle == NULL) {
+ return OMX_ErrorUndefined;
+ }
+
+ return (*mFreeHandle)(reinterpret_cast<OMX_HANDLETYPE *>(component));
+}
+
+OMX_ERRORTYPE QComOMXPlugin::enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index) {
+ if (mLibHandle == NULL) {
+ return OMX_ErrorUndefined;
+ }
+
+ return (*mComponentNameEnum)(name, size, index);
+}
+
+OMX_ERRORTYPE QComOMXPlugin::getRolesOfComponent(
+ const char *name,
+ Vector<String8> *roles) {
+ roles->clear();
+
+ if (mLibHandle == NULL) {
+ return OMX_ErrorUndefined;
+ }
+
+ OMX_U32 numRoles;
+ OMX_ERRORTYPE err = (*mGetRolesOfComponentHandle)(
+ const_cast<OMX_STRING>(name), &numRoles, NULL);
+
+ if (err != OMX_ErrorNone) {
+ return err;
+ }
+
+ if (numRoles > 0) {
+ OMX_U8 **array = new OMX_U8 *[numRoles];
+ for (OMX_U32 i = 0; i < numRoles; ++i) {
+ array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
+ }
+
+ OMX_U32 numRoles2;
+ err = (*mGetRolesOfComponentHandle)(
+ const_cast<OMX_STRING>(name), &numRoles2, array);
+
+ if (err != OMX_ErrorNone) {
+ return err;
+ }
+
+ if (numRoles2 != numRoles) {
+ return err;
+ }
+
+ for (OMX_U32 i = 0; i < numRoles; ++i) {
+ String8 s((const char *)array[i]);
+ roles->push(s);
+
+ delete[] array[i];
+ array[i] = NULL;
+ }
+
+ delete[] array;
+ array = NULL;
+ }
+
+ return OMX_ErrorNone;
+}
+
+} // namespace android
diff --git a/msmcobalt/libstagefrighthw/QComOMXPlugin.h b/msmcobalt/libstagefrighthw/QComOMXPlugin.h
new file mode 100644
index 0000000..fc623e3
--- /dev/null
+++ b/msmcobalt/libstagefrighthw/QComOMXPlugin.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef QCOM_OMX_PLUGIN_H_
+
+#define QCOM_OMX_PLUGIN_H_
+
+#include <media/hardware/OMXPluginBase.h>
+
+namespace android {
+
+struct QComOMXPlugin : public OMXPluginBase {
+ QComOMXPlugin();
+ virtual ~QComOMXPlugin();
+
+ virtual OMX_ERRORTYPE makeComponentInstance(
+ const char *name,
+ const OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData,
+ OMX_COMPONENTTYPE **component);
+
+ virtual OMX_ERRORTYPE destroyComponentInstance(
+ OMX_COMPONENTTYPE *component);
+
+ virtual OMX_ERRORTYPE enumerateComponents(
+ OMX_STRING name,
+ size_t size,
+ OMX_U32 index);
+
+ virtual OMX_ERRORTYPE getRolesOfComponent(
+ const char *name,
+ Vector<String8> *roles);
+
+private:
+ void *mLibHandle;
+
+ typedef OMX_ERRORTYPE (*InitFunc)();
+ typedef OMX_ERRORTYPE (*DeinitFunc)();
+ typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)(
+ OMX_STRING, OMX_U32, OMX_U32);
+
+ typedef OMX_ERRORTYPE (*GetHandleFunc)(
+ OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *);
+
+ typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE *);
+
+ typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)(
+ OMX_STRING, OMX_U32 *, OMX_U8 **);
+
+ InitFunc mInit;
+ DeinitFunc mDeinit;
+ ComponentNameEnumFunc mComponentNameEnum;
+ GetHandleFunc mGetHandle;
+ FreeHandleFunc mFreeHandle;
+ GetRolesOfComponentFunc mGetRolesOfComponentHandle;
+
+ QComOMXPlugin(const QComOMXPlugin &);
+ QComOMXPlugin &operator=(const QComOMXPlugin &);
+};
+
+} // namespace android
+
+#endif // QCOM_OMX_PLUGIN_H_
diff --git a/msmcobalt/mm-core/Android.mk b/msmcobalt/mm-core/Android.mk
new file mode 100644
index 0000000..8934a48
--- /dev/null
+++ b/msmcobalt/mm-core/Android.mk
@@ -0,0 +1,137 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+OMXCORE_CFLAGS := -g -O3 -DVERBOSE
+OMXCORE_CFLAGS += -O0 -fno-inline -fno-short-enums
+OMXCORE_CFLAGS += -D_ANDROID_
+OMXCORE_CFLAGS += -U_ENABLE_QC_MSG_LOG_
+
+#===============================================================================
+# Figure out the targets
+#===============================================================================
+
+ifeq ($(TARGET_BOARD_PLATFORM),msm7627a)
+MM_CORE_TARGET = 7627A
+else ifeq ($(TARGET_BOARD_PLATFORM),msm7630_surf)
+MM_CORE_TARGET = 7630
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8660)
+MM_CORE_TARGET = 8660
+#Comment out following line to disable drm.play component
+OMXCORE_CFLAGS += -DENABLE_DRMPLAY
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8960)
+MM_CORE_TARGET = 8960
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8974)
+MM_CORE_TARGET = 8974
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8610)
+MM_CORE_TARGET = 8610
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8226)
+MM_CORE_TARGET = 8226
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8916)
+MM_CORE_TARGET = 8916
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8909)
+MM_CORE_TARGET = 8909
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8937)
+MM_CORE_TARGET = 8937
+else ifeq ($(TARGET_BOARD_PLATFORM),apq8084)
+MM_CORE_TARGET = 8084
+else ifeq ($(TARGET_BOARD_PLATFORM),mpq8092)
+MM_CORE_TARGET = 8092
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8992)
+MM_CORE_TARGET = msm8992
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8994)
+MM_CORE_TARGET = msm8994
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8996)
+MM_CORE_TARGET = msm8996
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8952)
+MM_CORE_TARGET = 8952
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8953)
+MM_CORE_TARGET = msm8953
+else ifeq ($(TARGET_BOARD_PLATFORM),msmcobalt)
+MM_CORE_TARGET = msmcobalt
+else
+MM_CORE_TARGET = default
+endif
+
+#===============================================================================
+# Deploy the headers that can be exposed
+#===============================================================================
+
+LOCAL_COPY_HEADERS_TO := mm-core/omxcore
+LOCAL_COPY_HEADERS := inc/OMX_Audio.h
+LOCAL_COPY_HEADERS += inc/OMX_Component.h
+LOCAL_COPY_HEADERS += inc/OMX_ContentPipe.h
+LOCAL_COPY_HEADERS += inc/OMX_Core.h
+LOCAL_COPY_HEADERS += inc/OMX_Image.h
+LOCAL_COPY_HEADERS += inc/OMX_Index.h
+LOCAL_COPY_HEADERS += inc/OMX_IVCommon.h
+LOCAL_COPY_HEADERS += inc/OMX_Other.h
+LOCAL_COPY_HEADERS += inc/OMX_QCOMExtns.h
+LOCAL_COPY_HEADERS += inc/OMX_Types.h
+LOCAL_COPY_HEADERS += inc/OMX_Video.h
+LOCAL_COPY_HEADERS += inc/qc_omx_common.h
+LOCAL_COPY_HEADERS += inc/qc_omx_component.h
+LOCAL_COPY_HEADERS += inc/qc_omx_msg.h
+LOCAL_COPY_HEADERS += inc/QOMX_AudioExtensions.h
+LOCAL_COPY_HEADERS += inc/QOMX_AudioIndexExtensions.h
+LOCAL_COPY_HEADERS += inc/OMX_CoreExt.h
+LOCAL_COPY_HEADERS += inc/QOMX_CoreExtensions.h
+LOCAL_COPY_HEADERS += inc/QOMX_FileFormatExtensions.h
+LOCAL_COPY_HEADERS += inc/QOMX_IVCommonExtensions.h
+LOCAL_COPY_HEADERS += inc/QOMX_SourceExtensions.h
+LOCAL_COPY_HEADERS += inc/QOMX_VideoExtensions.h
+LOCAL_COPY_HEADERS += inc/OMX_IndexExt.h
+LOCAL_COPY_HEADERS += inc/OMX_VideoExt.h
+LOCAL_COPY_HEADERS += inc/QOMX_StreamingExtensions.h
+LOCAL_COPY_HEADERS += inc/QCMediaDefs.h
+LOCAL_COPY_HEADERS += inc/QCMetaData.h
+LOCAL_COPY_HEADERS += inc/OMX_Skype_VideoExtensions.h
+
+#===============================================================================
+# LIBRARY for Android apps
+#===============================================================================
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/common
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/inc
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libOmxCore
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := liblog libdl libcutils
+LOCAL_CFLAGS := $(OMXCORE_CFLAGS)
+
+LOCAL_SRC_FILES := src/common/omx_core_cmp.cpp
+LOCAL_SRC_FILES += src/common/qc_omx_core.c
+ifneq (,$(filter msm8916 msm8994 msm8909 msm8937 msm8996 msm8992 msm8952 msm8953 msmcobalt,$(TARGET_BOARD_PLATFORM)))
+LOCAL_SRC_FILES += src/$(MM_CORE_TARGET)/registry_table_android.c
+else
+LOCAL_SRC_FILES += src/$(MM_CORE_TARGET)/qc_registry_table_android.c
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+#===============================================================================
+# LIBRARY for command line test apps
+#===============================================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/src/common
+LOCAL_C_INCLUDES += $(LOCAL_PATH)/inc
+LOCAL_PRELINK_MODULE := false
+LOCAL_MODULE := libmm-omxcore
+LOCAL_MODULE_TAGS := optional
+LOCAL_SHARED_LIBRARIES := liblog libdl libcutils
+LOCAL_CFLAGS := $(OMXCORE_CFLAGS)
+
+LOCAL_SRC_FILES := src/common/omx_core_cmp.cpp
+LOCAL_SRC_FILES += src/common/qc_omx_core.c
+ifneq (,$(filter msm8916 msm8994 msm8909 msm8937 msm8996 msm8992 msm8952 msm8953 msmcobalt,$(TARGET_BOARD_PLATFORM)))
+LOCAL_SRC_FILES += src/$(MM_CORE_TARGET)/registry_table.c
+else
+LOCAL_SRC_FILES += src/$(MM_CORE_TARGET)/qc_registry_table.c
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif #BUILD_TINY_ANDROID
diff --git a/msmcobalt/mm-core/inc/OMX_Audio.h b/msmcobalt/mm-core/inc/OMX_Audio.h
new file mode 100644
index 0000000..1d0ef1c
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Audio.h
@@ -0,0 +1,1321 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_Audio.h - OpenMax IL version 1.1.2
+ * The structures needed by Audio components to exchange
+ * parameters and configuration data with the componenmilts.
+ */
+
+#ifndef OMX_Audio_h
+#define OMX_Audio_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_Core.h>
+
+/** @defgroup midi MIDI
+ * @ingroup audio
+ */
+
+/** @defgroup effects Audio effects
+ * @ingroup audio
+ */
+
+/** @defgroup audio OpenMAX IL Audio Domain
+ * Structures for OpenMAX IL Audio domain
+ * @{
+ */
+
+/** Enumeration used to define the possible audio codings.
+ * If "OMX_AUDIO_CodingUnused" is selected, the coding selection must
+ * be done in a vendor specific way. Since this is for an audio
+ * processing element this enum is relevant. However, for another
+ * type of component other enums would be in this area.
+ */
+typedef enum OMX_AUDIO_CODINGTYPE {
+ OMX_AUDIO_CodingUnused = 0, /**< Placeholder value when coding is N/A */
+ OMX_AUDIO_CodingAutoDetect, /**< auto detection of audio format */
+ OMX_AUDIO_CodingPCM, /**< Any variant of PCM coding */
+ OMX_AUDIO_CodingADPCM, /**< Any variant of ADPCM encoded data */
+ OMX_AUDIO_CodingAMR, /**< Any variant of AMR encoded data */
+ OMX_AUDIO_CodingGSMFR, /**< Any variant of GSM fullrate (i.e. GSM610) */
+ OMX_AUDIO_CodingGSMEFR, /**< Any variant of GSM Enhanced Fullrate encoded data*/
+ OMX_AUDIO_CodingGSMHR, /**< Any variant of GSM Halfrate encoded data */
+ OMX_AUDIO_CodingPDCFR, /**< Any variant of PDC Fullrate encoded data */
+ OMX_AUDIO_CodingPDCEFR, /**< Any variant of PDC Enhanced Fullrate encoded data */
+ OMX_AUDIO_CodingPDCHR, /**< Any variant of PDC Halfrate encoded data */
+ OMX_AUDIO_CodingTDMAFR, /**< Any variant of TDMA Fullrate encoded data (TIA/EIA-136-420) */
+ OMX_AUDIO_CodingTDMAEFR, /**< Any variant of TDMA Enhanced Fullrate encoded data (TIA/EIA-136-410) */
+ OMX_AUDIO_CodingQCELP8, /**< Any variant of QCELP 8kbps encoded data */
+ OMX_AUDIO_CodingQCELP13, /**< Any variant of QCELP 13kbps encoded data */
+ OMX_AUDIO_CodingEVRC, /**< Any variant of EVRC encoded data */
+ OMX_AUDIO_CodingSMV, /**< Any variant of SMV encoded data */
+ OMX_AUDIO_CodingG711, /**< Any variant of G.711 encoded data */
+ OMX_AUDIO_CodingG723, /**< Any variant of G.723 dot 1 encoded data */
+ OMX_AUDIO_CodingG726, /**< Any variant of G.726 encoded data */
+ OMX_AUDIO_CodingG729, /**< Any variant of G.729 encoded data */
+ OMX_AUDIO_CodingAAC, /**< Any variant of AAC encoded data */
+ OMX_AUDIO_CodingMP3, /**< Any variant of MP3 encoded data */
+ OMX_AUDIO_CodingSBC, /**< Any variant of SBC encoded data */
+ OMX_AUDIO_CodingVORBIS, /**< Any variant of VORBIS encoded data */
+ OMX_AUDIO_CodingWMA, /**< Any variant of WMA encoded data */
+ OMX_AUDIO_CodingRA, /**< Any variant of RA encoded data */
+ OMX_AUDIO_CodingMIDI, /**< Any variant of MIDI encoded data */
+ OMX_AUDIO_CodingAC3, /**< Any variant of AC3 encoded data */
+ OMX_AUDIO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_CodingMax = 0x7FFFFFFF
+} OMX_AUDIO_CODINGTYPE;
+
+
+/** The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output audio
+ * path. If additional information is needed to define the parameters of the
+ * port (such as frequency), additional structures must be sent such as the
+ * OMX_AUDIO_PARAM_PCMMODETYPE structure to supply the extra parameters for the port.
+ */
+typedef struct OMX_AUDIO_PORTDEFINITIONTYPE {
+ OMX_STRING cMIMEType; /**< MIME type of data for the port */
+ OMX_NATIVE_DEVICETYPE pNativeRender; /** < platform specific reference
+ for an output device,
+ otherwise this field is 0 */
+ OMX_BOOL bFlagErrorConcealment; /**< Turns on error concealment if it is
+ supported by the OMX component */
+ OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this
+ port (e.g. PCM, AMR, MP3, etc) */
+} OMX_AUDIO_PORTDEFINITIONTYPE;
+
+
+/** Port format parameter. This structure is used to enumerate
+ * the various data input/output format supported by the port.
+ */
+typedef struct OMX_AUDIO_PARAM_PORTFORMATTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Indicates which port to set */
+ OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */
+ OMX_AUDIO_CODINGTYPE eEncoding; /**< Type of data expected for this port (e.g. PCM, AMR, MP3, etc) */
+} OMX_AUDIO_PARAM_PORTFORMATTYPE;
+
+
+/** PCM mode type */
+typedef enum OMX_AUDIO_PCMMODETYPE {
+ OMX_AUDIO_PCMModeLinear = 0, /**< Linear PCM encoded data */
+ OMX_AUDIO_PCMModeALaw, /**< A law PCM encoded data (G.711) */
+ OMX_AUDIO_PCMModeMULaw, /**< Mu law PCM encoded data (G.711) */
+ OMX_AUDIO_PCMModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_PCMModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_PCMModeMax = 0x7FFFFFFF
+} OMX_AUDIO_PCMMODETYPE;
+
+
+typedef enum OMX_AUDIO_CHANNELTYPE {
+ OMX_AUDIO_ChannelNone = 0x0, /**< Unused or empty */
+ OMX_AUDIO_ChannelLF = 0x1, /**< Left front */
+ OMX_AUDIO_ChannelRF = 0x2, /**< Right front */
+ OMX_AUDIO_ChannelCF = 0x3, /**< Center front */
+ OMX_AUDIO_ChannelLS = 0x4, /**< Left surround */
+ OMX_AUDIO_ChannelRS = 0x5, /**< Right surround */
+ OMX_AUDIO_ChannelLFE = 0x6, /**< Low frequency effects */
+ OMX_AUDIO_ChannelCS = 0x7, /**< Back surround */
+ OMX_AUDIO_ChannelLR = 0x8, /**< Left rear. */
+ OMX_AUDIO_ChannelRR = 0x9, /**< Right rear. */
+ OMX_AUDIO_ChannelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_ChannelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_ChannelMax = 0x7FFFFFFF
+} OMX_AUDIO_CHANNELTYPE;
+
+#define OMX_AUDIO_MAXCHANNELS 16 /**< maximum number distinct audio channels that a buffer may contain */
+#define OMX_MIN_PCMPAYLOAD_MSEC 5 /**< Minimum audio buffer payload size for uncompressed (PCM) audio */
+
+/** PCM format description */
+typedef struct OMX_AUDIO_PARAM_PCMMODETYPE {
+ OMX_U32 nSize; /**< Size of this structure, in Bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels (e.g. 2 for stereo) */
+ OMX_NUMERICALDATATYPE eNumData; /**< indicates PCM data as signed or unsigned */
+ OMX_ENDIANTYPE eEndian; /**< indicates PCM data as little or big endian */
+ OMX_BOOL bInterleaved; /**< True for normal interleaved data; false for
+ non-interleaved data (e.g. block data) */
+ OMX_U32 nBitPerSample; /**< Bit per sample */
+ OMX_U32 nSamplingRate; /**< Sampling rate of the source data. Use 0 for
+ variable or unknown sampling rate. */
+ OMX_AUDIO_PCMMODETYPE ePCMMode; /**< PCM mode enumeration */
+ OMX_AUDIO_CHANNELTYPE eChannelMapping[OMX_AUDIO_MAXCHANNELS]; /**< Slot i contains channel defined by eChannelMap[i] */
+
+} OMX_AUDIO_PARAM_PCMMODETYPE;
+
+
+/** Audio channel mode. This is used by both AAC and MP3, although the names are more appropriate
+ * for the MP3. For example, JointStereo for MP3 is CouplingChannels for AAC.
+ */
+typedef enum OMX_AUDIO_CHANNELMODETYPE {
+ OMX_AUDIO_ChannelModeStereo = 0, /**< 2 channels, the bitrate allocation between those
+ two channels changes accordingly to each channel information */
+ OMX_AUDIO_ChannelModeJointStereo, /**< mode that takes advantage of what is common between
+ 2 channels for higher compression gain */
+ OMX_AUDIO_ChannelModeDual, /**< 2 mono-channels, each channel is encoded with half
+ the bitrate of the overall bitrate */
+ OMX_AUDIO_ChannelModeMono, /**< Mono channel mode */
+ OMX_AUDIO_ChannelModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_ChannelModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_ChannelModeMax = 0x7FFFFFFF
+} OMX_AUDIO_CHANNELMODETYPE;
+
+
+typedef enum OMX_AUDIO_MP3STREAMFORMATTYPE {
+ OMX_AUDIO_MP3StreamFormatMP1Layer3 = 0, /**< MP3 Audio MPEG 1 Layer 3 Stream format */
+ OMX_AUDIO_MP3StreamFormatMP2Layer3, /**< MP3 Audio MPEG 2 Layer 3 Stream format */
+ OMX_AUDIO_MP3StreamFormatMP2_5Layer3, /**< MP3 Audio MPEG2.5 Layer 3 Stream format */
+ OMX_AUDIO_MP3StreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_MP3StreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_MP3StreamFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_MP3STREAMFORMATTYPE;
+
+/** MP3 params */
+typedef struct OMX_AUDIO_PARAM_MP3TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels */
+ OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable
+ rate or unknown bit rates */
+ OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for
+ variable or unknown sampling rate. */
+ OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should
+ limit the audio signal. Use 0 to let encoder decide */
+ OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */
+ OMX_AUDIO_MP3STREAMFORMATTYPE eFormat; /**< MP3 stream format */
+} OMX_AUDIO_PARAM_MP3TYPE;
+
+
+typedef enum OMX_AUDIO_AACSTREAMFORMATTYPE {
+ OMX_AUDIO_AACStreamFormatMP2ADTS = 0, /**< AAC Audio Data Transport Stream 2 format */
+ OMX_AUDIO_AACStreamFormatMP4ADTS, /**< AAC Audio Data Transport Stream 4 format */
+ OMX_AUDIO_AACStreamFormatMP4LOAS, /**< AAC Low Overhead Audio Stream format */
+ OMX_AUDIO_AACStreamFormatMP4LATM, /**< AAC Low overhead Audio Transport Multiplex */
+ OMX_AUDIO_AACStreamFormatADIF, /**< AAC Audio Data Interchange Format */
+ OMX_AUDIO_AACStreamFormatMP4FF, /**< AAC inside MPEG-4/ISO File Format */
+ OMX_AUDIO_AACStreamFormatRAW, /**< AAC Raw Format */
+ OMX_AUDIO_AACStreamFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_AACStreamFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_AACStreamFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_AACSTREAMFORMATTYPE;
+
+
+/** AAC mode type. Note that the term profile is used with the MPEG-2
+ * standard and the term object type and profile is used with MPEG-4 */
+typedef enum OMX_AUDIO_AACPROFILETYPE{
+ OMX_AUDIO_AACObjectNull = 0, /**< Null, not used */
+ OMX_AUDIO_AACObjectMain = 1, /**< AAC Main object */
+ OMX_AUDIO_AACObjectLC, /**< AAC Low Complexity object (AAC profile) */
+ OMX_AUDIO_AACObjectSSR, /**< AAC Scalable Sample Rate object */
+ OMX_AUDIO_AACObjectLTP, /**< AAC Long Term Prediction object */
+ OMX_AUDIO_AACObjectHE, /**< AAC High Efficiency (object type SBR, HE-AAC profile) */
+ OMX_AUDIO_AACObjectScalable, /**< AAC Scalable object */
+ OMX_AUDIO_AACObjectERLC = 17, /**< ER AAC Low Complexity object (Error Resilient AAC-LC) */
+ OMX_AUDIO_AACObjectLD = 23, /**< AAC Low Delay object (Error Resilient) */
+ OMX_AUDIO_AACObjectHE_PS = 29, /**< AAC High Efficiency with Parametric Stereo coding (HE-AAC v2, object type PS) */
+ OMX_AUDIO_AACObjectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_AACObjectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_AACObjectMax = 0x7FFFFFFF
+} OMX_AUDIO_AACPROFILETYPE;
+
+
+/** AAC tool usage (for nAACtools in OMX_AUDIO_PARAM_AACPROFILETYPE).
+ * Required for encoder configuration and optional as decoder info output.
+ * For MP3, OMX_AUDIO_CHANNELMODETYPE is sufficient. */
+#define OMX_AUDIO_AACToolNone 0x00000000 /**< no AAC tools allowed (encoder config) or active (decoder info output) */
+#define OMX_AUDIO_AACToolMS 0x00000001 /**< MS: Mid/side joint coding tool allowed or active */
+#define OMX_AUDIO_AACToolIS 0x00000002 /**< IS: Intensity stereo tool allowed or active */
+#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */
+#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */
+#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */
+#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/
+
+/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE).
+ * Required for ER encoder configuration and optional as decoder info output */
+#define OMX_AUDIO_AACERNone 0x00000000 /**< no AAC ER tools allowed/used */
+#define OMX_AUDIO_AACERVCB11 0x00000001 /**< VCB11: Virtual Code Books for AAC section data */
+#define OMX_AUDIO_AACERRVLC 0x00000002 /**< RVLC: Reversible Variable Length Coding */
+#define OMX_AUDIO_AACERHCR 0x00000004 /**< HCR: Huffman Codeword Reordering */
+#define OMX_AUDIO_AACERAll 0x7FFFFFFF /**< all AAC ER tools allowed/used */
+
+
+/** AAC params */
+typedef struct OMX_AUDIO_PARAM_AACPROFILETYPE {
+ OMX_U32 nSize; /**< Size of this structure, in Bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels */
+ OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for
+ variable or unknown sampling rate. */
+ OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable
+ rate or unknown bit rates */
+ OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should
+ limit the audio signal. Use 0 to let encoder decide */
+ OMX_U32 nFrameLength; /**< Frame length (in audio samples per channel) of the codec.
+ Can be 1024 or 960 (AAC-LC), 2048 (HE-AAC), 480 or 512 (AAC-LD).
+ Use 0 to let encoder decide */
+ OMX_U32 nAACtools; /**< AAC tool usage */
+ OMX_U32 nAACERtools; /**< MPEG-4 AAC error resilience tool usage */
+ OMX_AUDIO_AACPROFILETYPE eAACProfile; /**< AAC profile enumeration */
+ OMX_AUDIO_AACSTREAMFORMATTYPE eAACStreamFormat; /**< AAC stream format enumeration */
+ OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */
+} OMX_AUDIO_PARAM_AACPROFILETYPE;
+
+
+/** VORBIS params */
+typedef struct OMX_AUDIO_PARAM_VORBISTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels */
+ OMX_U32 nBitRate; /**< Bit rate of the encoded data data. Use 0 for variable
+ rate or unknown bit rates. Encoding is set to the
+ bitrate closest to specified value (in bps) */
+ OMX_U32 nMinBitRate; /**< Sets minimum bitrate (in bps). */
+ OMX_U32 nMaxBitRate; /**< Sets maximum bitrate (in bps). */
+
+ OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for
+ variable or unknown sampling rate. */
+ OMX_U32 nAudioBandWidth; /**< Audio band width (in Hz) to which an encoder should
+ limit the audio signal. Use 0 to let encoder decide */
+ OMX_S32 nQuality; /**< Sets encoding quality to n, between -1 (low) and 10 (high).
+ In the default mode of operation, teh quality level is 3.
+ Normal quality range is 0 - 10. */
+ OMX_BOOL bManaged; /**< Set bitrate management mode. This turns off the
+ normal VBR encoding, but allows hard or soft bitrate
+ constraints to be enforced by the encoder. This mode can
+ be slower, and may also be lower quality. It is
+ primarily useful for streaming. */
+ OMX_BOOL bDownmix; /**< Downmix input from stereo to mono (has no effect on
+ non-stereo streams). Useful for lower-bitrate encoding. */
+} OMX_AUDIO_PARAM_VORBISTYPE;
+
+
+/** WMA Version */
+typedef enum OMX_AUDIO_WMAFORMATTYPE {
+ OMX_AUDIO_WMAFormatUnused = 0, /**< format unused or unknown */
+ OMX_AUDIO_WMAFormat7, /**< Windows Media Audio format 7 */
+ OMX_AUDIO_WMAFormat8, /**< Windows Media Audio format 8 */
+ OMX_AUDIO_WMAFormat9, /**< Windows Media Audio format 9 */
+ OMX_AUDIO_WMAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_WMAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_WMAFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_WMAFORMATTYPE;
+
+
+/** WMA Profile */
+typedef enum OMX_AUDIO_WMAPROFILETYPE {
+ OMX_AUDIO_WMAProfileUnused = 0, /**< profile unused or unknown */
+ OMX_AUDIO_WMAProfileL1, /**< Windows Media audio version 9 profile L1 */
+ OMX_AUDIO_WMAProfileL2, /**< Windows Media audio version 9 profile L2 */
+ OMX_AUDIO_WMAProfileL3, /**< Windows Media audio version 9 profile L3 */
+ OMX_AUDIO_WMAProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_WMAProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_WMAProfileMax = 0x7FFFFFFF
+} OMX_AUDIO_WMAPROFILETYPE;
+
+
+/** WMA params */
+typedef struct OMX_AUDIO_PARAM_WMATYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U16 nChannels; /**< Number of channels */
+ OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable
+ rate or unknown bit rates */
+ OMX_AUDIO_WMAFORMATTYPE eFormat; /**< Version of WMA stream / data */
+ OMX_AUDIO_WMAPROFILETYPE eProfile; /**< Profile of WMA stream / data */
+ OMX_U32 nSamplingRate; /**< Sampling rate of the source data */
+ OMX_U16 nBlockAlign; /**< is the block alignment, or block size, in bytes of the audio codec */
+ OMX_U16 nEncodeOptions; /**< WMA Type-specific data */
+ OMX_U32 nSuperBlockAlign; /**< WMA Type-specific data */
+} OMX_AUDIO_PARAM_WMATYPE;
+
+/** G711 params */
+typedef struct OMX_AUDIO_PARAM_G711TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U16 nChannels; /**< Number of channels */
+ OMX_U32 nSamplingRate; /**< Sampling rate of the source data */
+} OMX_AUDIO_PARAM_G711TYPE;
+
+/**
+ * RealAudio format
+ */
+typedef enum OMX_AUDIO_RAFORMATTYPE {
+ OMX_AUDIO_RAFormatUnused = 0, /**< Format unused or unknown */
+ OMX_AUDIO_RA8, /**< RealAudio 8 codec */
+ OMX_AUDIO_RA9, /**< RealAudio 9 codec */
+ OMX_AUDIO_RA10_AAC, /**< MPEG-4 AAC codec for bitrates of more than 128kbps */
+ OMX_AUDIO_RA10_CODEC, /**< RealAudio codec for bitrates less than 128 kbps */
+ OMX_AUDIO_RA10_LOSSLESS, /**< RealAudio Lossless */
+ OMX_AUDIO_RA10_MULTICHANNEL, /**< RealAudio Multichannel */
+ OMX_AUDIO_RA10_VOICE, /**< RealAudio Voice for bitrates below 15 kbps */
+ OMX_AUDIO_RAFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_RAFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_RAFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_RAFORMATTYPE;
+
+/** RA (Real Audio) params */
+typedef struct OMX_AUDIO_PARAM_RATYPE {
+ OMX_U32 nSize; /**< Size of this structure, in Bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels */
+ OMX_U32 nSamplingRate; /**< is the sampling rate of the source data */
+ OMX_U32 nBitsPerFrame; /**< is the value for bits per frame */
+ OMX_U32 nSamplePerFrame; /**< is the value for samples per frame */
+ OMX_U32 nCouplingQuantBits; /**< is the number of coupling quantization bits in the stream */
+ OMX_U32 nCouplingStartRegion; /**< is the coupling start region in the stream */
+ OMX_U32 nNumRegions; /**< is the number of regions value */
+ OMX_AUDIO_RAFORMATTYPE eFormat; /**< is the RealAudio audio format */
+} OMX_AUDIO_PARAM_RATYPE;
+
+
+/** SBC Allocation Method Type */
+typedef enum OMX_AUDIO_SBCALLOCMETHODTYPE {
+ OMX_AUDIO_SBCAllocMethodLoudness, /**< Loudness allocation method */
+ OMX_AUDIO_SBCAllocMethodSNR, /**< SNR allocation method */
+ OMX_AUDIO_SBCAllocMethodKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_SBCAllocMethodVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_SBCAllocMethodMax = 0x7FFFFFFF
+} OMX_AUDIO_SBCALLOCMETHODTYPE;
+
+
+/** SBC params */
+typedef struct OMX_AUDIO_PARAM_SBCTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels */
+ OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable
+ rate or unknown bit rates */
+ OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for
+ variable or unknown sampling rate. */
+ OMX_U32 nBlocks; /**< Number of blocks */
+ OMX_U32 nSubbands; /**< Number of subbands */
+ OMX_U32 nBitPool; /**< Bitpool value */
+ OMX_BOOL bEnableBitrate; /**< Use bitrate value instead of bitpool */
+ OMX_AUDIO_CHANNELMODETYPE eChannelMode; /**< Channel mode enumeration */
+ OMX_AUDIO_SBCALLOCMETHODTYPE eSBCAllocType; /**< SBC Allocation method type */
+} OMX_AUDIO_PARAM_SBCTYPE;
+
+
+/** ADPCM stream format parameters */
+typedef struct OMX_AUDIO_PARAM_ADPCMTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_U32 nBitsPerSample; /**< Number of bits in each sample */
+ OMX_U32 nSampleRate; /**< Sampling rate of the source data. Use 0 for
+ variable or unknown sampling rate. */
+} OMX_AUDIO_PARAM_ADPCMTYPE;
+
+
+/** G723 rate */
+typedef enum OMX_AUDIO_G723RATE {
+ OMX_AUDIO_G723ModeUnused = 0, /**< AMRNB Mode unused / unknown */
+ OMX_AUDIO_G723ModeLow, /**< 5300 bps */
+ OMX_AUDIO_G723ModeHigh, /**< 6300 bps */
+ OMX_AUDIO_G723ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_G723ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_G723ModeMax = 0x7FFFFFFF
+} OMX_AUDIO_G723RATE;
+
+
+/** G723 - Sample rate must be 8 KHz */
+typedef struct OMX_AUDIO_PARAM_G723TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_AUDIO_G723RATE eBitRate; /**< todo: Should this be moved to a config? */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+ OMX_BOOL bPostFilter; /**< Enable Post Filter */
+} OMX_AUDIO_PARAM_G723TYPE;
+
+
+/** ITU G726 (ADPCM) rate */
+typedef enum OMX_AUDIO_G726MODE {
+ OMX_AUDIO_G726ModeUnused = 0, /**< G726 Mode unused / unknown */
+ OMX_AUDIO_G726Mode16, /**< 16 kbps */
+ OMX_AUDIO_G726Mode24, /**< 24 kbps */
+ OMX_AUDIO_G726Mode32, /**< 32 kbps, most common rate, also G721 */
+ OMX_AUDIO_G726Mode40, /**< 40 kbps */
+ OMX_AUDIO_G726ModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_G726ModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_G726ModeMax = 0x7FFFFFFF
+} OMX_AUDIO_G726MODE;
+
+
+/** G.726 stream format parameters - must be at 8KHz */
+typedef struct OMX_AUDIO_PARAM_G726TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_AUDIO_G726MODE eG726Mode;
+} OMX_AUDIO_PARAM_G726TYPE;
+
+
+/** G729 coder type */
+typedef enum OMX_AUDIO_G729TYPE {
+ OMX_AUDIO_G729 = 0, /**< ITU G.729 encoded data */
+ OMX_AUDIO_G729A, /**< ITU G.729 annex A encoded data */
+ OMX_AUDIO_G729B, /**< ITU G.729 with annex B encoded data */
+ OMX_AUDIO_G729AB, /**< ITU G.729 annexes A and B encoded data */
+ OMX_AUDIO_G729KhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_G729VendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_G729Max = 0x7FFFFFFF
+} OMX_AUDIO_G729TYPE;
+
+
+/** G729 stream format parameters - fixed 6KHz sample rate */
+typedef struct OMX_AUDIO_PARAM_G729TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_AUDIO_G729TYPE eBitType;
+} OMX_AUDIO_PARAM_G729TYPE;
+
+
+/** AMR Frame format */
+typedef enum OMX_AUDIO_AMRFRAMEFORMATTYPE {
+ OMX_AUDIO_AMRFrameFormatConformance = 0, /**< Frame Format is AMR Conformance
+ (Standard) Format */
+ OMX_AUDIO_AMRFrameFormatIF1, /**< Frame Format is AMR Interface
+ Format 1 */
+ OMX_AUDIO_AMRFrameFormatIF2, /**< Frame Format is AMR Interface
+ Format 2*/
+ OMX_AUDIO_AMRFrameFormatFSF, /**< Frame Format is AMR File Storage
+ Format */
+ OMX_AUDIO_AMRFrameFormatRTPPayload, /**< Frame Format is AMR Real-Time
+ Transport Protocol Payload Format */
+ OMX_AUDIO_AMRFrameFormatITU, /**< Frame Format is ITU Format (added at Motorola request) */
+ OMX_AUDIO_AMRFrameFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_AMRFrameFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_AMRFrameFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRFRAMEFORMATTYPE;
+
+
+/** AMR band mode */
+typedef enum OMX_AUDIO_AMRBANDMODETYPE {
+ OMX_AUDIO_AMRBandModeUnused = 0, /**< AMRNB Mode unused / unknown */
+ OMX_AUDIO_AMRBandModeNB0, /**< AMRNB Mode 0 = 4750 bps */
+ OMX_AUDIO_AMRBandModeNB1, /**< AMRNB Mode 1 = 5150 bps */
+ OMX_AUDIO_AMRBandModeNB2, /**< AMRNB Mode 2 = 5900 bps */
+ OMX_AUDIO_AMRBandModeNB3, /**< AMRNB Mode 3 = 6700 bps */
+ OMX_AUDIO_AMRBandModeNB4, /**< AMRNB Mode 4 = 7400 bps */
+ OMX_AUDIO_AMRBandModeNB5, /**< AMRNB Mode 5 = 7950 bps */
+ OMX_AUDIO_AMRBandModeNB6, /**< AMRNB Mode 6 = 10200 bps */
+ OMX_AUDIO_AMRBandModeNB7, /**< AMRNB Mode 7 = 12200 bps */
+ OMX_AUDIO_AMRBandModeWB0, /**< AMRWB Mode 0 = 6600 bps */
+ OMX_AUDIO_AMRBandModeWB1, /**< AMRWB Mode 1 = 8850 bps */
+ OMX_AUDIO_AMRBandModeWB2, /**< AMRWB Mode 2 = 12650 bps */
+ OMX_AUDIO_AMRBandModeWB3, /**< AMRWB Mode 3 = 14250 bps */
+ OMX_AUDIO_AMRBandModeWB4, /**< AMRWB Mode 4 = 15850 bps */
+ OMX_AUDIO_AMRBandModeWB5, /**< AMRWB Mode 5 = 18250 bps */
+ OMX_AUDIO_AMRBandModeWB6, /**< AMRWB Mode 6 = 19850 bps */
+ OMX_AUDIO_AMRBandModeWB7, /**< AMRWB Mode 7 = 23050 bps */
+ OMX_AUDIO_AMRBandModeWB8, /**< AMRWB Mode 8 = 23850 bps */
+ OMX_AUDIO_AMRBandModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_AMRBandModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_AMRBandModeMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRBANDMODETYPE;
+
+
+/** AMR Discontinuous Transmission mode */
+typedef enum OMX_AUDIO_AMRDTXMODETYPE {
+ OMX_AUDIO_AMRDTXModeOff = 0, /**< AMR Discontinuous Transmission Mode is disabled */
+ OMX_AUDIO_AMRDTXModeOnVAD1, /**< AMR Discontinuous Transmission Mode using
+ Voice Activity Detector 1 (VAD1) is enabled */
+ OMX_AUDIO_AMRDTXModeOnVAD2, /**< AMR Discontinuous Transmission Mode using
+ Voice Activity Detector 2 (VAD2) is enabled */
+ OMX_AUDIO_AMRDTXModeOnAuto, /**< The codec will automatically select between
+ Off, VAD1 or VAD2 modes */
+
+ OMX_AUDIO_AMRDTXasEFR, /**< DTX as EFR instead of AMR standard (3GPP 26.101, frame type =8,9,10) */
+
+ OMX_AUDIO_AMRDTXModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_AMRDTXModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_AMRDTXModeMax = 0x7FFFFFFF
+} OMX_AUDIO_AMRDTXMODETYPE;
+
+
+/** AMR params */
+typedef struct OMX_AUDIO_PARAM_AMRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels */
+ OMX_U32 nBitRate; /**< Bit rate read only field */
+ OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode; /**< AMR Band Mode enumeration */
+ OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode; /**< AMR DTX Mode enumeration */
+ OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat; /**< AMR frame format enumeration */
+} OMX_AUDIO_PARAM_AMRTYPE;
+
+
+/** GSM_FR (ETSI 06.10, 3GPP 46.010) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMFRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMFRTYPE;
+
+
+/** GSM-HR (ETSI 06.20, 3GPP 46.020) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMHRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMHRTYPE;
+
+
+/** GSM-EFR (ETSI 06.60, 3GPP 46.060) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_GSMEFRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_GSMEFRTYPE;
+
+
+/** TDMA FR (TIA/EIA-136-420, VSELP 7.95kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_TDMAFRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_TDMAFRTYPE;
+
+
+/** TDMA EFR (TIA/EIA-136-410, ACELP 7.4kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_TDMAEFRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_TDMAEFRTYPE;
+
+
+/** PDC FR ( RCR-27, VSELP 6.7kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCFRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCFRTYPE;
+
+
+/** PDC EFR ( RCR-27, ACELP 6.7kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCEFRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCEFRTYPE;
+
+/** PDC HR ( RCR-27, PSI-CELP 3.45kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_PDCHRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_BOOL bDTX; /**< Enable Discontinuous Transmisssion */
+ OMX_BOOL bHiPassFilter; /**< Enable High Pass Filter */
+} OMX_AUDIO_PARAM_PDCHRTYPE;
+
+
+/** CDMA Rate types */
+typedef enum OMX_AUDIO_CDMARATETYPE {
+ OMX_AUDIO_CDMARateBlank = 0, /**< CDMA encoded frame is blank */
+ OMX_AUDIO_CDMARateFull, /**< CDMA encoded frame in full rate */
+ OMX_AUDIO_CDMARateHalf, /**< CDMA encoded frame in half rate */
+ OMX_AUDIO_CDMARateQuarter, /**< CDMA encoded frame in quarter rate */
+ OMX_AUDIO_CDMARateEighth, /**< CDMA encoded frame in eighth rate (DTX)*/
+ OMX_AUDIO_CDMARateErasure, /**< CDMA erasure frame */
+ OMX_AUDIO_CDMARateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_CDMARateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_CDMARateMax = 0x7FFFFFFF
+} OMX_AUDIO_CDMARATETYPE;
+
+
+/** QCELP8 (TIA/EIA-96, up to 8kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_QCELP8TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_U32 nBitRate; /**< Bit rate of the input data. Use 0 for variable
+ rate or unknown bit rates */
+ OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+ OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+ OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+} OMX_AUDIO_PARAM_QCELP8TYPE;
+
+
+/** QCELP13 ( CDMA, EIA/TIA-733, 13.3kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_QCELP13TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+ OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+ OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+} OMX_AUDIO_PARAM_QCELP13TYPE;
+
+
+/** EVRC ( CDMA, EIA/TIA-127, RCELP up to 8.55kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_EVRCTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_AUDIO_CDMARATETYPE eCDMARate; /**< actual Frame rate */
+ OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */
+ OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 */
+ OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 */
+ OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter */
+ OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */
+ OMX_BOOL bPostFilter; /**< Enable decoder's post Filter */
+} OMX_AUDIO_PARAM_EVRCTYPE;
+
+
+/** SMV ( up to 8.55kbps coder) stream format parameters */
+typedef struct OMX_AUDIO_PARAM_SMVTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannels; /**< Number of channels in the data stream (not
+ necessarily the same as the number of channels
+ to be rendered. */
+ OMX_AUDIO_CDMARATETYPE eCDMARate; /**< Frame rate */
+ OMX_BOOL bRATE_REDUCon; /**< RATE_REDUCtion is requested for this frame */
+ OMX_U32 nMinBitRate; /**< minmal rate for the encoder = 1,2,3,4, default = 1 ??*/
+ OMX_U32 nMaxBitRate; /**< maximal rate for the encoder = 1,2,3,4, default = 4 ??*/
+ OMX_BOOL bHiPassFilter; /**< Enable encoder's High Pass Filter ??*/
+ OMX_BOOL bNoiseSuppressor; /**< Enable encoder's noise suppressor pre-processing */
+ OMX_BOOL bPostFilter; /**< Enable decoder's post Filter ??*/
+} OMX_AUDIO_PARAM_SMVTYPE;
+
+
+/** MIDI Format
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDIFORMATTYPE
+{
+ OMX_AUDIO_MIDIFormatUnknown = 0, /**< MIDI Format unknown or don't care */
+ OMX_AUDIO_MIDIFormatSMF0, /**< Standard MIDI File Type 0 */
+ OMX_AUDIO_MIDIFormatSMF1, /**< Standard MIDI File Type 1 */
+ OMX_AUDIO_MIDIFormatSMF2, /**< Standard MIDI File Type 2 */
+ OMX_AUDIO_MIDIFormatSPMIDI, /**< SP-MIDI */
+ OMX_AUDIO_MIDIFormatXMF0, /**< eXtensible Music Format type 0 */
+ OMX_AUDIO_MIDIFormatXMF1, /**< eXtensible Music Format type 1 */
+ OMX_AUDIO_MIDIFormatMobileXMF, /**< Mobile XMF (eXtensible Music Format type 2) */
+ OMX_AUDIO_MIDIFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_MIDIFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_MIDIFormatMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDIFORMATTYPE;
+
+
+/** MIDI params
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_PARAM_MIDITYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nFileSize; /**< size of the MIDI file in bytes, where the entire
+ MIDI file passed in, otherwise if 0x0, the MIDI data
+ is merged and streamed (instead of passed as an
+ entire MIDI file) */
+ OMX_BU32 sMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic
+ voices. A value of zero indicates that the default
+ polyphony of the device is used */
+ OMX_BOOL bLoadDefaultSound; /**< Whether to load default sound
+ bank at initialization */
+ OMX_AUDIO_MIDIFORMATTYPE eMidiFormat; /**< Version of the MIDI file */
+} OMX_AUDIO_PARAM_MIDITYPE;
+
+
+/** Type of the MIDI sound bank
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDISOUNDBANKTYPE {
+ OMX_AUDIO_MIDISoundBankUnused = 0, /**< unused/unknown soundbank type */
+ OMX_AUDIO_MIDISoundBankDLS1, /**< DLS version 1 */
+ OMX_AUDIO_MIDISoundBankDLS2, /**< DLS version 2 */
+ OMX_AUDIO_MIDISoundBankMobileDLSBase, /**< Mobile DLS, using the base functionality */
+ OMX_AUDIO_MIDISoundBankMobileDLSPlusOptions, /**< Mobile DLS, using the specification-defined optional feature set */
+ OMX_AUDIO_MIDISoundBankKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_MIDISoundBankVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_MIDISoundBankMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDISOUNDBANKTYPE;
+
+
+/** Bank Layout describes how bank MSB & LSB are used in the DLS instrument definitions sound bank
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE {
+ OMX_AUDIO_MIDISoundBankLayoutUnused = 0, /**< unused/unknown soundbank type */
+ OMX_AUDIO_MIDISoundBankLayoutGM, /**< GS layout (based on bank MSB 0x00) */
+ OMX_AUDIO_MIDISoundBankLayoutGM2, /**< General MIDI 2 layout (using MSB 0x78/0x79, LSB 0x00) */
+ OMX_AUDIO_MIDISoundBankLayoutUser, /**< Does not conform to any bank numbering standards */
+ OMX_AUDIO_MIDISoundBankLayoutKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_MIDISoundBankLayoutVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_MIDISoundBankLayoutMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE;
+
+
+/** MIDI params to load/unload user soundbank
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nDLSIndex; /**< DLS file index to be loaded */
+ OMX_U32 nDLSSize; /**< Size in bytes */
+ OMX_PTR pDLSData; /**< Pointer to DLS file data */
+ OMX_AUDIO_MIDISOUNDBANKTYPE eMidiSoundBank; /**< Midi sound bank type enumeration */
+ OMX_AUDIO_MIDISOUNDBANKLAYOUTTYPE eMidiSoundBankLayout; /**< Midi sound bank layout enumeration */
+} OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE;
+
+
+/** Structure for Live MIDI events and MIP messages.
+ * (MIP = Maximum Instantaneous Polyphony; part of the SP-MIDI standard.)
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port that this structure applies to */
+ OMX_U32 nMidiEventSize; /**< Size of immediate MIDI events or MIP message in bytes */
+ OMX_U8 nMidiEvents[1]; /**< MIDI event array to be rendered immediately, or an
+ array for the MIP message buffer, where the size is
+ indicated by nMidiEventSize */
+} OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE;
+
+
+/** MIDI sound bank/ program pair in a given channel
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port that this structure applies to */
+ OMX_U32 nChannel; /**< Valid channel values range from 1 to 16 */
+ OMX_U16 nIDProgram; /**< Valid program ID range is 1 to 128 */
+ OMX_U16 nIDSoundBank; /**< Sound bank ID */
+ OMX_U32 nUserSoundBankIndex;/**< User soundbank index, easier to access soundbanks
+ by index if multiple banks are present */
+} OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE;
+
+
+/** MIDI control
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDICONTROLTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BS32 sPitchTransposition; /**< Pitch transposition in semitones, stored as Q22.10
+ format based on JAVA MMAPI (JSR-135) requirement */
+ OMX_BU32 sPlayBackRate; /**< Relative playback rate, stored as Q14.17 fixed-point
+ number based on JSR-135 requirement */
+ OMX_BU32 sTempo ; /**< Tempo in beats per minute (BPM), stored as Q22.10
+ fixed-point number based on JSR-135 requirement */
+ OMX_U32 nMaxPolyphony; /**< Specifies the maximum simultaneous polyphonic
+ voices. A value of zero indicates that the default
+ polyphony of the device is used */
+ OMX_U32 nNumRepeat; /**< Number of times to repeat playback */
+ OMX_U32 nStopTime; /**< Time in milliseconds to indicate when playback
+ will stop automatically. Set to zero if not used */
+ OMX_U16 nChannelMuteMask; /**< 16 bit mask for channel mute status */
+ OMX_U16 nChannelSoloMask; /**< 16 bit mask for channel solo status */
+ OMX_U32 nTrack0031MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 0-31 */
+ OMX_U32 nTrack3263MuteMask; /**< 32 bit mask for track mute status. Note: This is for tracks 32-63 */
+ OMX_U32 nTrack0031SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 0-31 */
+ OMX_U32 nTrack3263SoloMask; /**< 32 bit mask for track solo status. Note: This is for tracks 32-63 */
+
+} OMX_AUDIO_CONFIG_MIDICONTROLTYPE;
+
+
+/** MIDI Playback States
+ * @ingroup midi
+ */
+typedef enum OMX_AUDIO_MIDIPLAYBACKSTATETYPE {
+ OMX_AUDIO_MIDIPlayBackStateUnknown = 0, /**< Unknown state or state does not map to
+ other defined states */
+ OMX_AUDIO_MIDIPlayBackStateClosedEngaged, /**< No MIDI resource is currently open.
+ The MIDI engine is currently processing
+ MIDI events. */
+ OMX_AUDIO_MIDIPlayBackStateParsing, /**< A MIDI resource is open and is being
+ primed. The MIDI engine is currently
+ processing MIDI events. */
+ OMX_AUDIO_MIDIPlayBackStateOpenEngaged, /**< A MIDI resource is open and primed but
+ not playing. The MIDI engine is currently
+ processing MIDI events. The transition to
+ this state is only possible from the
+ OMX_AUDIO_MIDIPlayBackStatePlaying state,
+ when the 'playback head' reaches the end
+ of media data or the playback stops due
+ to stop time set.*/
+ OMX_AUDIO_MIDIPlayBackStatePlaying, /**< A MIDI resource is open and currently
+ playing. The MIDI engine is currently
+ processing MIDI events.*/
+ OMX_AUDIO_MIDIPlayBackStatePlayingPartially, /**< Best-effort playback due to SP-MIDI/DLS
+ resource constraints */
+ OMX_AUDIO_MIDIPlayBackStatePlayingSilently, /**< Due to system resource constraints and
+ SP-MIDI content constraints, there is
+ no audible MIDI content during playback
+ currently. The situation may change if
+ resources are freed later.*/
+ OMX_AUDIO_MIDIPlayBackStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_MIDIPlayBackStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_MIDIPlayBackStateMax = 0x7FFFFFFF
+} OMX_AUDIO_MIDIPLAYBACKSTATETYPE;
+
+
+/** MIDI status
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDISTATUSTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U16 nNumTracks; /**< Number of MIDI tracks in the file, read only field.
+ NOTE: May not return a meaningful value until the entire
+ file is parsed and buffered. */
+ OMX_U32 nDuration; /**< The length of the currently open MIDI resource
+ in milliseconds. NOTE: May not return a meaningful value
+ until the entire file is parsed and buffered. */
+ OMX_U32 nPosition; /**< Current Position of the MIDI resource being played
+ in milliseconds */
+ OMX_BOOL bVibra; /**< Does Vibra track exist? NOTE: May not return a meaningful
+ value until the entire file is parsed and buffered. */
+ OMX_U32 nNumMetaEvents; /**< Total number of MIDI Meta Events in the currently
+ open MIDI resource. NOTE: May not return a meaningful value
+ until the entire file is parsed and buffered. */
+ OMX_U32 nNumActiveVoices; /**< Number of active voices in the currently playing
+ MIDI resource. NOTE: May not return a meaningful value until
+ the entire file is parsed and buffered. */
+ OMX_AUDIO_MIDIPLAYBACKSTATETYPE eMIDIPlayBackState; /**< MIDI playback state enumeration, read only field */
+} OMX_AUDIO_CONFIG_MIDISTATUSTYPE;
+
+
+/** MIDI Meta Event structure one per Meta Event.
+ * MIDI Meta Events are like audio metadata, except that they are interspersed
+ * with the MIDI content throughout the file and are not localized in the header.
+ * As such, it is necessary to retrieve information about these Meta Events from
+ * the engine, as it encounters these Meta Events within the MIDI content.
+ * For example, SMF files can have up to 14 types of MIDI Meta Events (copyright,
+ * author, default tempo, etc.) scattered throughout the file.
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE{
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nIndex; /**< Index of Meta Event */
+ OMX_U8 nMetaEventType; /**< Meta Event Type, 7bits (i.e. 0 - 127) */
+ OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */
+ OMX_U32 nTrack; /**< track number for the meta event */
+ OMX_U32 nPosition; /**< Position of the meta-event in milliseconds */
+} OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE;
+
+
+/** MIDI Meta Event Data structure - one per Meta Event.
+ * @ingroup midi
+ */
+typedef struct OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE{
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nIndex; /**< Index of Meta Event */
+ OMX_U32 nMetaEventSize; /**< size of the Meta Event in bytes */
+ OMX_U8 nData[1]; /**< array of one or more bytes of meta data
+ as indicated by the nMetaEventSize field */
+} OMX_AUDIO_CONFIG__MIDIMETAEVENTDATATYPE;
+
+
+/** Audio Volume adjustment for a port */
+typedef struct OMX_AUDIO_CONFIG_VOLUMETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port index indicating which port to
+ set. Select the input port to set
+ just that port's volume. Select the
+ output port to adjust the master
+ volume. */
+ OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100)
+ or logarithmic scale (mB) */
+ OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR
+ Volume logarithmic setting for this port. The values
+ for volume are in mB (millibels = 1/100 dB) relative
+ to a gain of 1 (e.g. the output is the same as the
+ input level). Values are in mB from nMax
+ (maximum volume) to nMin mB (typically negative).
+ Since the volume is "voltage"
+ and not a "power", it takes a setting of
+ -600 mB to decrease the volume by 1/2. If
+ a component cannot accurately set the
+ volume to the requested value, it must
+ set the volume to the closest value BELOW
+ the requested value. When getting the
+ volume setting, the current actual volume
+ must be returned. */
+} OMX_AUDIO_CONFIG_VOLUMETYPE;
+
+
+/** Audio Volume adjustment for a channel */
+typedef struct OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port index indicating which port to
+ set. Select the input port to set
+ just that port's volume. Select the
+ output port to adjust the master
+ volume. */
+ OMX_U32 nChannel; /**< channel to select from 0 to N-1,
+ using OMX_ALL to apply volume settings
+ to all channels */
+ OMX_BOOL bLinear; /**< Is the volume to be set in linear (0.100) or
+ logarithmic scale (mB) */
+ OMX_BS32 sVolume; /**< Volume linear setting in the 0..100 range, OR
+ Volume logarithmic setting for this port.
+ The values for volume are in mB
+ (millibels = 1/100 dB) relative to a gain
+ of 1 (e.g. the output is the same as the
+ input level). Values are in mB from nMax
+ (maximum volume) to nMin mB (typically negative).
+ Since the volume is "voltage"
+ and not a "power", it takes a setting of
+ -600 mB to decrease the volume by 1/2. If
+ a component cannot accurately set the
+ volume to the requested value, it must
+ set the volume to the closest value BELOW
+ the requested value. When getting the
+ volume setting, the current actual volume
+ must be returned. */
+ OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel,
+ FALSE otherwise */
+} OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE;
+
+
+/** Audio balance setting */
+typedef struct OMX_AUDIO_CONFIG_BALANCETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port index indicating which port to
+ set. Select the input port to set
+ just that port's balance. Select the
+ output port to adjust the master
+ balance. */
+ OMX_S32 nBalance; /**< balance setting for this port
+ (-100 to 100, where -100 indicates
+ all left, and no right */
+} OMX_AUDIO_CONFIG_BALANCETYPE;
+
+
+/** Audio Port mute */
+typedef struct OMX_AUDIO_CONFIG_MUTETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port index indicating which port to
+ set. Select the input port to set
+ just that port's mute. Select the
+ output port to adjust the master
+ mute. */
+ OMX_BOOL bMute; /**< Mute setting for this port */
+} OMX_AUDIO_CONFIG_MUTETYPE;
+
+
+/** Audio Channel mute */
+typedef struct OMX_AUDIO_CONFIG_CHANNELMUTETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nChannel; /**< channel to select from 0 to N-1,
+ using OMX_ALL to apply mute settings
+ to all channels */
+ OMX_BOOL bMute; /**< Mute setting for this channel */
+ OMX_BOOL bIsMIDI; /**< TRUE if nChannel refers to a MIDI channel,
+ FALSE otherwise */
+} OMX_AUDIO_CONFIG_CHANNELMUTETYPE;
+
+
+
+/** Enable / Disable for loudness control, which boosts bass and to a
+ * smaller extent high end frequencies to compensate for hearing
+ * ability at the extreme ends of the audio spectrum
+ */
+typedef struct OMX_AUDIO_CONFIG_LOUDNESSTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bLoudness; /**< Enable/disable for loudness */
+} OMX_AUDIO_CONFIG_LOUDNESSTYPE;
+
+
+/** Enable / Disable for bass, which controls low frequencies
+ */
+typedef struct OMX_AUDIO_CONFIG_BASSTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bEnable; /**< Enable/disable for bass control */
+ OMX_S32 nBass; /**< bass setting for the port, as a
+ continuous value from -100 to 100
+ (0 means no change in bass level)*/
+} OMX_AUDIO_CONFIG_BASSTYPE;
+
+
+/** Enable / Disable for treble, which controls high frequencies tones
+ */
+typedef struct OMX_AUDIO_CONFIG_TREBLETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bEnable; /**< Enable/disable for treble control */
+ OMX_S32 nTreble; /**< treble setting for the port, as a
+ continuous value from -100 to 100
+ (0 means no change in treble level) */
+} OMX_AUDIO_CONFIG_TREBLETYPE;
+
+
+/** An equalizer is typically used for two reasons: to compensate for an
+ * sub-optimal frequency response of a system to make it sound more natural
+ * or to create intentionally some unnatural coloring to the sound to create
+ * an effect.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_EQUALIZERTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bEnable; /**< Enable/disable for equalizer */
+ OMX_BU32 sBandIndex; /**< Band number to be set. Upper Limit is
+ N-1, where N is the number of bands, lower limit is 0 */
+ OMX_BU32 sCenterFreq; /**< Center frequecies in Hz. This is a
+ read only element and is used to determine
+ the lower, center and upper frequency of
+ this band. */
+ OMX_BS32 sBandLevel; /**< band level in millibels */
+} OMX_AUDIO_CONFIG_EQUALIZERTYPE;
+
+
+/** Stereo widening mode type
+ * @ingroup effects
+ */
+typedef enum OMX_AUDIO_STEREOWIDENINGTYPE {
+ OMX_AUDIO_StereoWideningHeadphones, /**< Stereo widening for loudspeakers */
+ OMX_AUDIO_StereoWideningLoudspeakers, /**< Stereo widening for closely spaced loudspeakers */
+ OMX_AUDIO_StereoWideningKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_StereoWideningVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_StereoWideningMax = 0x7FFFFFFF
+} OMX_AUDIO_STEREOWIDENINGTYPE;
+
+
+/** Control for stereo widening, which is a special 2-channel
+ * case of the audio virtualizer effect. For example, for 5.1-channel
+ * output, it translates to virtual surround sound.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bEnable; /**< Enable/disable for stereo widening control */
+ OMX_AUDIO_STEREOWIDENINGTYPE eWideningType; /**< Stereo widening algorithm type */
+ OMX_U32 nStereoWidening; /**< stereo widening setting for the port,
+ as a continuous value from 0 to 100 */
+} OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE;
+
+
+/** The chorus effect (or ``choralizer'') is any signal processor which makes
+ * one sound source (such as a voice) sound like many such sources singing
+ * (or playing) in unison. Since performance in unison is never exact, chorus
+ * effects simulate this by making independently modified copies of the input
+ * signal. Modifications may include (1) delay, (2) frequency shift, and
+ * (3) amplitude modulation.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_CHORUSTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bEnable; /**< Enable/disable for chorus */
+ OMX_BU32 sDelay; /**< average delay in milliseconds */
+ OMX_BU32 sModulationRate; /**< rate of modulation in millihertz */
+ OMX_U32 nModulationDepth; /**< depth of modulation as a percentage of
+ delay (i.e. 0 to 100) */
+ OMX_BU32 nFeedback; /**< Feedback from chorus output to input in percentage */
+} OMX_AUDIO_CONFIG_CHORUSTYPE;
+
+
+/** Reverberation is part of the reflected sound that follows the early
+ * reflections. In a typical room, this consists of a dense succession of
+ * echoes whose energy decays exponentially. The reverberation effect structure
+ * as defined here includes both (early) reflections as well as (late) reverberations.
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_REVERBERATIONTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bEnable; /**< Enable/disable for reverberation control */
+ OMX_BS32 sRoomLevel; /**< Intensity level for the whole room effect
+ (i.e. both early reflections and late
+ reverberation) in millibels */
+ OMX_BS32 sRoomHighFreqLevel; /**< Attenuation at high frequencies
+ relative to the intensity at low
+ frequencies in millibels */
+ OMX_BS32 sReflectionsLevel; /**< Intensity level of early reflections
+ (relative to room value), in millibels */
+ OMX_BU32 sReflectionsDelay; /**< Delay time of the first reflection relative
+ to the direct path, in milliseconds */
+ OMX_BS32 sReverbLevel; /**< Intensity level of late reverberation
+ relative to room level, in millibels */
+ OMX_BU32 sReverbDelay; /**< Time delay from the first early reflection
+ to the beginning of the late reverberation
+ section, in milliseconds */
+ OMX_BU32 sDecayTime; /**< Late reverberation decay time at low
+ frequencies, in milliseconds */
+ OMX_BU32 nDecayHighFreqRatio; /**< Ratio of high frequency decay time relative
+ to low frequency decay time in percent */
+ OMX_U32 nDensity; /**< Modal density in the late reverberation decay,
+ in percent (i.e. 0 - 100) */
+ OMX_U32 nDiffusion; /**< Echo density in the late reverberation decay,
+ in percent (i.e. 0 - 100) */
+ OMX_BU32 sReferenceHighFreq; /**< Reference high frequency in Hertz. This is
+ the frequency used as the reference for all
+ the high-frequency settings above */
+
+} OMX_AUDIO_CONFIG_REVERBERATIONTYPE;
+
+
+/** Possible settings for the Echo Cancelation structure to use
+ * @ingroup effects
+ */
+typedef enum OMX_AUDIO_ECHOCANTYPE {
+ OMX_AUDIO_EchoCanOff = 0, /**< Echo Cancellation is disabled */
+ OMX_AUDIO_EchoCanNormal, /**< Echo Cancellation normal operation -
+ echo from plastics and face */
+ OMX_AUDIO_EchoCanHFree, /**< Echo Cancellation optimized for
+ Hands Free operation */
+ OMX_AUDIO_EchoCanCarKit, /**< Echo Cancellation optimized for
+ Car Kit (longer echo) */
+ OMX_AUDIO_EchoCanKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_AUDIO_EchoCanVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_AUDIO_EchoCanMax = 0x7FFFFFFF
+} OMX_AUDIO_ECHOCANTYPE;
+
+
+/** Enable / Disable for echo cancelation, which removes undesired echo's
+ * from the audio
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_AUDIO_ECHOCANTYPE eEchoCancelation; /**< Echo cancelation settings */
+} OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE;
+
+
+/** Enable / Disable for noise reduction, which undesired noise from
+ * the audio
+ * @ingroup effects
+ */
+typedef struct OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BOOL bNoiseReduction; /**< Enable/disable for noise reduction */
+} OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+
diff --git a/msmcobalt/mm-core/inc/OMX_Component.h b/msmcobalt/mm-core/inc/OMX_Component.h
new file mode 100644
index 0000000..d595640
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Component.h
@@ -0,0 +1,579 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_Component.h - OpenMax IL version 1.1.2
+ * The OMX_Component header file contains the definitions used to define
+ * the public interface of a component. This header file is intended to
+ * be used by both the application and the component.
+ */
+
+#ifndef OMX_Component_h
+#define OMX_Component_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+
+/* Each OMX header must include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_Audio.h>
+#include <OMX_Video.h>
+#include <OMX_Image.h>
+#include <OMX_Other.h>
+
+/** @ingroup comp */
+typedef enum OMX_PORTDOMAINTYPE {
+ OMX_PortDomainAudio,
+ OMX_PortDomainVideo,
+ OMX_PortDomainImage,
+ OMX_PortDomainOther,
+ OMX_PortDomainKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_PortDomainVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_PortDomainMax = 0x7ffffff
+} OMX_PORTDOMAINTYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_PORTDEFINITIONTYPE {
+ OMX_U32 nSize; /**< Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port number the structure applies to */
+ OMX_DIRTYPE eDir; /**< Direction (input or output) of this port */
+ OMX_U32 nBufferCountActual; /**< The actual number of buffers allocated on this port */
+ OMX_U32 nBufferCountMin; /**< The minimum number of buffers this port requires */
+ OMX_U32 nBufferSize; /**< Size, in bytes, for buffers to be used for this channel */
+ OMX_BOOL bEnabled; /**< Ports default to enabled and are enabled/disabled by
+ OMX_CommandPortEnable/OMX_CommandPortDisable.
+ When disabled a port is unpopulated. A disabled port
+ is not populated with buffers on a transition to IDLE. */
+ OMX_BOOL bPopulated; /**< Port is populated with all of its buffers as indicated by
+ nBufferCountActual. A disabled port is always unpopulated.
+ An enabled port is populated on a transition to OMX_StateIdle
+ and unpopulated on a transition to loaded. */
+ OMX_PORTDOMAINTYPE eDomain; /**< Domain of the port. Determines the contents of metadata below. */
+ union {
+ OMX_AUDIO_PORTDEFINITIONTYPE audio;
+ OMX_VIDEO_PORTDEFINITIONTYPE video;
+ OMX_IMAGE_PORTDEFINITIONTYPE image;
+ OMX_OTHER_PORTDEFINITIONTYPE other;
+ } format;
+ OMX_BOOL bBuffersContiguous;
+ OMX_U32 nBufferAlignment;
+} OMX_PARAM_PORTDEFINITIONTYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_U32TYPE {
+ OMX_U32 nSize; /**< Size of this structure, in Bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_U32 nU32; /**< U32 value */
+} OMX_PARAM_U32TYPE;
+
+/** @ingroup rpm */
+typedef enum OMX_SUSPENSIONPOLICYTYPE {
+ OMX_SuspensionDisabled, /**< No suspension; v1.0 behavior */
+ OMX_SuspensionEnabled, /**< Suspension allowed */
+ OMX_SuspensionPolicyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_SuspensionPolicyStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_SuspensionPolicyMax = 0x7fffffff
+} OMX_SUSPENSIONPOLICYTYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_PARAM_SUSPENSIONPOLICYTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_SUSPENSIONPOLICYTYPE ePolicy;
+} OMX_PARAM_SUSPENSIONPOLICYTYPE;
+
+/** @ingroup rpm */
+typedef enum OMX_SUSPENSIONTYPE {
+ OMX_NotSuspended, /**< component is not suspended */
+ OMX_Suspended, /**< component is suspended */
+ OMX_SuspensionKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_SuspensionVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_SuspendMax = 0x7FFFFFFF
+} OMX_SUSPENSIONTYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_PARAM_SUSPENSIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_SUSPENSIONTYPE eType;
+} OMX_PARAM_SUSPENSIONTYPE ;
+
+typedef struct OMX_CONFIG_BOOLEANTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bEnabled;
+} OMX_CONFIG_BOOLEANTYPE;
+
+/* Parameter specifying the content uri to use. */
+/** @ingroup cp */
+typedef struct OMX_PARAM_CONTENTURITYPE
+{
+ OMX_U32 nSize; /**< size of the structure in bytes, including
+ actual URI name */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U8 contentURI[1]; /**< The URI name */
+} OMX_PARAM_CONTENTURITYPE;
+
+/* Parameter specifying the pipe to use. */
+/** @ingroup cp */
+typedef struct OMX_PARAM_CONTENTPIPETYPE
+{
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_HANDLETYPE hPipe; /**< The pipe handle*/
+} OMX_PARAM_CONTENTPIPETYPE;
+
+/** @ingroup rpm */
+typedef struct OMX_RESOURCECONCEALMENTTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bResourceConcealmentForbidden; /**< disallow the use of resource concealment
+ methods (like degrading algorithm quality to
+ lower resource consumption or functional bypass)
+ on a component as a resolution to resource conflicts. */
+} OMX_RESOURCECONCEALMENTTYPE;
+
+
+/** @ingroup metadata */
+typedef enum OMX_METADATACHARSETTYPE {
+ OMX_MetadataCharsetUnknown = 0,
+ OMX_MetadataCharsetASCII,
+ OMX_MetadataCharsetBinary,
+ OMX_MetadataCharsetCodePage1252,
+ OMX_MetadataCharsetUTF8,
+ OMX_MetadataCharsetJavaConformantUTF8,
+ OMX_MetadataCharsetUTF7,
+ OMX_MetadataCharsetImapUTF7,
+ OMX_MetadataCharsetUTF16LE,
+ OMX_MetadataCharsetUTF16BE,
+ OMX_MetadataCharsetGB12345,
+ OMX_MetadataCharsetHZGB2312,
+ OMX_MetadataCharsetGB2312,
+ OMX_MetadataCharsetGB18030,
+ OMX_MetadataCharsetGBK,
+ OMX_MetadataCharsetBig5,
+ OMX_MetadataCharsetISO88591,
+ OMX_MetadataCharsetISO88592,
+ OMX_MetadataCharsetISO88593,
+ OMX_MetadataCharsetISO88594,
+ OMX_MetadataCharsetISO88595,
+ OMX_MetadataCharsetISO88596,
+ OMX_MetadataCharsetISO88597,
+ OMX_MetadataCharsetISO88598,
+ OMX_MetadataCharsetISO88599,
+ OMX_MetadataCharsetISO885910,
+ OMX_MetadataCharsetISO885913,
+ OMX_MetadataCharsetISO885914,
+ OMX_MetadataCharsetISO885915,
+ OMX_MetadataCharsetShiftJIS,
+ OMX_MetadataCharsetISO2022JP,
+ OMX_MetadataCharsetISO2022JP1,
+ OMX_MetadataCharsetISOEUCJP,
+ OMX_MetadataCharsetSMS7Bit,
+ OMX_MetadataCharsetKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_MetadataCharsetVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_MetadataCharsetTypeMax= 0x7FFFFFFF
+} OMX_METADATACHARSETTYPE;
+
+/** @ingroup metadata */
+typedef enum OMX_METADATASCOPETYPE
+{
+ OMX_MetadataScopeAllLevels,
+ OMX_MetadataScopeTopLevel,
+ OMX_MetadataScopePortLevel,
+ OMX_MetadataScopeNodeLevel,
+ OMX_MetadataScopeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_MetadataScopeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_MetadataScopeTypeMax = 0x7fffffff
+} OMX_METADATASCOPETYPE;
+
+/** @ingroup metadata */
+typedef enum OMX_METADATASEARCHMODETYPE
+{
+ OMX_MetadataSearchValueSizeByIndex,
+ OMX_MetadataSearchItemByIndex,
+ OMX_MetadataSearchNextItemByKey,
+ OMX_MetadataSearchKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_MetadataSearchVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_MetadataSearchTypeMax = 0x7fffffff
+} OMX_METADATASEARCHMODETYPE;
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_METADATAITEMCOUNTTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_METADATASCOPETYPE eScopeMode;
+ OMX_U32 nScopeSpecifier;
+ OMX_U32 nMetadataItemCount;
+} OMX_CONFIG_METADATAITEMCOUNTTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_METADATAITEMTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_METADATASCOPETYPE eScopeMode;
+ OMX_U32 nScopeSpecifier;
+ OMX_U32 nMetadataItemIndex;
+ OMX_METADATASEARCHMODETYPE eSearchMode;
+ OMX_METADATACHARSETTYPE eKeyCharset;
+ OMX_U8 nKeySizeUsed;
+ OMX_U8 nKey[128];
+ OMX_METADATACHARSETTYPE eValueCharset;
+ OMX_STRING sLanguageCountry;
+ OMX_U32 nValueMaxSize;
+ OMX_U32 nValueSizeUsed;
+ OMX_U8 nValue[1];
+} OMX_CONFIG_METADATAITEMTYPE;
+
+/* @ingroup metadata */
+typedef struct OMX_CONFIG_CONTAINERNODECOUNTTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bAllKeys;
+ OMX_U32 nParentNodeID;
+ OMX_U32 nNumNodes;
+} OMX_CONFIG_CONTAINERNODECOUNTTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_CONFIG_CONTAINERNODEIDTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bAllKeys;
+ OMX_U32 nParentNodeID;
+ OMX_U32 nNodeIndex;
+ OMX_U32 nNodeID;
+ OMX_STRING cNodeName;
+ OMX_BOOL bIsLeafType;
+} OMX_CONFIG_CONTAINERNODEIDTYPE;
+
+/** @ingroup metadata */
+typedef struct OMX_PARAM_METADATAFILTERTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bAllKeys; /* if true then this structure refers to all keys and
+ * the three key fields below are ignored */
+ OMX_METADATACHARSETTYPE eKeyCharset;
+ OMX_U32 nKeySizeUsed;
+ OMX_U8 nKey [128];
+ OMX_U32 nLanguageCountrySizeUsed;
+ OMX_U8 nLanguageCountry[128];
+ OMX_BOOL bEnabled; /* if true then key is part of filter (e.g.
+ * retained for query later). If false then
+ * key is not part of filter */
+} OMX_PARAM_METADATAFILTERTYPE;
+
+/** The OMX_HANDLETYPE structure defines the component handle. The component
+ * handle is used to access all of the component's public methods and also
+ * contains pointers to the component's private data area. The component
+ * handle is initialized by the OMX core (with help from the component)
+ * during the process of loading the component. After the component is
+ * successfully loaded, the application can safely access any of the
+ * component's public functions (although some may return an error because
+ * the state is inappropriate for the access).
+ *
+ * @ingroup comp
+ */
+typedef struct OMX_COMPONENTTYPE
+{
+ /** The size of this structure, in bytes. It is the responsibility
+ of the allocator of this structure to fill in this value. Since
+ this structure is allocated by the GetHandle function, this
+ function will fill in this value. */
+ OMX_U32 nSize;
+
+ /** nVersion is the version of the OMX specification that the structure
+ is built against. It is the responsibility of the creator of this
+ structure to initialize this value and every user of this structure
+ should verify that it knows how to use the exact version of
+ this structure found herein. */
+ OMX_VERSIONTYPE nVersion;
+
+ /** pComponentPrivate is a pointer to the component private data area.
+ This member is allocated and initialized by the component when the
+ component is first loaded. The application should not access this
+ data area. */
+ OMX_PTR pComponentPrivate;
+
+ /** pApplicationPrivate is a pointer that is a parameter to the
+ OMX_GetHandle method, and contains an application private value
+ provided by the IL client. This application private data is
+ returned to the IL Client by OMX in all callbacks */
+ OMX_PTR pApplicationPrivate;
+
+ /** refer to OMX_GetComponentVersion in OMX_core.h or the OMX IL
+ specification for details on the GetComponentVersion method.
+ */
+ OMX_ERRORTYPE (*GetComponentVersion)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_STRING pComponentName,
+ OMX_OUT OMX_VERSIONTYPE* pComponentVersion,
+ OMX_OUT OMX_VERSIONTYPE* pSpecVersion,
+ OMX_OUT OMX_UUIDTYPE* pComponentUUID);
+
+ /** refer to OMX_SendCommand in OMX_core.h or the OMX IL
+ specification for details on the SendCommand method.
+ */
+ OMX_ERRORTYPE (*SendCommand)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_COMMANDTYPE Cmd,
+ OMX_IN OMX_U32 nParam1,
+ OMX_IN OMX_PTR pCmdData);
+
+ /** refer to OMX_GetParameter in OMX_core.h or the OMX IL
+ specification for details on the GetParameter method.
+ */
+ OMX_ERRORTYPE (*GetParameter)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nParamIndex,
+ OMX_INOUT OMX_PTR pComponentParameterStructure);
+
+
+ /** refer to OMX_SetParameter in OMX_core.h or the OMX IL
+ specification for details on the SetParameter method.
+ */
+ OMX_ERRORTYPE (*SetParameter)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR pComponentParameterStructure);
+
+
+ /** refer to OMX_GetConfig in OMX_core.h or the OMX IL
+ specification for details on the GetConfig method.
+ */
+ OMX_ERRORTYPE (*GetConfig)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_INOUT OMX_PTR pComponentConfigStructure);
+
+
+ /** refer to OMX_SetConfig in OMX_core.h or the OMX IL
+ specification for details on the SetConfig method.
+ */
+ OMX_ERRORTYPE (*SetConfig)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_INDEXTYPE nIndex,
+ OMX_IN OMX_PTR pComponentConfigStructure);
+
+
+ /** refer to OMX_GetExtensionIndex in OMX_core.h or the OMX IL
+ specification for details on the GetExtensionIndex method.
+ */
+ OMX_ERRORTYPE (*GetExtensionIndex)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_STRING cParameterName,
+ OMX_OUT OMX_INDEXTYPE* pIndexType);
+
+
+ /** refer to OMX_GetState in OMX_core.h or the OMX IL
+ specification for details on the GetState method.
+ */
+ OMX_ERRORTYPE (*GetState)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_STATETYPE* pState);
+
+
+ /** The ComponentTunnelRequest method will interact with another OMX
+ component to determine if tunneling is possible and to setup the
+ tunneling. The return codes for this method can be used to
+ determine if tunneling is not possible, or if tunneling is not
+ supported.
+
+ Base profile components (i.e. non-interop) do not support this
+ method and should return OMX_ErrorNotImplemented
+
+ The interop profile component MUST support tunneling to another
+ interop profile component with a compatible port parameters.
+ A component may also support proprietary communication.
+
+ If proprietary communication is supported the negotiation of
+ proprietary communication is done outside of OMX in a vendor
+ specific way. It is only required that the proper result be
+ returned and the details of how the setup is done is left
+ to the component implementation.
+
+ When this method is invoked when nPort in an output port, the
+ component will:
+ 1. Populate the pTunnelSetup structure with the output port's
+ requirements and constraints for the tunnel.
+
+ When this method is invoked when nPort in an input port, the
+ component will:
+ 1. Query the necessary parameters from the output port to
+ determine if the ports are compatible for tunneling
+ 2. If the ports are compatible, the component should store
+ the tunnel step provided by the output port
+ 3. Determine which port (either input or output) is the buffer
+ supplier, and call OMX_SetParameter on the output port to
+ indicate this selection.
+
+ The component will return from this call within 5 msec.
+
+ @param [in] hComp
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle method.
+ @param [in] nPort
+ nPort is used to select the port on the component to be used
+ for tunneling.
+ @param [in] hTunneledComp
+ Handle of the component to tunnel with. This is the component
+ handle returned by the call to the OMX_GetHandle method. When
+ this parameter is 0x0 the component should setup the port for
+ communication with the application / IL Client.
+ @param [in] nPortOutput
+ nPortOutput is used indicate the port the component should
+ tunnel with.
+ @param [in] pTunnelSetup
+ Pointer to the tunnel setup structure. When nPort is an output port
+ the component should populate the fields of this structure. When
+ When nPort is an input port the component should review the setup
+ provided by the component with the output port.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup tun
+ */
+
+ OMX_ERRORTYPE (*ComponentTunnelRequest)(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 nPort,
+ OMX_IN OMX_HANDLETYPE hTunneledComp,
+ OMX_IN OMX_U32 nTunneledPort,
+ OMX_INOUT OMX_TUNNELSETUPTYPE* pTunnelSetup);
+
+ /** refer to OMX_UseBuffer in OMX_core.h or the OMX IL
+ specification for details on the UseBuffer method.
+ @ingroup buf
+ */
+ OMX_ERRORTYPE (*UseBuffer)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+ OMX_IN OMX_U32 nPortIndex,
+ OMX_IN OMX_PTR pAppPrivate,
+ OMX_IN OMX_U32 nSizeBytes,
+ OMX_IN OMX_U8* pBuffer);
+
+ /** refer to OMX_AllocateBuffer in OMX_core.h or the OMX IL
+ specification for details on the AllocateBuffer method.
+ @ingroup buf
+ */
+ OMX_ERRORTYPE (*AllocateBuffer)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
+ OMX_IN OMX_U32 nPortIndex,
+ OMX_IN OMX_PTR pAppPrivate,
+ OMX_IN OMX_U32 nSizeBytes);
+
+ /** refer to OMX_FreeBuffer in OMX_core.h or the OMX IL
+ specification for details on the FreeBuffer method.
+ @ingroup buf
+ */
+ OMX_ERRORTYPE (*FreeBuffer)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_U32 nPortIndex,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+ /** refer to OMX_EmptyThisBuffer in OMX_core.h or the OMX IL
+ specification for details on the EmptyThisBuffer method.
+ @ingroup buf
+ */
+ OMX_ERRORTYPE (*EmptyThisBuffer)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+ /** refer to OMX_FillThisBuffer in OMX_core.h or the OMX IL
+ specification for details on the FillThisBuffer method.
+ @ingroup buf
+ */
+ OMX_ERRORTYPE (*FillThisBuffer)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+ /** The SetCallbacks method is used by the core to specify the callback
+ structure from the application to the component. This is a blocking
+ call. The component will return from this call within 5 msec.
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the GetHandle function.
+ @param [in] pCallbacks
+ pointer to an OMX_CALLBACKTYPE structure used to provide the
+ callback information to the component
+ @param [in] pAppData
+ pointer to an application defined value. It is anticipated that
+ the application will pass a pointer to a data structure or a "this
+ pointer" in this area to allow the callback (in the application)
+ to determine the context of the call
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ */
+ OMX_ERRORTYPE (*SetCallbacks)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_CALLBACKTYPE* pCallbacks,
+ OMX_IN OMX_PTR pAppData);
+
+ /** ComponentDeInit method is used to deinitialize the component
+ providing a means to free any resources allocated at component
+ initialization. NOTE: After this call the component handle is
+ not valid for further use.
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the GetHandle function.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ */
+ OMX_ERRORTYPE (*ComponentDeInit)(
+ OMX_IN OMX_HANDLETYPE hComponent);
+
+ /** @ingroup buf */
+ OMX_ERRORTYPE (*UseEGLImage)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+ OMX_IN OMX_U32 nPortIndex,
+ OMX_IN OMX_PTR pAppPrivate,
+ OMX_IN void* eglImage);
+
+ OMX_ERRORTYPE (*ComponentRoleEnum)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_U8 *cRole,
+ OMX_IN OMX_U32 nIndex);
+
+} OMX_COMPONENTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_ContentPipe.h b/msmcobalt/mm-core/inc/OMX_ContentPipe.h
new file mode 100644
index 0000000..5f6310c
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_ContentPipe.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_ContentPipe.h - OpenMax IL version 1.1.2
+ * The OMX_ContentPipe header file contains the definitions used to define
+ * the public interface for content piples. This header file is intended to
+ * be used by the component.
+ */
+
+#ifndef OMX_CONTENTPIPE_H
+#define OMX_CONTENTPIPE_H
+
+#ifndef KD_EACCES
+/* OpenKODE error codes. CPResult values may be zero (indicating success
+ or one of the following values) */
+#define KD_EACCES (1)
+#define KD_EADDRINUSE (2)
+#define KD_EAGAIN (5)
+#define KD_EBADF (7)
+#define KD_EBUSY (8)
+#define KD_ECONNREFUSED (9)
+#define KD_ECONNRESET (10)
+#define KD_EDEADLK (11)
+#define KD_EDESTADDRREQ (12)
+#define KD_ERANGE (35)
+#define KD_EEXIST (13)
+#define KD_EFBIG (14)
+#define KD_EHOSTUNREACH (15)
+#define KD_EINVAL (17)
+#define KD_EIO (18)
+#define KD_EISCONN (20)
+#define KD_EISDIR (21)
+#define KD_EMFILE (22)
+#define KD_ENAMETOOLONG (23)
+#define KD_ENOENT (24)
+#define KD_ENOMEM (25)
+#define KD_ENOSPC (26)
+#define KD_ENOSYS (27)
+#define KD_ENOTCONN (28)
+#define KD_EPERM (33)
+#define KD_ETIMEDOUT (36)
+#define KD_EILSEQ (19)
+#endif
+
+/** Map types from OMX standard types only here so interface is as generic as possible. */
+typedef OMX_U32 CPresult;
+typedef char * CPstring;
+typedef void * CPhandle;
+typedef OMX_U32 CPuint;
+typedef OMX_S32 CPint;
+typedef char CPbyte;
+typedef OMX_BOOL CPbool;
+
+/** enumeration of origin types used in the CP_PIPETYPE's Seek function
+ * @ingroup cp
+ */
+typedef enum CP_ORIGINTYPE {
+ CP_OriginBegin,
+ CP_OriginCur,
+ CP_OriginEnd,
+ CP_OriginKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ CP_OriginVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ CP_OriginMax = 0X7FFFFFFF
+} CP_ORIGINTYPE;
+
+/** enumeration of contact access types used in the CP_PIPETYPE's Open function
+ * @ingroup cp
+ */
+typedef enum CP_ACCESSTYPE {
+ CP_AccessRead,
+ CP_AccessWrite,
+ CP_AccessReadWrite ,
+ CP_AccessKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ CP_AccessVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ CP_AccessMax = 0X7FFFFFFF
+} CP_ACCESSTYPE;
+
+/** enumeration of results returned by the CP_PIPETYPE's CheckAvailableBytes function
+ * @ingroup cp
+ */
+typedef enum CP_CHECKBYTESRESULTTYPE
+{
+ CP_CheckBytesOk, /**< There are at least the request number
+ of bytes available */
+ CP_CheckBytesNotReady, /**< The pipe is still retrieving bytes
+ and presently lacks sufficient bytes.
+ Client will be called when they are
+ sufficient bytes are available. */
+ CP_CheckBytesInsufficientBytes , /**< The pipe has retrieved all bytes
+ but those available are less than those
+ requested */
+ CP_CheckBytesAtEndOfStream, /**< The pipe has reached the end of stream
+ and no more bytes are available. */
+ CP_CheckBytesOutOfBuffers, /**< All read/write buffers are currently in use. */
+ CP_CheckBytesKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ CP_CheckBytesVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ CP_CheckBytesMax = 0X7FFFFFFF
+} CP_CHECKBYTESRESULTTYPE;
+
+/** enumeration of content pipe events sent to the client callback.
+ * @ingroup cp
+ */
+typedef enum CP_EVENTTYPE{
+ CP_BytesAvailable, /** bytes requested in a CheckAvailableBytes call are now available*/
+ CP_Overflow, /** enumeration of content pipe events sent to the client callback*/
+ CP_PipeDisconnected , /** enumeration of content pipe events sent to the client callback*/
+ CP_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ CP_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ CP_EventMax = 0X7FFFFFFF
+} CP_EVENTTYPE;
+
+/** content pipe definition
+ * @ingroup cp
+ */
+typedef struct CP_PIPETYPE
+{
+ /** Open a content stream for reading or writing. */
+ CPresult (*Open)( CPhandle* hContent, CPstring szURI, CP_ACCESSTYPE eAccess );
+
+ /** Close a content stream. */
+ CPresult (*Close)( CPhandle hContent );
+
+ /** Create a content source and open it for writing. */
+ CPresult (*Create)( CPhandle *hContent, CPstring szURI );
+
+ /** Check the that specified number of bytes are available for reading or writing (depending on access type).*/
+ CPresult (*CheckAvailableBytes)( CPhandle hContent, CPuint nBytesRequested, CP_CHECKBYTESRESULTTYPE *eResult );
+
+ /** Seek to certain position in the content relative to the specified origin. */
+ CPresult (*SetPosition)( CPhandle hContent, CPint nOffset, CP_ORIGINTYPE eOrigin);
+
+ /** Retrieve the current position relative to the start of the content. */
+ CPresult (*GetPosition)( CPhandle hContent, CPuint *pPosition);
+
+ /** Retrieve data of the specified size from the content stream (advance content pointer by size of data).
+ Note: pipe client provides pointer. This function is appropriate for small high frequency reads. */
+ CPresult (*Read)( CPhandle hContent, CPbyte *pData, CPuint nSize);
+
+ /** Retrieve a buffer allocated by the pipe that contains the requested number of bytes.
+ Buffer contains the next block of bytes, as specified by nSize, of the content. nSize also
+ returns the size of the block actually read. Content pointer advances the by the returned size.
+ Note: pipe provides pointer. This function is appropriate for large reads. The client must call
+ ReleaseReadBuffer when done with buffer.
+
+ In some cases the requested block may not reside in contiguous memory within the
+ pipe implementation. For instance if the pipe leverages a circular buffer then the requested
+ block may straddle the boundary of the circular buffer. By default a pipe implementation
+ performs a copy in this case to provide the block to the pipe client in one contiguous buffer.
+ If, however, the client sets bForbidCopy, then the pipe returns only those bytes preceding the memory
+ boundary. Here the client may retrieve the data in segments over successive calls. */
+ CPresult (*ReadBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint *nSize, CPbool bForbidCopy);
+
+ /** Release a buffer obtained by ReadBuffer back to the pipe. */
+ CPresult (*ReleaseReadBuffer)(CPhandle hContent, CPbyte *pBuffer);
+
+ /** Write data of the specified size to the content (advance content pointer by size of data).
+ Note: pipe client provides pointer. This function is appropriate for small high frequency writes. */
+ CPresult (*Write)( CPhandle hContent, CPbyte *data, CPuint nSize);
+
+ /** Retrieve a buffer allocated by the pipe used to write data to the content.
+ Client will fill buffer with output data. Note: pipe provides pointer. This function is appropriate
+ for large writes. The client must call WriteBuffer when done it has filled the buffer with data.*/
+ CPresult (*GetWriteBuffer)( CPhandle hContent, CPbyte **ppBuffer, CPuint nSize);
+
+ /** Deliver a buffer obtained via GetWriteBuffer to the pipe. Pipe will write the
+ the contents of the buffer to content and advance content pointer by the size of the buffer */
+ CPresult (*WriteBuffer)( CPhandle hContent, CPbyte *pBuffer, CPuint nFilledSize);
+
+ /** Register a per-handle client callback with the content pipe. */
+ CPresult (*RegisterCallback)( CPhandle hContent, CPresult (*ClientCallback)(CP_EVENTTYPE eEvent, CPuint iParam));
+
+} CP_PIPETYPE;
+
+#endif
+
diff --git a/msmcobalt/mm-core/inc/OMX_Core.h b/msmcobalt/mm-core/inc/OMX_Core.h
new file mode 100644
index 0000000..52d211f
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Core.h
@@ -0,0 +1,1440 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_Core.h - OpenMax IL version 1.1.2
+ * The OMX_Core header file contains the definitions used by both the
+ * application and the component to access common items.
+ */
+
+#ifndef OMX_Core_h
+#define OMX_Core_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_Index.h>
+
+
+/** The OMX_COMMANDTYPE enumeration is used to specify the action in the
+ * OMX_SendCommand macro.
+ * @ingroup core
+ */
+typedef enum OMX_COMMANDTYPE
+{
+ OMX_CommandStateSet, /**< Change the component state */
+ OMX_CommandFlush, /**< Flush the data queue(s) of a component */
+ OMX_CommandPortDisable, /**< Disable a port on a component. */
+ OMX_CommandPortEnable, /**< Enable a port on a component. */
+ OMX_CommandMarkBuffer, /**< Mark a component/buffer for observation */
+ OMX_CommandKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_CommandVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_CommandMax = 0X7FFFFFFF
+} OMX_COMMANDTYPE;
+
+
+
+/** The OMX_STATETYPE enumeration is used to indicate or change the component
+ * state. This enumeration reflects the current state of the component when
+ * used with the OMX_GetState macro or becomes the parameter in a state change
+ * command when used with the OMX_SendCommand macro.
+ *
+ * The component will be in the Loaded state after the component is initially
+ * loaded into memory. In the Loaded state, the component is not allowed to
+ * allocate or hold resources other than to build it's internal parameter
+ * and configuration tables. The application will send one or more
+ * SetParameters/GetParameters and SetConfig/GetConfig commands to the
+ * component and the component will record each of these parameter and
+ * configuration changes for use later. When the application sends the
+ * Idle command, the component will acquire the resources needed for the
+ * specified configuration and will transition to the idle state if the
+ * allocation is successful. If the component cannot successfully
+ * transition to the idle state for any reason, the state of the component
+ * shall be fully rolled back to the Loaded state (e.g. all allocated
+ * resources shall be released). When the component receives the command
+ * to go to the Executing state, it shall begin processing buffers by
+ * sending all input buffers it holds to the application. While
+ * the component is in the Idle state, the application may also send the
+ * Pause command. If the component receives the pause command while in the
+ * Idle state, the component shall send all input buffers it holds to the
+ * application, but shall not begin processing buffers. This will allow the
+ * application to prefill buffers.
+ *
+ * @ingroup comp
+ */
+
+typedef enum OMX_STATETYPE
+{
+ OMX_StateInvalid, /**< component has detected that it's internal data
+ structures are corrupted to the point that
+ it cannot determine it's state properly */
+ OMX_StateLoaded, /**< component has been loaded but has not completed
+ initialization. The OMX_SetParameter macro
+ and the OMX_GetParameter macro are the only
+ valid macros allowed to be sent to the
+ component in this state. */
+ OMX_StateIdle, /**< component initialization has been completed
+ successfully and the component is ready to
+ to start. */
+ OMX_StateExecuting, /**< component has accepted the start command and
+ is processing data (if data is available) */
+ OMX_StatePause, /**< component has received pause command */
+ OMX_StateWaitForResources, /**< component is waiting for resources, either after
+ preemption or before it gets the resources requested.
+ See specification for complete details. */
+ OMX_StateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_StateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_StateMax = 0X7FFFFFFF
+} OMX_STATETYPE;
+
+/** The OMX_ERRORTYPE enumeration defines the standard OMX Errors. These
+ * errors should cover most of the common failure cases. However,
+ * vendors are free to add additional error messages of their own as
+ * long as they follow these rules:
+ * 1. Vendor error messages shall be in the range of 0x90000000 to
+ * 0x9000FFFF.
+ * 2. Vendor error messages shall be defined in a header file provided
+ * with the component. No error messages are allowed that are
+ * not defined.
+ */
+typedef enum OMX_ERRORTYPE
+{
+ OMX_ErrorNone = 0,
+
+ /** There were insufficient resources to perform the requested operation */
+ OMX_ErrorInsufficientResources = (OMX_S32) 0x80001000,
+
+ /** There was an error, but the cause of the error could not be determined */
+ OMX_ErrorUndefined = (OMX_S32) 0x80001001,
+
+ /** The component name string was not valid */
+ OMX_ErrorInvalidComponentName = (OMX_S32) 0x80001002,
+
+ /** No component with the specified name string was found */
+ OMX_ErrorComponentNotFound = (OMX_S32) 0x80001003,
+
+ /** The component specified did not have a "OMX_ComponentInit" or
+ "OMX_ComponentDeInit entry point */
+ OMX_ErrorInvalidComponent = (OMX_S32) 0x80001004,
+
+ /** One or more parameters were not valid */
+ OMX_ErrorBadParameter = (OMX_S32) 0x80001005,
+
+ /** The requested function is not implemented */
+ OMX_ErrorNotImplemented = (OMX_S32) 0x80001006,
+
+ /** The buffer was emptied before the next buffer was ready */
+ OMX_ErrorUnderflow = (OMX_S32) 0x80001007,
+
+ /** The buffer was not available when it was needed */
+ OMX_ErrorOverflow = (OMX_S32) 0x80001008,
+
+ /** The hardware failed to respond as expected */
+ OMX_ErrorHardware = (OMX_S32) 0x80001009,
+
+ /** The component is in the state OMX_StateInvalid */
+ OMX_ErrorInvalidState = (OMX_S32) 0x8000100A,
+
+ /** Stream is found to be corrupt */
+ OMX_ErrorStreamCorrupt = (OMX_S32) 0x8000100B,
+
+ /** Ports being connected are not compatible */
+ OMX_ErrorPortsNotCompatible = (OMX_S32) 0x8000100C,
+
+ /** Resources allocated to an idle component have been
+ lost resulting in the component returning to the loaded state */
+ OMX_ErrorResourcesLost = (OMX_S32) 0x8000100D,
+
+ /** No more indicies can be enumerated */
+ OMX_ErrorNoMore = (OMX_S32) 0x8000100E,
+
+ /** The component detected a version mismatch */
+ OMX_ErrorVersionMismatch = (OMX_S32) 0x8000100F,
+
+ /** The component is not ready to return data at this time */
+ OMX_ErrorNotReady = (OMX_S32) 0x80001010,
+
+ /** There was a timeout that occurred */
+ OMX_ErrorTimeout = (OMX_S32) 0x80001011,
+
+ /** This error occurs when trying to transition into the state you are already in */
+ OMX_ErrorSameState = (OMX_S32) 0x80001012,
+
+ /** Resources allocated to an executing or paused component have been
+ preempted, causing the component to return to the idle state */
+ OMX_ErrorResourcesPreempted = (OMX_S32) 0x80001013,
+
+ /** A non-supplier port sends this error to the IL client (via the EventHandler callback)
+ during the allocation of buffers (on a transition from the LOADED to the IDLE state or
+ on a port restart) when it deems that it has waited an unusually long time for the supplier
+ to send it an allocated buffer via a UseBuffer call. */
+ OMX_ErrorPortUnresponsiveDuringAllocation = (OMX_S32) 0x80001014,
+
+ /** A non-supplier port sends this error to the IL client (via the EventHandler callback)
+ during the deallocation of buffers (on a transition from the IDLE to LOADED state or
+ on a port stop) when it deems that it has waited an unusually long time for the supplier
+ to request the deallocation of a buffer header via a FreeBuffer call. */
+ OMX_ErrorPortUnresponsiveDuringDeallocation = (OMX_S32) 0x80001015,
+
+ /** A supplier port sends this error to the IL client (via the EventHandler callback)
+ during the stopping of a port (either on a transition from the IDLE to LOADED
+ state or a port stop) when it deems that it has waited an unusually long time for
+ the non-supplier to return a buffer via an EmptyThisBuffer or FillThisBuffer call. */
+ OMX_ErrorPortUnresponsiveDuringStop = (OMX_S32) 0x80001016,
+
+ /** Attempting a state transtion that is not allowed */
+ OMX_ErrorIncorrectStateTransition = (OMX_S32) 0x80001017,
+
+ /* Attempting a command that is not allowed during the present state. */
+ OMX_ErrorIncorrectStateOperation = (OMX_S32) 0x80001018,
+
+ /** The values encapsulated in the parameter or config structure are not supported. */
+ OMX_ErrorUnsupportedSetting = (OMX_S32) 0x80001019,
+
+ /** The parameter or config indicated by the given index is not supported. */
+ OMX_ErrorUnsupportedIndex = (OMX_S32) 0x8000101A,
+
+ /** The port index supplied is incorrect. */
+ OMX_ErrorBadPortIndex = (OMX_S32) 0x8000101B,
+
+ /** The port has lost one or more of its buffers and it thus unpopulated. */
+ OMX_ErrorPortUnpopulated = (OMX_S32) 0x8000101C,
+
+ /** Component suspended due to temporary loss of resources */
+ OMX_ErrorComponentSuspended = (OMX_S32) 0x8000101D,
+
+ /** Component suspended due to an inability to acquire dynamic resources */
+ OMX_ErrorDynamicResourcesUnavailable = (OMX_S32) 0x8000101E,
+
+ /** When the macroblock error reporting is enabled the component returns new error
+ for every frame that has errors */
+ OMX_ErrorMbErrorsInFrame = (OMX_S32) 0x8000101F,
+
+ /** A component reports this error when it cannot parse or determine the format of an input stream. */
+ OMX_ErrorFormatNotDetected = (OMX_S32) 0x80001020,
+
+ /** The content open operation failed. */
+ OMX_ErrorContentPipeOpenFailed = (OMX_S32) 0x80001021,
+
+ /** The content creation operation failed. */
+ OMX_ErrorContentPipeCreationFailed = (OMX_S32) 0x80001022,
+
+ /** Separate table information is being used */
+ OMX_ErrorSeperateTablesUsed = (OMX_S32) 0x80001023,
+
+ /** Tunneling is unsupported by the component*/
+ OMX_ErrorTunnelingUnsupported = (OMX_S32) 0x80001024,
+
+ OMX_ErrorKhronosExtensions = (OMX_S32)0x8F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ErrorVendorStartUnused = (OMX_S32)0x90000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_ErrorMax = 0x7FFFFFFF
+} OMX_ERRORTYPE;
+
+/** @ingroup core */
+typedef OMX_ERRORTYPE (* OMX_COMPONENTINITTYPE)(OMX_IN OMX_HANDLETYPE hComponent);
+
+/** @ingroup core */
+typedef struct OMX_COMPONENTREGISTERTYPE
+{
+ const char * pName; /* Component name, 128 byte limit (including '\0') applies */
+ OMX_COMPONENTINITTYPE pInitialize; /* Component instance initialization function */
+} OMX_COMPONENTREGISTERTYPE;
+
+/** @ingroup core */
+extern OMX_COMPONENTREGISTERTYPE OMX_ComponentRegistered[];
+
+/** @ingroup rpm */
+typedef struct OMX_PRIORITYMGMTTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nGroupPriority; /**< Priority of the component group */
+ OMX_U32 nGroupID; /**< ID of the component group */
+} OMX_PRIORITYMGMTTYPE;
+
+/* Component name and Role names are limited to 128 characters including the terminating '\0'. */
+#define OMX_MAX_STRINGNAME_SIZE 128
+
+/** @ingroup comp */
+typedef struct OMX_PARAM_COMPONENTROLETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U8 cRole[OMX_MAX_STRINGNAME_SIZE]; /**< name of standard component which defines component role */
+} OMX_PARAM_COMPONENTROLETYPE;
+
+/** End of Stream Buffer Flag:
+ *
+ * A component sets EOS when it has no more data to emit on a particular
+ * output port. Thus an output port shall set EOS on the last buffer it
+ * emits. A component's determination of when an output port should
+ * cease sending data is implemenation specific.
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_EOS 0x00000001
+
+/** Start Time Buffer Flag:
+ *
+ * The source of a stream (e.g. a demux component) sets the STARTTIME
+ * flag on the buffer that contains the starting timestamp for the
+ * stream. The starting timestamp corresponds to the first data that
+ * should be displayed at startup or after a seek.
+ * The first timestamp of the stream is not necessarily the start time.
+ * For instance, in the case of a seek to a particular video frame,
+ * the target frame may be an interframe. Thus the first buffer of
+ * the stream will be the intra-frame preceding the target frame and
+ * the starttime will occur with the target frame (with any other
+ * required frames required to reconstruct the target intervening).
+ *
+ * The STARTTIME flag is directly associated with the buffer's
+ * timestamp ' thus its association to buffer data and its
+ * propagation is identical to the timestamp's.
+ *
+ * When a Sync Component client receives a buffer with the
+ * STARTTIME flag it shall perform a SetConfig on its sync port
+ * using OMX_ConfigTimeClientStartTime and passing the buffer's
+ * timestamp.
+ *
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_STARTTIME 0x00000002
+
+
+
+/** Decode Only Buffer Flag:
+ *
+ * The source of a stream (e.g. a demux component) sets the DECODEONLY
+ * flag on any buffer that should shall be decoded but should not be
+ * displayed. This flag is used, for instance, when a source seeks to
+ * a target interframe that requires the decode of frames preceding the
+ * target to facilitate the target's reconstruction. In this case the
+ * source would emit the frames preceding the target downstream
+ * but mark them as decode only.
+ *
+ * The DECODEONLY is associated with buffer data and propagated in a
+ * manner identical to the buffer timestamp.
+ *
+ * A component that renders data should ignore all buffers with
+ * the DECODEONLY flag set.
+ *
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_DECODEONLY 0x00000004
+
+
+/* Data Corrupt Flag: This flag is set when the IL client believes the data in the associated buffer is corrupt
+ * @ingroup buf
+ */
+
+#define OMX_BUFFERFLAG_DATACORRUPT 0x00000008
+
+/* End of Frame: The buffer contains exactly one end of frame and no data
+ * occurs after the end of frame. This flag is an optional hint. The absence
+ * of this flag does not imply the absence of an end of frame within the buffer.
+ * @ingroup buf
+*/
+#define OMX_BUFFERFLAG_ENDOFFRAME 0x00000010
+
+/* Sync Frame Flag: This flag is set when the buffer content contains a coded sync frame '
+ * a frame that has no dependency on any other frame information
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_SYNCFRAME 0x00000020
+
+/* Extra data present flag: there is extra data appended to the data stream
+ * residing in the buffer
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_EXTRADATA 0x00000040
+
+/** Codec Config Buffer Flag:
+* OMX_BUFFERFLAG_CODECCONFIG is an optional flag that is set by an
+* output port when all bytes in the buffer form part or all of a set of
+* codec specific configuration data. Examples include SPS/PPS nal units
+* for OMX_VIDEO_CodingAVC or AudioSpecificConfig data for
+* OMX_AUDIO_CodingAAC. Any component that for a given stream sets
+* OMX_BUFFERFLAG_CODECCONFIG shall not mix codec configuration bytes
+* with frame data in the same buffer, and shall send all buffers
+* containing codec configuration bytes before any buffers containing
+* frame data that those configurations bytes describe.
+* If the stream format for a particular codec has a frame specific
+* header at the start of each frame, for example OMX_AUDIO_CodingMP3 or
+* OMX_AUDIO_CodingAAC in ADTS mode, then these shall be presented as
+* normal without setting OMX_BUFFERFLAG_CODECCONFIG.
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_CODECCONFIG 0x00000080
+
+/*
+* OMX_BUFFERFLAG_READONLY: This flag is set when a component emitting the
+* buffer on an output port or the IL client wishes to identify the buffer
+* payload contents to be read-only. An IL client or an input port
+* shall not alter the contents of the buffer. This flag shall only be
+* cleared by the originator of the buffer when the buffer is returned.
+* For tunneled ports, the usage of this flag shall be allowed only if the
+* components negotiated a read-only tunnel
+*/
+#define OMX_BUFFERFLAG_READONLY 0x00000200
+
+/** @ingroup buf */
+typedef struct OMX_BUFFERHEADERTYPE
+{
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U8* pBuffer; /**< Pointer to actual block of memory
+ that is acting as the buffer */
+ OMX_U32 nAllocLen; /**< size of the buffer allocated, in bytes */
+ OMX_U32 nFilledLen; /**< number of bytes currently in the
+ buffer */
+ OMX_U32 nOffset; /**< start offset of valid data in bytes from
+ the start of the buffer */
+ OMX_PTR pAppPrivate; /**< pointer to any data the application
+ wants to associate with this buffer */
+ OMX_PTR pPlatformPrivate; /**< pointer to any data the platform
+ wants to associate with this buffer */
+ OMX_PTR pInputPortPrivate; /**< pointer to any data the input port
+ wants to associate with this buffer */
+ OMX_PTR pOutputPortPrivate; /**< pointer to any data the output port
+ wants to associate with this buffer */
+ OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will generate a
+ mark event upon processing this buffer. */
+ OMX_PTR pMarkData; /**< Application specific data associated with
+ the mark sent on a mark event to disambiguate
+ this mark from others. */
+ OMX_U32 nTickCount; /**< Optional entry that the component and
+ application can update with a tick count
+ when they access the component. This
+ value should be in microseconds. Since
+ this is a value relative to an arbitrary
+ starting point, this value cannot be used
+ to determine absolute time. This is an
+ optional entry and not all components
+ will update it.*/
+ OMX_TICKS nTimeStamp; /**< Timestamp corresponding to the sample
+ starting at the first logical sample
+ boundary in the buffer. Timestamps of
+ successive samples within the buffer may
+ be inferred by adding the duration of the
+ of the preceding buffer to the timestamp
+ of the preceding buffer.*/
+ OMX_U32 nFlags; /**< buffer specific flags */
+ OMX_U32 nOutputPortIndex; /**< The index of the output port (if any) using
+ this buffer */
+ OMX_U32 nInputPortIndex; /**< The index of the input port (if any) using
+ this buffer */
+} OMX_BUFFERHEADERTYPE;
+
+/** The OMX_EXTRADATATYPE enumeration is used to define the
+ * possible extra data payload types.
+ * NB: this enum is binary backwards compatible with the previous
+ * OMX_EXTRADATA_QUANT define. This should be replaced with
+ * OMX_ExtraDataQuantization.
+ */
+typedef enum OMX_EXTRADATATYPE
+{
+ OMX_ExtraDataNone = 0, /**< Indicates that no more extra data sections follow */
+ OMX_ExtraDataQuantization, /**< The data payload contains quantization data */
+ OMX_ExtraDataKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ExtraDataVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_ExtraDataMax = 0x7FFFFFFF
+} OMX_EXTRADATATYPE;
+
+
+typedef struct OMX_OTHER_EXTRADATATYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_EXTRADATATYPE eType; /* Extra Data type */
+ OMX_U32 nDataSize; /* Size of the supporting data to follow */
+ OMX_U8 data[1]; /* Supporting data hint */
+} OMX_OTHER_EXTRADATATYPE;
+
+/** @ingroup comp */
+typedef struct OMX_PORT_PARAM_TYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPorts; /**< The number of ports for this component */
+ OMX_U32 nStartPortNumber; /** first port number for this type of port */
+} OMX_PORT_PARAM_TYPE;
+
+/** @ingroup comp */
+typedef enum OMX_EVENTTYPE
+{
+ OMX_EventCmdComplete, /**< component has sucessfully completed a command */
+ OMX_EventError, /**< component has detected an error condition */
+ OMX_EventMark, /**< component has detected a buffer mark */
+ OMX_EventPortSettingsChanged, /**< component is reported a port settings change */
+ OMX_EventBufferFlag, /**< component has detected an EOS */
+ OMX_EventResourcesAcquired, /**< component has been granted resources and is
+ automatically starting the state change from
+ OMX_StateWaitForResources to OMX_StateIdle. */
+ OMX_EventComponentResumed, /**< Component resumed due to reacquisition of resources */
+ OMX_EventDynamicResourcesAvailable, /**< Component has acquired previously unavailable dynamic resources */
+ OMX_EventPortFormatDetected, /**< Component has detected a supported format. */
+ OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_EventMax = 0x7FFFFFFF
+} OMX_EVENTTYPE;
+
+typedef struct OMX_CALLBACKTYPE
+{
+ /** The EventHandler method is used to notify the application when an
+ event of interest occurs. Events are defined in the OMX_EVENTTYPE
+ enumeration. Please see that enumeration for details of what will
+ be returned for each type of event. Callbacks should not return
+ an error to the component, so if an error occurs, the application
+ shall handle it internally. This is a blocking call.
+
+ The application should return from this call within 5 msec to avoid
+ blocking the component for an excessively long period of time.
+
+ @param hComponent
+ handle of the component to access. This is the component
+ handle returned by the call to the GetHandle function.
+ @param pAppData
+ pointer to an application defined value that was provided in the
+ pAppData parameter to the OMX_GetHandle method for the component.
+ This application defined value is provided so that the application
+ can have a component specific context when receiving the callback.
+ @param eEvent
+ Event that the component wants to notify the application about.
+ @param nData1
+ nData will be the OMX_ERRORTYPE for an error event and will be
+ an OMX_COMMANDTYPE for a command complete event and OMX_INDEXTYPE for a OMX_PortSettingsChanged event.
+ @param nData2
+ nData2 will hold further information related to the event. Can be OMX_STATETYPE for
+ a OMX_CommandStateSet command or port index for a OMX_PortSettingsChanged event.
+ Default value is 0 if not used. )
+ @param pEventData
+ Pointer to additional event-specific data (see spec for meaning).
+ */
+
+ OMX_ERRORTYPE (*EventHandler)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_PTR pAppData,
+ OMX_IN OMX_EVENTTYPE eEvent,
+ OMX_IN OMX_U32 nData1,
+ OMX_IN OMX_U32 nData2,
+ OMX_IN OMX_PTR pEventData);
+
+ /** The EmptyBufferDone method is used to return emptied buffers from an
+ input port back to the application for reuse. This is a blocking call
+ so the application should not attempt to refill the buffers during this
+ call, but should queue them and refill them in another thread. There
+ is no error return, so the application shall handle any errors generated
+ internally.
+
+ The application should return from this call within 5 msec.
+
+ @param hComponent
+ handle of the component to access. This is the component
+ handle returned by the call to the GetHandle function.
+ @param pAppData
+ pointer to an application defined value that was provided in the
+ pAppData parameter to the OMX_GetHandle method for the component.
+ This application defined value is provided so that the application
+ can have a component specific context when receiving the callback.
+ @param pBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+ or AllocateBuffer indicating the buffer that was emptied.
+ @ingroup buf
+ */
+ OMX_ERRORTYPE (*EmptyBufferDone)(
+ OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_PTR pAppData,
+ OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+ /** The FillBufferDone method is used to return filled buffers from an
+ output port back to the application for emptying and then reuse.
+ This is a blocking call so the application should not attempt to
+ empty the buffers during this call, but should queue the buffers
+ and empty them in another thread. There is no error return, so
+ the application shall handle any errors generated internally. The
+ application shall also update the buffer header to indicate the
+ number of bytes placed into the buffer.
+
+ The application should return from this call within 5 msec.
+
+ @param hComponent
+ handle of the component to access. This is the component
+ handle returned by the call to the GetHandle function.
+ @param pAppData
+ pointer to an application defined value that was provided in the
+ pAppData parameter to the OMX_GetHandle method for the component.
+ This application defined value is provided so that the application
+ can have a component specific context when receiving the callback.
+ @param pBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+ or AllocateBuffer indicating the buffer that was filled.
+ @ingroup buf
+ */
+ OMX_ERRORTYPE (*FillBufferDone)(
+ OMX_OUT OMX_HANDLETYPE hComponent,
+ OMX_OUT OMX_PTR pAppData,
+ OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
+
+} OMX_CALLBACKTYPE;
+
+/** The OMX_BUFFERSUPPLIERTYPE enumeration is used to dictate port supplier
+ preference when tunneling between two ports.
+ @ingroup tun buf
+*/
+typedef enum OMX_BUFFERSUPPLIERTYPE
+{
+ OMX_BufferSupplyUnspecified = 0x0, /**< port supplying the buffers is unspecified,
+ or don't care */
+ OMX_BufferSupplyInput, /**< input port supplies the buffers */
+ OMX_BufferSupplyOutput, /**< output port supplies the buffers */
+ OMX_BufferSupplyKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_BufferSupplyVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_BufferSupplyMax = 0x7FFFFFFF
+} OMX_BUFFERSUPPLIERTYPE;
+
+
+/** buffer supplier parameter
+ * @ingroup tun
+ */
+typedef struct OMX_PARAM_BUFFERSUPPLIERTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_BUFFERSUPPLIERTYPE eBufferSupplier; /**< buffer supplier */
+} OMX_PARAM_BUFFERSUPPLIERTYPE;
+
+
+/**< indicates that buffers received by an input port of a tunnel
+ may not modify the data in the buffers
+ @ingroup tun
+ */
+#define OMX_PORTTUNNELFLAG_READONLY 0x00000001
+
+
+/** The OMX_TUNNELSETUPTYPE structure is used to pass data from an output
+ port to an input port as part the two ComponentTunnelRequest calls
+ resulting from a OMX_SetupTunnel call from the IL Client.
+ @ingroup tun
+ */
+typedef struct OMX_TUNNELSETUPTYPE
+{
+ OMX_U32 nTunnelFlags; /**< bit flags for tunneling */
+ OMX_BUFFERSUPPLIERTYPE eSupplier; /**< supplier preference */
+} OMX_TUNNELSETUPTYPE;
+
+/* OMX Component headers is included to enable the core to use
+ macros for functions into the component for OMX release 1.0.
+ Developers should not access any structures or data from within
+ the component header directly */
+/* TO BE REMOVED - #include <OMX_Component.h> */
+
+/** GetComponentVersion will return information about the component.
+ This is a blocking call. This macro will go directly from the
+ application to the component (via a core macro). The
+ component will return from this call within 5 msec.
+ @param [in] hComponent
+ handle of component to execute the command
+ @param [out] pComponentName
+ pointer to an empty string of length 128 bytes. The component
+ will write its name into this string. The name will be
+ terminated by a single zero byte. The name of a component will
+ be 127 bytes or less to leave room for the trailing zero byte.
+ An example of a valid component name is "OMX.ABC.ChannelMixer\0".
+ @param [out] pComponentVersion
+ pointer to an OMX Version structure that the component will fill
+ in. The component will fill in a value that indicates the
+ component version. NOTE: the component version is NOT the same
+ as the OMX Specification version (found in all structures). The
+ component version is defined by the vendor of the component and
+ its value is entirely up to the component vendor.
+ @param [out] pSpecVersion
+ pointer to an OMX Version structure that the component will fill
+ in. The SpecVersion is the version of the specification that the
+ component was built against. Please note that this value may or
+ may not match the structure's version. For example, if the
+ component was built against the 2.0 specification, but the
+ application (which creates the structure is built against the
+ 1.0 specification the versions would be different.
+ @param [out] pComponentUUID
+ pointer to the UUID of the component which will be filled in by
+ the component. The UUID is a unique identifier that is set at
+ RUN time for the component and is unique to each instantion of
+ the component.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+ */
+#define OMX_GetComponentVersion( \
+ hComponent, \
+ pComponentName, \
+ pComponentVersion, \
+ pSpecVersion, \
+ pComponentUUID) \
+ ((OMX_COMPONENTTYPE*)hComponent)->GetComponentVersion( \
+ hComponent, \
+ pComponentName, \
+ pComponentVersion, \
+ pSpecVersion, \
+ pComponentUUID) /* Macro End */
+
+
+/** Send a command to the component. This call is a non-blocking call.
+ The component should check the parameters and then queue the command
+ to the component thread to be executed. The component thread shall
+ send the EventHandler() callback at the conclusion of the command.
+ This macro will go directly from the application to the component (via
+ a core macro). The component will return from this call within 5 msec.
+
+ When the command is "OMX_CommandStateSet" the component will queue a
+ state transition to the new state idenfied in nParam.
+
+ When the command is "OMX_CommandFlush", to flush a port's buffer queues,
+ the command will force the component to return all buffers NOT CURRENTLY
+ BEING PROCESSED to the application, in the order in which the buffers
+ were received.
+
+ When the command is "OMX_CommandPortDisable" or
+ "OMX_CommandPortEnable", the component's port (given by the value of
+ nParam) will be stopped or restarted.
+
+ When the command "OMX_CommandMarkBuffer" is used to mark a buffer, the
+ pCmdData will point to a OMX_MARKTYPE structure containing the component
+ handle of the component to examine the buffer chain for the mark. nParam1
+ contains the index of the port on which the buffer mark is applied.
+
+ Specification text for more details.
+
+ @param [in] hComponent
+ handle of component to execute the command
+ @param [in] Cmd
+ Command for the component to execute
+ @param [in] nParam
+ Parameter for the command to be executed. When Cmd has the value
+ OMX_CommandStateSet, value is a member of OMX_STATETYPE. When Cmd has
+ the value OMX_CommandFlush, value of nParam indicates which port(s)
+ to flush. -1 is used to flush all ports a single port index will
+ only flush that port. When Cmd has the value "OMX_CommandPortDisable"
+ or "OMX_CommandPortEnable", the component's port is given by
+ the value of nParam. When Cmd has the value "OMX_CommandMarkBuffer"
+ the components pot is given by the value of nParam.
+ @param [in] pCmdData
+ Parameter pointing to the OMX_MARKTYPE structure when Cmd has the value
+ "OMX_CommandMarkBuffer".
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+ */
+#define OMX_SendCommand( \
+ hComponent, \
+ Cmd, \
+ nParam, \
+ pCmdData) \
+ ((OMX_COMPONENTTYPE*)hComponent)->SendCommand( \
+ hComponent, \
+ Cmd, \
+ nParam, \
+ pCmdData) /* Macro End */
+
+
+/** The OMX_GetParameter macro will get one of the current parameter
+ settings from the component. This macro cannot only be invoked when
+ the component is in the OMX_StateInvalid state. The nParamIndex
+ parameter is used to indicate which structure is being requested from
+ the component. The application shall allocate the correct structure
+ and shall fill in the structure size and version information before
+ invoking this macro. When the parameter applies to a port, the
+ caller shall fill in the appropriate nPortIndex value indicating the
+ port on which the parameter applies. If the component has not had
+ any settings changed, then the component should return a set of
+ valid DEFAULT parameters for the component. This is a blocking
+ call.
+
+ The component should return from this call within 20 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [in] nParamIndex
+ Index of the structure to be filled. This value is from the
+ OMX_INDEXTYPE enumeration.
+ @param [in,out] pComponentParameterStructure
+ Pointer to application allocated structure to be filled by the
+ component.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+ */
+#define OMX_GetParameter( \
+ hComponent, \
+ nParamIndex, \
+ pComponentParameterStructure) \
+ ((OMX_COMPONENTTYPE*)hComponent)->GetParameter( \
+ hComponent, \
+ nParamIndex, \
+ pComponentParameterStructure) /* Macro End */
+
+
+/** The OMX_SetParameter macro will send an initialization parameter
+ structure to a component. Each structure shall be sent one at a time,
+ in a separate invocation of the macro. This macro can only be
+ invoked when the component is in the OMX_StateLoaded state, or the
+ port is disabled (when the parameter applies to a port). The
+ nParamIndex parameter is used to indicate which structure is being
+ passed to the component. The application shall allocate the
+ correct structure and shall fill in the structure size and version
+ information (as well as the actual data) before invoking this macro.
+ The application is free to dispose of this structure after the call
+ as the component is required to copy any data it shall retain. This
+ is a blocking call.
+
+ The component should return from this call within 20 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [in] nIndex
+ Index of the structure to be sent. This value is from the
+ OMX_INDEXTYPE enumeration.
+ @param [in] pComponentParameterStructure
+ pointer to application allocated structure to be used for
+ initialization by the component.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+ */
+#define OMX_SetParameter( \
+ hComponent, \
+ nParamIndex, \
+ pComponentParameterStructure) \
+ ((OMX_COMPONENTTYPE*)hComponent)->SetParameter( \
+ hComponent, \
+ nParamIndex, \
+ pComponentParameterStructure) /* Macro End */
+
+
+/** The OMX_GetConfig macro will get one of the configuration structures
+ from a component. This macro can be invoked anytime after the
+ component has been loaded. The nParamIndex call parameter is used to
+ indicate which structure is being requested from the component. The
+ application shall allocate the correct structure and shall fill in the
+ structure size and version information before invoking this macro.
+ If the component has not had this configuration parameter sent before,
+ then the component should return a set of valid DEFAULT values for the
+ component. This is a blocking call.
+
+ The component should return from this call within 5 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [in] nIndex
+ Index of the structure to be filled. This value is from the
+ OMX_INDEXTYPE enumeration.
+ @param [in,out] pComponentConfigStructure
+ pointer to application allocated structure to be filled by the
+ component.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+*/
+#define OMX_GetConfig( \
+ hComponent, \
+ nConfigIndex, \
+ pComponentConfigStructure) \
+ ((OMX_COMPONENTTYPE*)hComponent)->GetConfig( \
+ hComponent, \
+ nConfigIndex, \
+ pComponentConfigStructure) /* Macro End */
+
+
+/** The OMX_SetConfig macro will send one of the configuration
+ structures to a component. Each structure shall be sent one at a time,
+ each in a separate invocation of the macro. This macro can be invoked
+ anytime after the component has been loaded. The application shall
+ allocate the correct structure and shall fill in the structure size
+ and version information (as well as the actual data) before invoking
+ this macro. The application is free to dispose of this structure after
+ the call as the component is required to copy any data it shall retain.
+ This is a blocking call.
+
+ The component should return from this call within 5 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [in] nConfigIndex
+ Index of the structure to be sent. This value is from the
+ OMX_INDEXTYPE enumeration above.
+ @param [in] pComponentConfigStructure
+ pointer to application allocated structure to be used for
+ initialization by the component.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+ */
+#define OMX_SetConfig( \
+ hComponent, \
+ nConfigIndex, \
+ pComponentConfigStructure) \
+ ((OMX_COMPONENTTYPE*)hComponent)->SetConfig( \
+ hComponent, \
+ nConfigIndex, \
+ pComponentConfigStructure) /* Macro End */
+
+
+/** The OMX_GetExtensionIndex macro will invoke a component to translate
+ a vendor specific configuration or parameter string into an OMX
+ structure index. There is no requirement for the vendor to support
+ this command for the indexes already found in the OMX_INDEXTYPE
+ enumeration (this is done to save space in small components). The
+ component shall support all vendor supplied extension indexes not found
+ in the master OMX_INDEXTYPE enumeration. This is a blocking call.
+
+ The component should return from this call within 5 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the GetHandle function.
+ @param [in] cParameterName
+ OMX_STRING that shall be less than 128 characters long including
+ the trailing null byte. This is the string that will get
+ translated by the component into a configuration index.
+ @param [out] pIndexType
+ a pointer to a OMX_INDEXTYPE to receive the index value.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+ */
+#define OMX_GetExtensionIndex( \
+ hComponent, \
+ cParameterName, \
+ pIndexType) \
+ ((OMX_COMPONENTTYPE*)hComponent)->GetExtensionIndex( \
+ hComponent, \
+ cParameterName, \
+ pIndexType) /* Macro End */
+
+
+/** The OMX_GetState macro will invoke the component to get the current
+ state of the component and place the state value into the location
+ pointed to by pState.
+
+ The component should return from this call within 5 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [out] pState
+ pointer to the location to receive the state. The value returned
+ is one of the OMX_STATETYPE members
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp
+ */
+#define OMX_GetState( \
+ hComponent, \
+ pState) \
+ ((OMX_COMPONENTTYPE*)hComponent)->GetState( \
+ hComponent, \
+ pState) /* Macro End */
+
+
+/** The OMX_UseBuffer macro will request that the component use
+ a buffer (and allocate its own buffer header) already allocated
+ by another component, or by the IL Client. This is a blocking
+ call.
+
+ The component should return from this call within 20 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [out] ppBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure used to receive the
+ pointer to the buffer header
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp buf
+ */
+
+#define OMX_UseBuffer( \
+ hComponent, \
+ ppBufferHdr, \
+ nPortIndex, \
+ pAppPrivate, \
+ nSizeBytes, \
+ pBuffer) \
+ ((OMX_COMPONENTTYPE*)hComponent)->UseBuffer( \
+ hComponent, \
+ ppBufferHdr, \
+ nPortIndex, \
+ pAppPrivate, \
+ nSizeBytes, \
+ pBuffer)
+
+
+/** The OMX_AllocateBuffer macro will request that the component allocate
+ a new buffer and buffer header. The component will allocate the
+ buffer and the buffer header and return a pointer to the buffer
+ header. This is a blocking call.
+
+ The component should return from this call within 5 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [out] ppBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure used to receive
+ the pointer to the buffer header
+ @param [in] nPortIndex
+ nPortIndex is used to select the port on the component the buffer will
+ be used with. The port can be found by using the nPortIndex
+ value as an index into the Port Definition array of the component.
+ @param [in] pAppPrivate
+ pAppPrivate is used to initialize the pAppPrivate member of the
+ buffer header structure.
+ @param [in] nSizeBytes
+ size of the buffer to allocate. Used when bAllocateNew is true.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp buf
+ */
+#define OMX_AllocateBuffer( \
+ hComponent, \
+ ppBuffer, \
+ nPortIndex, \
+ pAppPrivate, \
+ nSizeBytes) \
+ ((OMX_COMPONENTTYPE*)hComponent)->AllocateBuffer( \
+ hComponent, \
+ ppBuffer, \
+ nPortIndex, \
+ pAppPrivate, \
+ nSizeBytes) /* Macro End */
+
+
+/** The OMX_FreeBuffer macro will release a buffer header from the component
+ which was allocated using either OMX_AllocateBuffer or OMX_UseBuffer. If
+ the component allocated the buffer (see the OMX_UseBuffer macro) then
+ the component shall free the buffer and buffer header. This is a
+ blocking call.
+
+ The component should return from this call within 20 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [in] nPortIndex
+ nPortIndex is used to select the port on the component the buffer will
+ be used with.
+ @param [in] pBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+ or AllocateBuffer.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp buf
+ */
+#define OMX_FreeBuffer( \
+ hComponent, \
+ nPortIndex, \
+ pBuffer) \
+ ((OMX_COMPONENTTYPE*)hComponent)->FreeBuffer( \
+ hComponent, \
+ nPortIndex, \
+ pBuffer) /* Macro End */
+
+
+/** The OMX_EmptyThisBuffer macro will send a buffer full of data to an
+ input port of a component. The buffer will be emptied by the component
+ and returned to the application via the EmptyBufferDone call back.
+ This is a non-blocking call in that the component will record the buffer
+ and return immediately and then empty the buffer, later, at the proper
+ time. As expected, this macro may be invoked only while the component
+ is in the OMX_StateExecuting. If nPortIndex does not specify an input
+ port, the component shall return an error.
+
+ The component should return from this call within 5 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [in] pBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+ or AllocateBuffer.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp buf
+ */
+#define OMX_EmptyThisBuffer( \
+ hComponent, \
+ pBuffer) \
+ ((OMX_COMPONENTTYPE*)hComponent)->EmptyThisBuffer( \
+ hComponent, \
+ pBuffer) /* Macro End */
+
+
+/** The OMX_FillThisBuffer macro will send an empty buffer to an
+ output port of a component. The buffer will be filled by the component
+ and returned to the application via the FillBufferDone call back.
+ This is a non-blocking call in that the component will record the buffer
+ and return immediately and then fill the buffer, later, at the proper
+ time. As expected, this macro may be invoked only while the component
+ is in the OMX_ExecutingState. If nPortIndex does not specify an output
+ port, the component shall return an error.
+
+ The component should return from this call within 5 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [in] pBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure allocated with UseBuffer
+ or AllocateBuffer.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp buf
+ */
+#define OMX_FillThisBuffer( \
+ hComponent, \
+ pBuffer) \
+ ((OMX_COMPONENTTYPE*)hComponent)->FillThisBuffer( \
+ hComponent, \
+ pBuffer) /* Macro End */
+
+
+
+/** The OMX_UseEGLImage macro will request that the component use
+ a EGLImage provided by EGL (and allocate its own buffer header)
+ This is a blocking call.
+
+ The component should return from this call within 20 msec.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the OMX_GetHandle function.
+ @param [out] ppBuffer
+ pointer to an OMX_BUFFERHEADERTYPE structure used to receive the
+ pointer to the buffer header. Note that the memory location used
+ for this buffer is NOT visible to the IL Client.
+ @param [in] nPortIndex
+ nPortIndex is used to select the port on the component the buffer will
+ be used with. The port can be found by using the nPortIndex
+ value as an index into the Port Definition array of the component.
+ @param [in] pAppPrivate
+ pAppPrivate is used to initialize the pAppPrivate member of the
+ buffer header structure.
+ @param [in] eglImage
+ eglImage contains the handle of the EGLImage to use as a buffer on the
+ specified port. The component is expected to validate properties of
+ the EGLImage against the configuration of the port to ensure the component
+ can use the EGLImage as a buffer.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup comp buf
+ */
+#define OMX_UseEGLImage( \
+ hComponent, \
+ ppBufferHdr, \
+ nPortIndex, \
+ pAppPrivate, \
+ eglImage) \
+ ((OMX_COMPONENTTYPE*)hComponent)->UseEGLImage( \
+ hComponent, \
+ ppBufferHdr, \
+ nPortIndex, \
+ pAppPrivate, \
+ eglImage)
+
+/** The OMX_Init method is used to initialize the OMX core. It shall be the
+ first call made into OMX and it should only be executed one time without
+ an interviening OMX_Deinit call.
+
+ The core should return from this call within 20 msec.
+
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void);
+
+
+/** The OMX_Deinit method is used to deinitialize the OMX core. It shall be
+ the last call made into OMX. In the event that the core determines that
+ thare are components loaded when this call is made, the core may return
+ with an error rather than try to unload the components.
+
+ The core should return from this call within 20 msec.
+
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void);
+
+
+/** The OMX_ComponentNameEnum method will enumerate through all the names of
+ recognised valid components in the system. This function is provided
+ as a means to detect all the components in the system run-time. There is
+ no strict ordering to the enumeration order of component names, although
+ each name will only be enumerated once. If the OMX core supports run-time
+ installation of new components, it is only requried to detect newly
+ installed components when the first call to enumerate component names
+ is made (i.e. when nIndex is 0x0).
+
+ The core should return from this call in 20 msec.
+
+ @param [out] cComponentName
+ pointer to a null terminated string with the component name. The
+ names of the components are strings less than 127 bytes in length
+ plus the trailing null for a maximum size of 128 bytes. An example
+ of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are
+ assigned by the vendor, but shall start with "OMX." and then have
+ the Vendor designation next.
+ @param [in] nNameLength
+ number of characters in the cComponentName string. With all
+ component name strings restricted to less than 128 characters
+ (including the trailing null) it is recomended that the caller
+ provide a input string for the cComponentName of 128 characters.
+ @param [in] nIndex
+ number containing the enumeration index for the component.
+ Multiple calls to OMX_ComponentNameEnum with increasing values
+ of nIndex will enumerate through the component names in the
+ system until OMX_ErrorNoMore is returned. The value of nIndex
+ is 0 to (N-1), where N is the number of valid installed components
+ in the system.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. When the value of nIndex exceeds the number of
+ components in the system minus 1, OMX_ErrorNoMore will be
+ returned. Otherwise the appropriate OMX error will be returned.
+ @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
+ OMX_OUT OMX_STRING cComponentName,
+ OMX_IN OMX_U32 nNameLength,
+ OMX_IN OMX_U32 nIndex);
+
+
+/** The OMX_GetHandle method will locate the component specified by the
+ component name given, load that component into memory and then invoke
+ the component's methods to create an instance of the component.
+
+ The core should return from this call within 20 msec.
+
+ @param [out] pHandle
+ pointer to an OMX_HANDLETYPE pointer to be filled in by this method.
+ @param [in] cComponentName
+ pointer to a null terminated string with the component name. The
+ names of the components are strings less than 127 bytes in length
+ plus the trailing null for a maximum size of 128 bytes. An example
+ of a valid component name is "OMX.TI.AUDIO.DSP.MIXER\0". Names are
+ assigned by the vendor, but shall start with "OMX." and then have
+ the Vendor designation next.
+ @param [in] pAppData
+ pointer to an application defined value that will be returned
+ during callbacks so that the application can identify the source
+ of the callback.
+ @param [in] pCallBacks
+ pointer to a OMX_CALLBACKTYPE structure that will be passed to the
+ component to initialize it with.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
+ OMX_OUT OMX_HANDLETYPE* pHandle,
+ OMX_IN OMX_STRING cComponentName,
+ OMX_IN OMX_PTR pAppData,
+ OMX_IN OMX_CALLBACKTYPE* pCallBacks);
+
+
+/** The OMX_FreeHandle method will free a handle allocated by the OMX_GetHandle
+ method. If the component reference count goes to zero, the component will
+ be unloaded from memory.
+
+ The core should return from this call within 20 msec when the component is
+ in the OMX_StateLoaded state.
+
+ @param [in] hComponent
+ Handle of the component to be accessed. This is the component
+ handle returned by the call to the GetHandle function.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
+ OMX_IN OMX_HANDLETYPE hComponent);
+
+
+
+/** The OMX_SetupTunnel method will handle the necessary calls to the components
+ to setup the specified tunnel the two components. NOTE: This is
+ an actual method (not a #define macro). This method will make calls into
+ the component ComponentTunnelRequest method to do the actual tunnel
+ connection.
+
+ The ComponentTunnelRequest method on both components will be called.
+ This method shall not be called unless the component is in the
+ OMX_StateLoaded state except when the ports used for the tunnel are
+ disabled. In this case, the component may be in the OMX_StateExecuting,
+ OMX_StatePause, or OMX_StateIdle states.
+
+ The core should return from this call within 20 msec.
+
+ @param [in] hOutput
+ Handle of the component to be accessed. Also this is the handle
+ of the component whose port, specified in the nPortOutput parameter
+ will be used the source for the tunnel. This is the component handle
+ returned by the call to the OMX_GetHandle function. There is a
+ requirement that hOutput be the source for the data when
+ tunelling (i.e. nPortOutput is an output port). If 0x0, the component
+ specified in hInput will have it's port specified in nPortInput
+ setup for communication with the application / IL client.
+ @param [in] nPortOutput
+ nPortOutput is used to select the source port on component to be
+ used in the tunnel.
+ @param [in] hInput
+ This is the component to setup the tunnel with. This is the handle
+ of the component whose port, specified in the nPortInput parameter
+ will be used the destination for the tunnel. This is the component handle
+ returned by the call to the OMX_GetHandle function. There is a
+ requirement that hInput be the destination for the data when
+ tunelling (i.e. nPortInut is an input port). If 0x0, the component
+ specified in hOutput will have it's port specified in nPortPOutput
+ setup for communication with the application / IL client.
+ @param [in] nPortInput
+ nPortInput is used to select the destination port on component to be
+ used in the tunnel.
+ @return OMX_ERRORTYPE
+ If the command successfully executes, the return code will be
+ OMX_ErrorNone. Otherwise the appropriate OMX error will be returned.
+ When OMX_ErrorNotImplemented is returned, one or both components is
+ a non-interop component and does not support tunneling.
+
+ On failure, the ports of both components are setup for communication
+ with the application / IL Client.
+ @ingroup core tun
+ */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
+ OMX_IN OMX_HANDLETYPE hOutput,
+ OMX_IN OMX_U32 nPortOutput,
+ OMX_IN OMX_HANDLETYPE hInput,
+ OMX_IN OMX_U32 nPortInput);
+
+/** @ingroup cp */
+OMX_API OMX_ERRORTYPE OMX_GetContentPipe(
+ OMX_OUT OMX_HANDLETYPE *hPipe,
+ OMX_IN OMX_STRING szURI);
+
+/** The OMX_GetComponentsOfRole method will return the number of components that support the given
+ role and (if the compNames field is non-NULL) the names of those components. The call will fail if
+ an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
+ client should:
+ * first call this function with the compNames field NULL to determine the number of component names
+ * second call this function with the compNames field pointing to an array of names allocated
+ according to the number returned by the first call.
+
+ The core should return from this call within 5 msec.
+
+ @param [in] role
+ This is generic standard component name consisting only of component class
+ name and the type within that class (e.g. 'audio_decoder.aac').
+ @param [inout] pNumComps
+ This is used both as input and output.
+
+ If compNames is NULL, the input is ignored and the output specifies how many components support
+ the given role.
+
+ If compNames is not NULL, on input it bounds the size of the input structure and
+ on output, it specifies the number of components string names listed within the compNames parameter.
+ @param [inout] compNames
+ If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings which accepts
+ a list of the names of all physical components that implement the specified standard component name.
+ Each name is NULL terminated. numComps indicates the number of names.
+ @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (
+ OMX_IN OMX_STRING role,
+ OMX_INOUT OMX_U32 *pNumComps,
+ OMX_INOUT OMX_U8 **compNames);
+
+/** The OMX_GetRolesOfComponent method will return the number of roles supported by the given
+ component and (if the roles field is non-NULL) the names of those roles. The call will fail if
+ an insufficiently sized array of names is supplied. To ensure the array is sufficiently sized the
+ client should:
+ * first call this function with the roles field NULL to determine the number of role names
+ * second call this function with the roles field pointing to an array of names allocated
+ according to the number returned by the first call.
+
+ The core should return from this call within 5 msec.
+
+ @param [in] compName
+ This is the name of the component being queried about.
+ @param [inout] pNumRoles
+ This is used both as input and output.
+
+ If roles is NULL, the input is ignored and the output specifies how many roles the component supports.
+
+ If compNames is not NULL, on input it bounds the size of the input structure and
+ on output, it specifies the number of roles string names listed within the roles parameter.
+ @param [out] roles
+ If NULL this field is ignored. If non-NULL this points to an array of 128-byte strings
+ which accepts a list of the names of all standard components roles implemented on the
+ specified component name. numComps indicates the number of names.
+ @ingroup core
+ */
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (
+ OMX_IN OMX_STRING compName,
+ OMX_INOUT OMX_U32 *pNumRoles,
+ OMX_OUT OMX_U8 **roles);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+
diff --git a/msmcobalt/mm-core/inc/OMX_CoreExt.h b/msmcobalt/mm-core/inc/OMX_CoreExt.h
new file mode 100644
index 0000000..3ec14b0
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_CoreExt.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_CoreExt.h - OpenMax IL version 1.1.2
+ * The OMX_CoreExt header file contains extensions to the definitions used
+ * by both the application and the component to access common items.
+ */
+
+#ifndef OMX_CoreExt_h
+#define OMX_CoreExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+
+/** Event type extensions. */
+typedef enum OMX_EVENTEXTTYPE
+{
+ OMX_EventIndexSettingChanged = OMX_EventKhronosExtensions, /**< component signals the IL client of a change
+ in a param, config, or extension */
+ OMX_EventExtMax = 0x7FFFFFFF
+} OMX_EVENTEXTTYPE;
+
+
+/** Enable or disable a callback event. */
+typedef struct OMX_CONFIG_CALLBACKREQUESTTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_INDEXTYPE nIndex; /**< the index the callback is requested for */
+ OMX_BOOL bEnable; /**< enable (OMX_TRUE) or disable (OMX_FALSE) the callback */
+} OMX_CONFIG_CALLBACKREQUESTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_CoreExt_h */
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_IVCommon.h b/msmcobalt/mm-core/inc/OMX_IVCommon.h
new file mode 100644
index 0000000..ec71756
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_IVCommon.h
@@ -0,0 +1,933 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * @file OMX_IVCommon.h - OpenMax IL version 1.1.2
+ * The structures needed by Video and Image components to exchange
+ * parameters and configuration data with the components.
+ */
+#ifndef OMX_IVCommon_h
+#define OMX_IVCommon_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * Each OMX header must include all required header files to allow the header
+ * to compile without errors. The includes below are required for this header
+ * file to compile successfully
+ */
+
+#include <OMX_Core.h>
+
+/** @defgroup iv OpenMAX IL Imaging and Video Domain
+ * Common structures for OpenMAX IL Imaging and Video domains
+ * @{
+ */
+
+
+/**
+ * Enumeration defining possible uncompressed image/video formats.
+ *
+ * ENUMS:
+ * Unused : Placeholder value when format is N/A
+ * Monochrome : black and white
+ * 8bitRGB332 : Red 7:5, Green 4:2, Blue 1:0
+ * 12bitRGB444 : Red 11:8, Green 7:4, Blue 3:0
+ * 16bitARGB4444 : Alpha 15:12, Red 11:8, Green 7:4, Blue 3:0
+ * 16bitARGB1555 : Alpha 15, Red 14:10, Green 9:5, Blue 4:0
+ * 16bitRGB565 : Red 15:11, Green 10:5, Blue 4:0
+ * 16bitBGR565 : Blue 15:11, Green 10:5, Red 4:0
+ * 18bitRGB666 : Red 17:12, Green 11:6, Blue 5:0
+ * 18bitARGB1665 : Alpha 17, Red 16:11, Green 10:5, Blue 4:0
+ * 19bitARGB1666 : Alpha 18, Red 17:12, Green 11:6, Blue 5:0
+ * 24bitRGB888 : Red 24:16, Green 15:8, Blue 7:0
+ * 24bitBGR888 : Blue 24:16, Green 15:8, Red 7:0
+ * 24bitARGB1887 : Alpha 23, Red 22:15, Green 14:7, Blue 6:0
+ * 25bitARGB1888 : Alpha 24, Red 23:16, Green 15:8, Blue 7:0
+ * 32bitBGRA8888 : Blue 31:24, Green 23:16, Red 15:8, Alpha 7:0
+ * 32bitARGB8888 : Alpha 31:24, Red 23:16, Green 15:8, Blue 7:0
+ * YUV411Planar : U,Y are subsampled by a factor of 4 horizontally
+ * YUV411PackedPlanar : packed per payload in planar slices
+ * YUV420Planar : Three arrays Y,U,V.
+ * YUV420PackedPlanar : packed per payload in planar slices
+ * YUV420SemiPlanar : Two arrays, one is all Y, the other is U and V
+ * YUV422Planar : Three arrays Y,U,V.
+ * YUV422PackedPlanar : packed per payload in planar slices
+ * YUV422SemiPlanar : Two arrays, one is all Y, the other is U and V
+ * YCbYCr : Organized as 16bit YUYV (i.e. YCbYCr)
+ * YCrYCb : Organized as 16bit YVYU (i.e. YCrYCb)
+ * CbYCrY : Organized as 16bit UYVY (i.e. CbYCrY)
+ * CrYCbY : Organized as 16bit VYUY (i.e. CrYCbY)
+ * YUV444Interleaved : Each pixel contains equal parts YUV
+ * RawBayer8bit : SMIA camera output format
+ * RawBayer10bit : SMIA camera output format
+ * RawBayer8bitcompressed : SMIA camera output format
+ */
+typedef enum OMX_COLOR_FORMATTYPE {
+ OMX_COLOR_FormatUnused,
+ OMX_COLOR_FormatMonochrome,
+ OMX_COLOR_Format8bitRGB332,
+ OMX_COLOR_Format12bitRGB444,
+ OMX_COLOR_Format16bitARGB4444,
+ OMX_COLOR_Format16bitARGB1555,
+ OMX_COLOR_Format16bitRGB565,
+ OMX_COLOR_Format16bitBGR565,
+ OMX_COLOR_Format18bitRGB666,
+ OMX_COLOR_Format18bitARGB1665,
+ OMX_COLOR_Format19bitARGB1666,
+ OMX_COLOR_Format24bitRGB888,
+ OMX_COLOR_Format24bitBGR888,
+ OMX_COLOR_Format24bitARGB1887,
+ OMX_COLOR_Format25bitARGB1888,
+ OMX_COLOR_Format32bitBGRA8888,
+ OMX_COLOR_Format32bitARGB8888,
+ OMX_COLOR_FormatYUV411Planar,
+ OMX_COLOR_FormatYUV411PackedPlanar,
+ OMX_COLOR_FormatYUV420Planar,
+ OMX_COLOR_FormatYUV420PackedPlanar,
+ OMX_COLOR_FormatYUV420SemiPlanar,
+ OMX_COLOR_FormatYUV422Planar,
+ OMX_COLOR_FormatYUV422PackedPlanar,
+ OMX_COLOR_FormatYUV422SemiPlanar,
+ OMX_COLOR_FormatYCbYCr,
+ OMX_COLOR_FormatYCrYCb,
+ OMX_COLOR_FormatCbYCrY,
+ OMX_COLOR_FormatCrYCbY,
+ OMX_COLOR_FormatYUV444Interleaved,
+ OMX_COLOR_FormatRawBayer8bit,
+ OMX_COLOR_FormatRawBayer10bit,
+ OMX_COLOR_FormatRawBayer8bitcompressed,
+ OMX_COLOR_FormatL2,
+ OMX_COLOR_FormatL4,
+ OMX_COLOR_FormatL8,
+ OMX_COLOR_FormatL16,
+ OMX_COLOR_FormatL24,
+ OMX_COLOR_FormatL32,
+ OMX_COLOR_FormatYUV420PackedSemiPlanar,
+ OMX_COLOR_FormatYUV422PackedSemiPlanar,
+ OMX_COLOR_Format18BitBGR666,
+ OMX_COLOR_Format24BitARGB6666,
+ OMX_COLOR_Format24BitABGR6666,
+ OMX_COLOR_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_COLOR_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ /**<Reserved android opaque colorformat. Tells the encoder that
+ * the actual colorformat will be relayed by the
+ * Gralloc Buffers.
+ * FIXME: In the process of reserving some enum values for
+ * Android-specific OMX IL colorformats. Change this enum to
+ * an acceptable range once that is done.
+ * */
+ OMX_COLOR_FormatAndroidOpaque = 0x7F000789,
+ OMX_TI_COLOR_FormatYUV420PackedSemiPlanar = 0x7F000100,
+ OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
+ OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka = 0x7FA30C03,
+ OMX_SEC_COLOR_FormatNV12Tiled = 0x7FC00002,
+ OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m = 0x7FA30C04,
+ OMX_COLOR_FormatMax = 0x7FFFFFFF
+} OMX_COLOR_FORMATTYPE;
+
+
+/**
+ * Defines the matrix for conversion from RGB to YUV or vice versa.
+ * iColorMatrix should be initialized with the fixed point values
+ * used in converting between formats.
+ */
+typedef struct OMX_CONFIG_COLORCONVERSIONTYPE {
+ OMX_U32 nSize; /**< Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
+ OMX_U32 nPortIndex; /**< Port that this struct applies to */
+ OMX_S32 xColorMatrix[3][3]; /**< Stored in signed Q16 format */
+ OMX_S32 xColorOffset[4]; /**< Stored in signed Q16 format */
+}OMX_CONFIG_COLORCONVERSIONTYPE;
+
+
+/**
+ * Structure defining percent to scale each frame dimension. For example:
+ * To make the width 50% larger, use fWidth = 1.5 and to make the width
+ * 1/2 the original size, use fWidth = 0.5
+ */
+typedef struct OMX_CONFIG_SCALEFACTORTYPE {
+ OMX_U32 nSize; /**< Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version info */
+ OMX_U32 nPortIndex; /**< Port that this struct applies to */
+ OMX_S32 xWidth; /**< Fixed point value stored as Q16 */
+ OMX_S32 xHeight; /**< Fixed point value stored as Q16 */
+}OMX_CONFIG_SCALEFACTORTYPE;
+
+
+/**
+ * Enumeration of possible image filter types
+ */
+typedef enum OMX_IMAGEFILTERTYPE {
+ OMX_ImageFilterNone,
+ OMX_ImageFilterNoise,
+ OMX_ImageFilterEmboss,
+ OMX_ImageFilterNegative,
+ OMX_ImageFilterSketch,
+ OMX_ImageFilterOilPaint,
+ OMX_ImageFilterHatch,
+ OMX_ImageFilterGpen,
+ OMX_ImageFilterAntialias,
+ OMX_ImageFilterDeRing,
+ OMX_ImageFilterSolarize,
+ OMX_ImageFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ImageFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_ImageFilterMax = 0x7FFFFFFF
+} OMX_IMAGEFILTERTYPE;
+
+
+/**
+ * Image filter configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eImageFilter : Image filter type enumeration
+ */
+typedef struct OMX_CONFIG_IMAGEFILTERTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_IMAGEFILTERTYPE eImageFilter;
+} OMX_CONFIG_IMAGEFILTERTYPE;
+
+
+/**
+ * Customized U and V for color enhancement
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * bColorEnhancement : Enable/disable color enhancement
+ * nCustomizedU : Practical values: 16-240, range: 0-255, value set for
+ * U component
+ * nCustomizedV : Practical values: 16-240, range: 0-255, value set for
+ * V component
+ */
+typedef struct OMX_CONFIG_COLORENHANCEMENTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bColorEnhancement;
+ OMX_U8 nCustomizedU;
+ OMX_U8 nCustomizedV;
+} OMX_CONFIG_COLORENHANCEMENTTYPE;
+
+
+/**
+ * Define color key and color key mask
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nARGBColor : 32bit Alpha, Red, Green, Blue Color
+ * nARGBMask : 32bit Mask for Alpha, Red, Green, Blue channels
+ */
+typedef struct OMX_CONFIG_COLORKEYTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nARGBColor;
+ OMX_U32 nARGBMask;
+} OMX_CONFIG_COLORKEYTYPE;
+
+
+/**
+ * List of color blend types for pre/post processing
+ *
+ * ENUMS:
+ * None : No color blending present
+ * AlphaConstant : Function is (alpha_constant * src) +
+ * (1 - alpha_constant) * dst)
+ * AlphaPerPixel : Function is (alpha * src) + (1 - alpha) * dst)
+ * Alternate : Function is alternating pixels from src and dst
+ * And : Function is (src & dst)
+ * Or : Function is (src | dst)
+ * Invert : Function is ~src
+ */
+typedef enum OMX_COLORBLENDTYPE {
+ OMX_ColorBlendNone,
+ OMX_ColorBlendAlphaConstant,
+ OMX_ColorBlendAlphaPerPixel,
+ OMX_ColorBlendAlternate,
+ OMX_ColorBlendAnd,
+ OMX_ColorBlendOr,
+ OMX_ColorBlendInvert,
+ OMX_ColorBlendKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ColorBlendVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_ColorBlendMax = 0x7FFFFFFF
+} OMX_COLORBLENDTYPE;
+
+
+/**
+ * Color blend configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nRGBAlphaConstant : Constant global alpha values when global alpha is used
+ * eColorBlend : Color blend type enumeration
+ */
+typedef struct OMX_CONFIG_COLORBLENDTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nRGBAlphaConstant;
+ OMX_COLORBLENDTYPE eColorBlend;
+} OMX_CONFIG_COLORBLENDTYPE;
+
+
+/**
+ * Hold frame dimension
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nWidth : Frame width in pixels
+ * nHeight : Frame height in pixels
+ */
+typedef struct OMX_FRAMESIZETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nWidth;
+ OMX_U32 nHeight;
+} OMX_FRAMESIZETYPE;
+
+
+/**
+ * Rotation configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nRotation : +/- integer rotation value
+ */
+typedef struct OMX_CONFIG_ROTATIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nRotation;
+} OMX_CONFIG_ROTATIONTYPE;
+
+
+/**
+ * Possible mirroring directions for pre/post processing
+ *
+ * ENUMS:
+ * None : No mirroring
+ * Vertical : Vertical mirroring, flip on X axis
+ * Horizontal : Horizontal mirroring, flip on Y axis
+ * Both : Both vertical and horizontal mirroring
+ */
+typedef enum OMX_MIRRORTYPE {
+ OMX_MirrorNone = 0,
+ OMX_MirrorVertical,
+ OMX_MirrorHorizontal,
+ OMX_MirrorBoth,
+ OMX_MirrorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_MirrorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_MirrorMax = 0x7FFFFFFF
+} OMX_MIRRORTYPE;
+
+
+/**
+ * Mirroring configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eMirror : Mirror type enumeration
+ */
+typedef struct OMX_CONFIG_MIRRORTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_MIRRORTYPE eMirror;
+} OMX_CONFIG_MIRRORTYPE;
+
+
+/**
+ * Position information only
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nX : X coordinate for the point
+ * nY : Y coordinate for the point
+ */
+typedef struct OMX_CONFIG_POINTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nX;
+ OMX_S32 nY;
+} OMX_CONFIG_POINTTYPE;
+
+
+/**
+ * Frame size plus position
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nLeft : X Coordinate of the top left corner of the rectangle
+ * nTop : Y Coordinate of the top left corner of the rectangle
+ * nWidth : Width of the rectangle
+ * nHeight : Height of the rectangle
+ */
+typedef struct OMX_CONFIG_RECTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nLeft;
+ OMX_S32 nTop;
+ OMX_U32 nWidth;
+ OMX_U32 nHeight;
+} OMX_CONFIG_RECTTYPE;
+
+
+/**
+ * Deblocking state; it is required to be set up before starting the codec
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * bDeblocking : Enable/disable deblocking mode
+ */
+typedef struct OMX_PARAM_DEBLOCKINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bDeblocking;
+} OMX_PARAM_DEBLOCKINGTYPE;
+
+
+/**
+ * Stabilization state
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * bStab : Enable/disable frame stabilization state
+ */
+typedef struct OMX_CONFIG_FRAMESTABTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bStab;
+} OMX_CONFIG_FRAMESTABTYPE;
+
+
+/**
+ * White Balance control type
+ *
+ * STRUCT MEMBERS:
+ * SunLight : Referenced in JSR-234
+ * Flash : Optimal for device's integrated flash
+ */
+typedef enum OMX_WHITEBALCONTROLTYPE {
+ OMX_WhiteBalControlOff = 0,
+ OMX_WhiteBalControlAuto,
+ OMX_WhiteBalControlSunLight,
+ OMX_WhiteBalControlCloudy,
+ OMX_WhiteBalControlShade,
+ OMX_WhiteBalControlTungsten,
+ OMX_WhiteBalControlFluorescent,
+ OMX_WhiteBalControlIncandescent,
+ OMX_WhiteBalControlFlash,
+ OMX_WhiteBalControlHorizon,
+ OMX_WhiteBalControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_WhiteBalControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_WhiteBalControlMax = 0x7FFFFFFF
+} OMX_WHITEBALCONTROLTYPE;
+
+
+/**
+ * White Balance control configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eWhiteBalControl : White balance enumeration
+ */
+typedef struct OMX_CONFIG_WHITEBALCONTROLTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_WHITEBALCONTROLTYPE eWhiteBalControl;
+} OMX_CONFIG_WHITEBALCONTROLTYPE;
+
+
+/**
+ * Exposure control type
+ */
+typedef enum OMX_EXPOSURECONTROLTYPE {
+ OMX_ExposureControlOff = 0,
+ OMX_ExposureControlAuto,
+ OMX_ExposureControlNight,
+ OMX_ExposureControlBackLight,
+ OMX_ExposureControlSpotLight,
+ OMX_ExposureControlSports,
+ OMX_ExposureControlSnow,
+ OMX_ExposureControlBeach,
+ OMX_ExposureControlLargeAperture,
+ OMX_ExposureControlSmallApperture,
+ OMX_ExposureControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_ExposureControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_ExposureControlMax = 0x7FFFFFFF
+} OMX_EXPOSURECONTROLTYPE;
+
+
+/**
+ * White Balance control configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eExposureControl : Exposure control enumeration
+ */
+typedef struct OMX_CONFIG_EXPOSURECONTROLTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_EXPOSURECONTROLTYPE eExposureControl;
+} OMX_CONFIG_EXPOSURECONTROLTYPE;
+
+
+/**
+ * Defines sensor supported mode.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nFrameRate : Single shot mode is indicated by a 0
+ * bOneShot : Enable for single shot, disable for streaming
+ * sFrameSize : Framesize
+ */
+typedef struct OMX_PARAM_SENSORMODETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nFrameRate;
+ OMX_BOOL bOneShot;
+ OMX_FRAMESIZETYPE sFrameSize;
+} OMX_PARAM_SENSORMODETYPE;
+
+
+/**
+ * Defines contrast level
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nContrast : Values allowed for contrast -100 to 100, zero means no change
+ */
+typedef struct OMX_CONFIG_CONTRASTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nContrast;
+} OMX_CONFIG_CONTRASTTYPE;
+
+
+/**
+ * Defines brightness level
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nBrightness : 0-100%
+ */
+typedef struct OMX_CONFIG_BRIGHTNESSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nBrightness;
+} OMX_CONFIG_BRIGHTNESSTYPE;
+
+
+/**
+ * Defines backlight level configuration for a video sink, e.g. LCD panel
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nBacklight : Values allowed for backlight 0-100%
+ * nTimeout : Number of milliseconds before backlight automatically turns
+ * off. A value of 0x0 disables backight timeout
+ */
+typedef struct OMX_CONFIG_BACKLIGHTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nBacklight;
+ OMX_U32 nTimeout;
+} OMX_CONFIG_BACKLIGHTTYPE;
+
+
+/**
+ * Defines setting for Gamma
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nGamma : Values allowed for gamma -100 to 100, zero means no change
+ */
+typedef struct OMX_CONFIG_GAMMATYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nGamma;
+} OMX_CONFIG_GAMMATYPE;
+
+
+/**
+ * Define for setting saturation
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nSaturation : Values allowed for saturation -100 to 100, zero means
+ * no change
+ */
+typedef struct OMX_CONFIG_SATURATIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nSaturation;
+} OMX_CONFIG_SATURATIONTYPE;
+
+
+/**
+ * Define for setting Lightness
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nLightness : Values allowed for lightness -100 to 100, zero means no
+ * change
+ */
+typedef struct OMX_CONFIG_LIGHTNESSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nLightness;
+} OMX_CONFIG_LIGHTNESSTYPE;
+
+
+/**
+ * Plane blend configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Index of input port associated with the plane.
+ * nDepth : Depth of the plane in relation to the screen. Higher
+ * numbered depths are "behind" lower number depths.
+ * This number defaults to the Port Index number.
+ * nAlpha : Transparency blending component for the entire plane.
+ * See blending modes for more detail.
+ */
+typedef struct OMX_CONFIG_PLANEBLENDTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nDepth;
+ OMX_U32 nAlpha;
+} OMX_CONFIG_PLANEBLENDTYPE;
+
+
+/**
+ * Define interlace type
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * bEnable : Enable control variable for this functionality
+ * (see below)
+ * nInterleavePortIndex : Index of input or output port associated with
+ * the interleaved plane.
+ * pPlanarPortIndexes[4] : Index of input or output planar ports.
+ */
+typedef struct OMX_PARAM_INTERLEAVETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ OMX_U32 nInterleavePortIndex;
+} OMX_PARAM_INTERLEAVETYPE;
+
+
+/**
+ * Defines the picture effect used for an input picture
+ */
+typedef enum OMX_TRANSITIONEFFECTTYPE {
+ OMX_EffectNone,
+ OMX_EffectFadeFromBlack,
+ OMX_EffectFadeToBlack,
+ OMX_EffectUnspecifiedThroughConstantColor,
+ OMX_EffectDissolve,
+ OMX_EffectWipe,
+ OMX_EffectUnspecifiedMixOfTwoScenes,
+ OMX_EffectKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_EffectVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_EffectMax = 0x7FFFFFFF
+} OMX_TRANSITIONEFFECTTYPE;
+
+
+/**
+ * Structure used to configure current transition effect
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eEffect : Effect to enable
+ */
+typedef struct OMX_CONFIG_TRANSITIONEFFECTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_TRANSITIONEFFECTTYPE eEffect;
+} OMX_CONFIG_TRANSITIONEFFECTTYPE;
+
+
+/**
+ * Defines possible data unit types for encoded video data. The data unit
+ * types are used both for encoded video input for playback as well as
+ * encoded video output from recording.
+ */
+typedef enum OMX_DATAUNITTYPE {
+ OMX_DataUnitCodedPicture,
+ OMX_DataUnitVideoSegment,
+ OMX_DataUnitSeveralSegments,
+ OMX_DataUnitArbitraryStreamSection,
+ OMX_DataUnitKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DataUnitVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_DataUnitMax = 0x7FFFFFFF
+} OMX_DATAUNITTYPE;
+
+
+/**
+ * Defines possible encapsulation types for coded video data unit. The
+ * encapsulation information is used both for encoded video input for
+ * playback as well as encoded video output from recording.
+ */
+typedef enum OMX_DATAUNITENCAPSULATIONTYPE {
+ OMX_DataEncapsulationElementaryStream,
+ OMX_DataEncapsulationGenericPayload,
+ OMX_DataEncapsulationRtpPayload,
+ OMX_DataEncapsulationKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DataEncapsulationVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_DataEncapsulationMax = 0x7FFFFFFF
+} OMX_DATAUNITENCAPSULATIONTYPE;
+
+
+/**
+ * Structure used to configure the type of being decoded/encoded
+ */
+typedef struct OMX_PARAM_DATAUNITTYPE {
+ OMX_U32 nSize; /**< Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port that this structure applies to */
+ OMX_DATAUNITTYPE eUnitType;
+ OMX_DATAUNITENCAPSULATIONTYPE eEncapsulationType;
+} OMX_PARAM_DATAUNITTYPE;
+
+
+/**
+ * Defines dither types
+ */
+typedef enum OMX_DITHERTYPE {
+ OMX_DitherNone,
+ OMX_DitherOrdered,
+ OMX_DitherErrorDiffusion,
+ OMX_DitherOther,
+ OMX_DitherKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_DitherVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_DitherMax = 0x7FFFFFFF
+} OMX_DITHERTYPE;
+
+
+/**
+ * Structure used to configure current type of dithering
+ */
+typedef struct OMX_CONFIG_DITHERTYPE {
+ OMX_U32 nSize; /**< Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port that this structure applies to */
+ OMX_DITHERTYPE eDither; /**< Type of dithering to use */
+} OMX_CONFIG_DITHERTYPE;
+
+typedef struct OMX_CONFIG_CAPTUREMODETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex; /**< Port that this structure applies to */
+ OMX_BOOL bContinuous; /**< If true then ignore frame rate and emit capture
+ * data as fast as possible (otherwise obey port's frame rate). */
+ OMX_BOOL bFrameLimited; /**< If true then terminate capture after the port emits the
+ * specified number of frames (otherwise the port does not
+ * terminate the capture until instructed to do so by the client).
+ * Even if set, the client may manually terminate the capture prior
+ * to reaching the limit. */
+ OMX_U32 nFrameLimit; /**< Limit on number of frames emitted during a capture (only
+ * valid if bFrameLimited is set). */
+} OMX_CONFIG_CAPTUREMODETYPE;
+
+typedef enum OMX_METERINGTYPE {
+
+ OMX_MeteringModeAverage, /**< Center-weighted average metering. */
+ OMX_MeteringModeSpot, /**< Spot (partial) metering. */
+ OMX_MeteringModeMatrix, /**< Matrix or evaluative metering. */
+
+ OMX_MeteringKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_MeteringVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_EVModeMax = 0x7fffffff
+} OMX_METERINGTYPE;
+
+typedef struct OMX_CONFIG_EXPOSUREVALUETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_METERINGTYPE eMetering;
+ OMX_S32 xEVCompensation; /**< Fixed point value stored as Q16 */
+ OMX_U32 nApertureFNumber; /**< e.g. nApertureFNumber = 2 implies "f/2" - Q16 format */
+ OMX_BOOL bAutoAperture; /**< Whether aperture number is defined automatically */
+ OMX_U32 nShutterSpeedMsec; /**< Shutterspeed in milliseconds */
+ OMX_BOOL bAutoShutterSpeed; /**< Whether shutter speed is defined automatically */
+ OMX_U32 nSensitivity; /**< e.g. nSensitivity = 100 implies "ISO 100" */
+ OMX_BOOL bAutoSensitivity; /**< Whether sensitivity is defined automatically */
+} OMX_CONFIG_EXPOSUREVALUETYPE;
+
+/**
+ * Focus region configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * bCenter : Use center region as focus region of interest
+ * bLeft : Use left region as focus region of interest
+ * bRight : Use right region as focus region of interest
+ * bTop : Use top region as focus region of interest
+ * bBottom : Use bottom region as focus region of interest
+ * bTopLeft : Use top left region as focus region of interest
+ * bTopRight : Use top right region as focus region of interest
+ * bBottomLeft : Use bottom left region as focus region of interest
+ * bBottomRight : Use bottom right region as focus region of interest
+ */
+typedef struct OMX_CONFIG_FOCUSREGIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bCenter;
+ OMX_BOOL bLeft;
+ OMX_BOOL bRight;
+ OMX_BOOL bTop;
+ OMX_BOOL bBottom;
+ OMX_BOOL bTopLeft;
+ OMX_BOOL bTopRight;
+ OMX_BOOL bBottomLeft;
+ OMX_BOOL bBottomRight;
+} OMX_CONFIG_FOCUSREGIONTYPE;
+
+/**
+ * Focus Status type
+ */
+typedef enum OMX_FOCUSSTATUSTYPE {
+ OMX_FocusStatusOff = 0,
+ OMX_FocusStatusRequest,
+ OMX_FocusStatusReached,
+ OMX_FocusStatusUnableToReach,
+ OMX_FocusStatusLost,
+ OMX_FocusStatusKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_FocusStatusVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_FocusStatusMax = 0x7FFFFFFF
+} OMX_FOCUSSTATUSTYPE;
+
+/**
+ * Focus status configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFocusStatus : Specifies the focus status
+ * bCenterStatus : Use center region as focus region of interest
+ * bLeftStatus : Use left region as focus region of interest
+ * bRightStatus : Use right region as focus region of interest
+ * bTopStatus : Use top region as focus region of interest
+ * bBottomStatus : Use bottom region as focus region of interest
+ * bTopLeftStatus : Use top left region as focus region of interest
+ * bTopRightStatus : Use top right region as focus region of interest
+ * bBottomLeftStatus : Use bottom left region as focus region of interest
+ * bBottomRightStatus : Use bottom right region as focus region of interest
+ */
+typedef struct OMX_PARAM_FOCUSSTATUSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_FOCUSSTATUSTYPE eFocusStatus;
+ OMX_BOOL bCenterStatus;
+ OMX_BOOL bLeftStatus;
+ OMX_BOOL bRightStatus;
+ OMX_BOOL bTopStatus;
+ OMX_BOOL bBottomStatus;
+ OMX_BOOL bTopLeftStatus;
+ OMX_BOOL bTopRightStatus;
+ OMX_BOOL bBottomLeftStatus;
+ OMX_BOOL bBottomRightStatus;
+} OMX_PARAM_FOCUSSTATUSTYPE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_Image.h b/msmcobalt/mm-core/inc/OMX_Image.h
new file mode 100644
index 0000000..a6d4666
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Image.h
@@ -0,0 +1,328 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file OMX_Image.h - OpenMax IL version 1.1.2
+ * The structures needed by Image components to exchange parameters and
+ * configuration data with the components.
+ */
+#ifndef OMX_Image_h
+#define OMX_Image_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Each OMX header must include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_IVCommon.h>
+
+/** @defgroup imaging OpenMAX IL Imaging Domain
+ * @ingroup iv
+ * Structures for OpenMAX IL Imaging domain
+ * @{
+ */
+
+/**
+ * Enumeration used to define the possible image compression coding.
+ */
+typedef enum OMX_IMAGE_CODINGTYPE {
+ OMX_IMAGE_CodingUnused, /**< Value when format is N/A */
+ OMX_IMAGE_CodingAutoDetect, /**< Auto detection of image format */
+ OMX_IMAGE_CodingJPEG, /**< JPEG/JFIF image format */
+ OMX_IMAGE_CodingJPEG2K, /**< JPEG 2000 image format */
+ OMX_IMAGE_CodingEXIF, /**< EXIF image format */
+ OMX_IMAGE_CodingTIFF, /**< TIFF image format */
+ OMX_IMAGE_CodingGIF, /**< Graphics image format */
+ OMX_IMAGE_CodingPNG, /**< PNG image format */
+ OMX_IMAGE_CodingLZW, /**< LZW image format */
+ OMX_IMAGE_CodingBMP, /**< Windows Bitmap format */
+ OMX_IMAGE_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_IMAGE_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_IMAGE_CodingMax = 0x7FFFFFFF
+} OMX_IMAGE_CODINGTYPE;
+
+
+/**
+ * Data structure used to define an image path. The number of image paths
+ * for input and output will vary by type of the image component.
+ *
+ * Input (aka Source) : Zero Inputs, one Output,
+ * Splitter : One Input, 2 or more Outputs,
+ * Processing Element : One Input, one output,
+ * Mixer : 2 or more inputs, one output,
+ * Output (aka Sink) : One Input, zero outputs.
+ *
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output
+ * image path. If additional vendor specific data is required, it should
+ * be transmitted to the component using the CustomCommand function.
+ * Compliant components will prepopulate this structure with optimal
+ * values during the OMX_GetParameter() command.
+ *
+ * STRUCT MEMBERS:
+ * cMIMEType : MIME type of data for the port
+ * pNativeRender : Platform specific reference for a display if a
+ * sync, otherwise this field is 0
+ * nFrameWidth : Width of frame to be used on port if
+ * uncompressed format is used. Use 0 for
+ * unknown, don't care or variable
+ * nFrameHeight : Height of frame to be used on port if
+ * uncompressed format is used. Use 0 for
+ * unknown, don't care or variable
+ * nStride : Number of bytes per span of an image (i.e.
+ * indicates the number of bytes to get from
+ * span N to span N+1, where negative stride
+ * indicates the image is bottom up
+ * nSliceHeight : Height used when encoding in slices
+ * bFlagErrorConcealment : Turns on error concealment if it is supported by
+ * the OMX component
+ * eCompressionFormat : Compression format used in this instance of
+ * the component. When OMX_IMAGE_CodingUnused is
+ * specified, eColorFormat is valid
+ * eColorFormat : Decompressed format used by this component
+ * pNativeWindow : Platform specific reference for a window object if a
+ * display sink , otherwise this field is 0x0.
+ */
+typedef struct OMX_IMAGE_PORTDEFINITIONTYPE {
+ OMX_STRING cMIMEType;
+ OMX_NATIVE_DEVICETYPE pNativeRender;
+ OMX_U32 nFrameWidth;
+ OMX_U32 nFrameHeight;
+ OMX_S32 nStride;
+ OMX_U32 nSliceHeight;
+ OMX_BOOL bFlagErrorConcealment;
+ OMX_IMAGE_CODINGTYPE eCompressionFormat;
+ OMX_COLOR_FORMATTYPE eColorFormat;
+ OMX_NATIVE_WINDOWTYPE pNativeWindow;
+} OMX_IMAGE_PORTDEFINITIONTYPE;
+
+
+/**
+ * Port format parameter. This structure is used to enumerate the various
+ * data input/output format supported by the port.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Indicates which port to set
+ * nIndex : Indicates the enumeration index for the format from
+ * 0x0 to N-1
+ * eCompressionFormat : Compression format used in this instance of the
+ * component. When OMX_IMAGE_CodingUnused is specified,
+ * eColorFormat is valid
+ * eColorFormat : Decompressed format used by this component
+ */
+typedef struct OMX_IMAGE_PARAM_PORTFORMATTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nIndex;
+ OMX_IMAGE_CODINGTYPE eCompressionFormat;
+ OMX_COLOR_FORMATTYPE eColorFormat;
+} OMX_IMAGE_PARAM_PORTFORMATTYPE;
+
+
+/**
+ * Flash control type
+ *
+ * ENUMS
+ * Torch : Flash forced constantly on
+ */
+typedef enum OMX_IMAGE_FLASHCONTROLTYPE {
+ OMX_IMAGE_FlashControlOn = 0,
+ OMX_IMAGE_FlashControlOff,
+ OMX_IMAGE_FlashControlAuto,
+ OMX_IMAGE_FlashControlRedEyeReduction,
+ OMX_IMAGE_FlashControlFillin,
+ OMX_IMAGE_FlashControlTorch,
+ OMX_IMAGE_FlashControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_IMAGE_FlashControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_IMAGE_FlashControlMax = 0x7FFFFFFF
+} OMX_IMAGE_FLASHCONTROLTYPE;
+
+
+/**
+ * Flash control configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFlashControl : Flash control type
+ */
+typedef struct OMX_IMAGE_PARAM_FLASHCONTROLTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_IMAGE_FLASHCONTROLTYPE eFlashControl;
+} OMX_IMAGE_PARAM_FLASHCONTROLTYPE;
+
+
+/**
+ * Focus control type
+ */
+typedef enum OMX_IMAGE_FOCUSCONTROLTYPE {
+ OMX_IMAGE_FocusControlOn = 0,
+ OMX_IMAGE_FocusControlOff,
+ OMX_IMAGE_FocusControlAuto,
+ OMX_IMAGE_FocusControlAutoLock,
+ OMX_IMAGE_FocusControlKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_IMAGE_FocusControlVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_IMAGE_FocusControlMax = 0x7FFFFFFF
+} OMX_IMAGE_FOCUSCONTROLTYPE;
+
+
+/**
+ * Focus control configuration
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFocusControl : Focus control
+ * nFocusSteps : Focus can take on values from 0 mm to infinity.
+ * Interest is only in number of steps over this range.
+ * nFocusStepIndex : Current focus step index
+ */
+typedef struct OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_IMAGE_FOCUSCONTROLTYPE eFocusControl;
+ OMX_U32 nFocusSteps;
+ OMX_U32 nFocusStepIndex;
+} OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE;
+
+
+/**
+ * Q Factor for JPEG compression, which controls the tradeoff between image
+ * quality and size. Q Factor provides a more simple means of controlling
+ * JPEG compression quality, without directly programming Quantization
+ * tables for chroma and luma
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nQFactor : JPEG Q factor value in the range of 1-100. A factor of 1
+ * produces the smallest, worst quality images, and a factor
+ * of 100 produces the largest, best quality images. A
+ * typical default is 75 for small good quality images
+ */
+typedef struct OMX_IMAGE_PARAM_QFACTORTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nQFactor;
+} OMX_IMAGE_PARAM_QFACTORTYPE;
+
+/**
+ * Quantization table type
+ */
+
+typedef enum OMX_IMAGE_QUANTIZATIONTABLETYPE {
+ OMX_IMAGE_QuantizationTableLuma = 0,
+ OMX_IMAGE_QuantizationTableChroma,
+ OMX_IMAGE_QuantizationTableChromaCb,
+ OMX_IMAGE_QuantizationTableChromaCr,
+ OMX_IMAGE_QuantizationTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_IMAGE_QuantizationTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_IMAGE_QuantizationTableMax = 0x7FFFFFFF
+} OMX_IMAGE_QUANTIZATIONTABLETYPE;
+
+/**
+ * JPEG quantization tables are used to determine DCT compression for
+ * YUV data, as an alternative to specifying Q factor, providing exact
+ * control of compression
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eQuantizationTable : Quantization table type
+ * nQuantizationMatrix[64] : JPEG quantization table of coefficients stored
+ * in increasing columns then by rows of data (i.e.
+ * row 1, ... row 8). Quantization values are in
+ * the range 0-255 and stored in linear order
+ * (i.e. the component will zig-zag the
+ * quantization table data if required internally)
+ */
+typedef struct OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_IMAGE_QUANTIZATIONTABLETYPE eQuantizationTable;
+ OMX_U8 nQuantizationMatrix[64];
+} OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE;
+
+
+/**
+ * Huffman table type, the same Huffman table is applied for chroma and
+ * luma component
+ */
+typedef enum OMX_IMAGE_HUFFMANTABLETYPE {
+ OMX_IMAGE_HuffmanTableAC = 0,
+ OMX_IMAGE_HuffmanTableDC,
+ OMX_IMAGE_HuffmanTableACLuma,
+ OMX_IMAGE_HuffmanTableACChroma,
+ OMX_IMAGE_HuffmanTableDCLuma,
+ OMX_IMAGE_HuffmanTableDCChroma,
+ OMX_IMAGE_HuffmanTableKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_IMAGE_HuffmanTableVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_IMAGE_HuffmanTableMax = 0x7FFFFFFF
+} OMX_IMAGE_HUFFMANTABLETYPE;
+
+/**
+ * JPEG Huffman table
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eHuffmanTable : Huffman table type
+ * nNumberOfHuffmanCodeOfLength[16] : 0-16, number of Huffman codes of each
+ * possible length
+ * nHuffmanTable[256] : 0-255, the size used for AC and DC
+ * HuffmanTable are 16 and 162
+ */
+typedef struct OMX_IMAGE_PARAM_HUFFMANTTABLETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_IMAGE_HUFFMANTABLETYPE eHuffmanTable;
+ OMX_U8 nNumberOfHuffmanCodeOfLength[16];
+ OMX_U8 nHuffmanTable[256];
+}OMX_IMAGE_PARAM_HUFFMANTTABLETYPE;
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_Index.h b/msmcobalt/mm-core/inc/OMX_Index.h
new file mode 100644
index 0000000..3131a5f
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Index.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_Index.h - OpenMax IL version 1.1.2
+ * The OMX_Index header file contains the definitions for both applications
+ * and components .
+ */
+
+
+#ifndef OMX_Index_h
+#define OMX_Index_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Types.h>
+
+
+/** The OMX_INDEXTYPE enumeration is used to select a structure when either
+ * getting or setting parameters and/or configuration data. Each entry in
+ * this enumeration maps to an OMX specified structure. When the
+ * OMX_GetParameter, OMX_SetParameter, OMX_GetConfig or OMX_SetConfig methods
+ * are used, the second parameter will always be an entry from this enumeration
+ * and the third entry will be the structure shown in the comments for the entry.
+ * For example, if the application is initializing a cropping function, the
+ * OMX_SetConfig command would have OMX_IndexConfigCommonInputCrop as the second parameter
+ * and would send a pointer to an initialized OMX_RECTTYPE structure as the
+ * third parameter.
+ *
+ * The enumeration entries named with the OMX_Config prefix are sent using
+ * the OMX_SetConfig command and the enumeration entries named with the
+ * OMX_PARAM_ prefix are sent using the OMX_SetParameter command.
+ */
+typedef enum OMX_INDEXTYPE {
+
+ OMX_IndexComponentStartUnused = 0x01000000,
+ OMX_IndexParamPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */
+ OMX_IndexParamAudioInit, /**< reference: OMX_PORT_PARAM_TYPE */
+ OMX_IndexParamImageInit, /**< reference: OMX_PORT_PARAM_TYPE */
+ OMX_IndexParamVideoInit, /**< reference: OMX_PORT_PARAM_TYPE */
+ OMX_IndexParamOtherInit, /**< reference: OMX_PORT_PARAM_TYPE */
+ OMX_IndexParamNumAvailableStreams, /**< reference: OMX_PARAM_U32TYPE */
+ OMX_IndexParamActiveStream, /**< reference: OMX_PARAM_U32TYPE */
+ OMX_IndexParamSuspensionPolicy, /**< reference: OMX_PARAM_SUSPENSIONPOLICYTYPE */
+ OMX_IndexParamComponentSuspended, /**< reference: OMX_PARAM_SUSPENSIONTYPE */
+ OMX_IndexConfigCapturing, /**< reference: OMX_CONFIG_BOOLEANTYPE */
+ OMX_IndexConfigCaptureMode, /**< reference: OMX_CONFIG_CAPTUREMODETYPE */
+ OMX_IndexAutoPauseAfterCapture, /**< reference: OMX_CONFIG_BOOLEANTYPE */
+ OMX_IndexParamContentURI, /**< reference: OMX_PARAM_CONTENTURITYPE */
+ OMX_IndexParamCustomContentPipe, /**< reference: OMX_PARAM_CONTENTPIPETYPE */
+ OMX_IndexParamDisableResourceConcealment, /**< reference: OMX_RESOURCECONCEALMENTTYPE */
+ OMX_IndexConfigMetadataItemCount, /**< reference: OMX_CONFIG_METADATAITEMCOUNTTYPE */
+ OMX_IndexConfigContainerNodeCount, /**< reference: OMX_CONFIG_CONTAINERNODECOUNTTYPE */
+ OMX_IndexConfigMetadataItem, /**< reference: OMX_CONFIG_METADATAITEMTYPE */
+ OMX_IndexConfigCounterNodeID, /**< reference: OMX_CONFIG_CONTAINERNODEIDTYPE */
+ OMX_IndexParamMetadataFilterType, /**< reference: OMX_PARAM_METADATAFILTERTYPE */
+ OMX_IndexParamMetadataKeyFilter, /**< reference: OMX_PARAM_METADATAFILTERTYPE */
+ OMX_IndexConfigPriorityMgmt, /**< reference: OMX_PRIORITYMGMTTYPE */
+ OMX_IndexParamStandardComponentRole, /**< reference: OMX_PARAM_COMPONENTROLETYPE */
+
+ OMX_IndexPortStartUnused = 0x02000000,
+ OMX_IndexParamPortDefinition, /**< reference: OMX_PARAM_PORTDEFINITIONTYPE */
+ OMX_IndexParamCompBufferSupplier, /**< reference: OMX_PARAM_BUFFERSUPPLIERTYPE */
+ OMX_IndexReservedStartUnused = 0x03000000,
+
+ /* Audio parameters and configurations */
+ OMX_IndexAudioStartUnused = 0x04000000,
+ OMX_IndexParamAudioPortFormat, /**< reference: OMX_AUDIO_PARAM_PORTFORMATTYPE */
+ OMX_IndexParamAudioPcm, /**< reference: OMX_AUDIO_PARAM_PCMMODETYPE */
+ OMX_IndexParamAudioAac, /**< reference: OMX_AUDIO_PARAM_AACPROFILETYPE */
+ OMX_IndexParamAudioRa, /**< reference: OMX_AUDIO_PARAM_RATYPE */
+ OMX_IndexParamAudioMp3, /**< reference: OMX_AUDIO_PARAM_MP3TYPE */
+ OMX_IndexParamAudioAdpcm, /**< reference: OMX_AUDIO_PARAM_ADPCMTYPE */
+ OMX_IndexParamAudioG723, /**< reference: OMX_AUDIO_PARAM_G723TYPE */
+ OMX_IndexParamAudioG729, /**< reference: OMX_AUDIO_PARAM_G729TYPE */
+ OMX_IndexParamAudioAmr, /**< reference: OMX_AUDIO_PARAM_AMRTYPE */
+ OMX_IndexParamAudioWma, /**< reference: OMX_AUDIO_PARAM_WMATYPE */
+ OMX_IndexParamAudioSbc, /**< reference: OMX_AUDIO_PARAM_SBCTYPE */
+ OMX_IndexParamAudioMidi, /**< reference: OMX_AUDIO_PARAM_MIDITYPE */
+ OMX_IndexParamAudioGsm_FR, /**< reference: OMX_AUDIO_PARAM_GSMFRTYPE */
+ OMX_IndexParamAudioMidiLoadUserSound, /**< reference: OMX_AUDIO_PARAM_MIDILOADUSERSOUNDTYPE */
+ OMX_IndexParamAudioG726, /**< reference: OMX_AUDIO_PARAM_G726TYPE */
+ OMX_IndexParamAudioGsm_EFR, /**< reference: OMX_AUDIO_PARAM_GSMEFRTYPE */
+ OMX_IndexParamAudioGsm_HR, /**< reference: OMX_AUDIO_PARAM_GSMHRTYPE */
+ OMX_IndexParamAudioPdc_FR, /**< reference: OMX_AUDIO_PARAM_PDCFRTYPE */
+ OMX_IndexParamAudioPdc_EFR, /**< reference: OMX_AUDIO_PARAM_PDCEFRTYPE */
+ OMX_IndexParamAudioPdc_HR, /**< reference: OMX_AUDIO_PARAM_PDCHRTYPE */
+ OMX_IndexParamAudioTdma_FR, /**< reference: OMX_AUDIO_PARAM_TDMAFRTYPE */
+ OMX_IndexParamAudioTdma_EFR, /**< reference: OMX_AUDIO_PARAM_TDMAEFRTYPE */
+ OMX_IndexParamAudioQcelp8, /**< reference: OMX_AUDIO_PARAM_QCELP8TYPE */
+ OMX_IndexParamAudioQcelp13, /**< reference: OMX_AUDIO_PARAM_QCELP13TYPE */
+ OMX_IndexParamAudioEvrc, /**< reference: OMX_AUDIO_PARAM_EVRCTYPE */
+ OMX_IndexParamAudioSmv, /**< reference: OMX_AUDIO_PARAM_SMVTYPE */
+ OMX_IndexParamAudioVorbis, /**< reference: OMX_AUDIO_PARAM_VORBISTYPE */
+ OMX_IndexParamAudioG711, /**< reference: OMX_AUDIO_PARAM_G711TYPE */
+
+ OMX_IndexConfigAudioMidiImmediateEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIIMMEDIATEEVENTTYPE */
+ OMX_IndexConfigAudioMidiControl, /**< reference: OMX_AUDIO_CONFIG_MIDICONTROLTYPE */
+ OMX_IndexConfigAudioMidiSoundBankProgram, /**< reference: OMX_AUDIO_CONFIG_MIDISOUNDBANKPROGRAMTYPE */
+ OMX_IndexConfigAudioMidiStatus, /**< reference: OMX_AUDIO_CONFIG_MIDISTATUSTYPE */
+ OMX_IndexConfigAudioMidiMetaEvent, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTTYPE */
+ OMX_IndexConfigAudioMidiMetaEventData, /**< reference: OMX_AUDIO_CONFIG_MIDIMETAEVENTDATATYPE */
+ OMX_IndexConfigAudioVolume, /**< reference: OMX_AUDIO_CONFIG_VOLUMETYPE */
+ OMX_IndexConfigAudioBalance, /**< reference: OMX_AUDIO_CONFIG_BALANCETYPE */
+ OMX_IndexConfigAudioChannelMute, /**< reference: OMX_AUDIO_CONFIG_CHANNELMUTETYPE */
+ OMX_IndexConfigAudioMute, /**< reference: OMX_AUDIO_CONFIG_MUTETYPE */
+ OMX_IndexConfigAudioLoudness, /**< reference: OMX_AUDIO_CONFIG_LOUDNESSTYPE */
+ OMX_IndexConfigAudioEchoCancelation, /**< reference: OMX_AUDIO_CONFIG_ECHOCANCELATIONTYPE */
+ OMX_IndexConfigAudioNoiseReduction, /**< reference: OMX_AUDIO_CONFIG_NOISEREDUCTIONTYPE */
+ OMX_IndexConfigAudioBass, /**< reference: OMX_AUDIO_CONFIG_BASSTYPE */
+ OMX_IndexConfigAudioTreble, /**< reference: OMX_AUDIO_CONFIG_TREBLETYPE */
+ OMX_IndexConfigAudioStereoWidening, /**< reference: OMX_AUDIO_CONFIG_STEREOWIDENINGTYPE */
+ OMX_IndexConfigAudioChorus, /**< reference: OMX_AUDIO_CONFIG_CHORUSTYPE */
+ OMX_IndexConfigAudioEqualizer, /**< reference: OMX_AUDIO_CONFIG_EQUALIZERTYPE */
+ OMX_IndexConfigAudioReverberation, /**< reference: OMX_AUDIO_CONFIG_REVERBERATIONTYPE */
+ OMX_IndexConfigAudioChannelVolume, /**< reference: OMX_AUDIO_CONFIG_CHANNELVOLUMETYPE */
+
+ /* Image specific parameters and configurations */
+ OMX_IndexImageStartUnused = 0x05000000,
+ OMX_IndexParamImagePortFormat, /**< reference: OMX_IMAGE_PARAM_PORTFORMATTYPE */
+ OMX_IndexParamFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */
+ OMX_IndexConfigFocusControl, /**< reference: OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE */
+ OMX_IndexParamQFactor, /**< reference: OMX_IMAGE_PARAM_QFACTORTYPE */
+ OMX_IndexParamQuantizationTable, /**< reference: OMX_IMAGE_PARAM_QUANTIZATIONTABLETYPE */
+ OMX_IndexParamHuffmanTable, /**< reference: OMX_IMAGE_PARAM_HUFFMANTTABLETYPE */
+ OMX_IndexConfigFlashControl, /**< reference: OMX_IMAGE_PARAM_FLASHCONTROLTYPE */
+
+ /* Video specific parameters and configurations */
+ OMX_IndexVideoStartUnused = 0x06000000,
+ OMX_IndexParamVideoPortFormat, /**< reference: OMX_VIDEO_PARAM_PORTFORMATTYPE */
+ OMX_IndexParamVideoQuantization, /**< reference: OMX_VIDEO_PARAM_QUANTIZATIONTYPE */
+ OMX_IndexParamVideoFastUpdate, /**< reference: OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE */
+ OMX_IndexParamVideoBitrate, /**< reference: OMX_VIDEO_PARAM_BITRATETYPE */
+ OMX_IndexParamVideoMotionVector, /**< reference: OMX_VIDEO_PARAM_MOTIONVECTORTYPE */
+ OMX_IndexParamVideoIntraRefresh, /**< reference: OMX_VIDEO_PARAM_INTRAREFRESHTYPE */
+ OMX_IndexParamVideoErrorCorrection, /**< reference: OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE */
+ OMX_IndexParamVideoVBSMC, /**< reference: OMX_VIDEO_PARAM_VBSMCTYPE */
+ OMX_IndexParamVideoMpeg2, /**< reference: OMX_VIDEO_PARAM_MPEG2TYPE */
+ OMX_IndexParamVideoMpeg4, /**< reference: OMX_VIDEO_PARAM_MPEG4TYPE */
+ OMX_IndexParamVideoWmv, /**< reference: OMX_VIDEO_PARAM_WMVTYPE */
+ OMX_IndexParamVideoRv, /**< reference: OMX_VIDEO_PARAM_RVTYPE */
+ OMX_IndexParamVideoAvc, /**< reference: OMX_VIDEO_PARAM_AVCTYPE */
+ OMX_IndexParamVideoH263, /**< reference: OMX_VIDEO_PARAM_H263TYPE */
+ OMX_IndexParamVideoProfileLevelQuerySupported, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */
+ OMX_IndexParamVideoProfileLevelCurrent, /**< reference: OMX_VIDEO_PARAM_PROFILELEVELTYPE */
+ OMX_IndexConfigVideoBitrate, /**< reference: OMX_VIDEO_CONFIG_BITRATETYPE */
+ OMX_IndexConfigVideoFramerate, /**< reference: OMX_CONFIG_FRAMERATETYPE */
+ OMX_IndexConfigVideoIntraVOPRefresh, /**< reference: OMX_CONFIG_INTRAREFRESHVOPTYPE */
+ OMX_IndexConfigVideoIntraMBRefresh, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */
+ OMX_IndexConfigVideoMBErrorReporting, /**< reference: OMX_CONFIG_MBERRORREPORTINGTYPE */
+ OMX_IndexParamVideoMacroblocksPerFrame, /**< reference: OMX_PARAM_MACROBLOCKSTYPE */
+ OMX_IndexConfigVideoMacroBlockErrorMap, /**< reference: OMX_CONFIG_MACROBLOCKERRORMAPTYPE */
+ OMX_IndexParamVideoSliceFMO, /**< reference: OMX_VIDEO_PARAM_AVCSLICEFMO */
+ OMX_IndexConfigVideoAVCIntraPeriod, /**< reference: OMX_VIDEO_CONFIG_AVCINTRAPERIOD */
+ OMX_IndexConfigVideoNalSize, /**< reference: OMX_VIDEO_CONFIG_NALSIZE */
+ OMX_IndexConfigCommonDeinterlace, /**< reference: OMX_VIDEO_CONFIG_DEINTERLACE */
+
+ /* Image & Video common Configurations */
+ OMX_IndexCommonStartUnused = 0x07000000,
+ OMX_IndexParamCommonDeblocking, /**< reference: OMX_PARAM_DEBLOCKINGTYPE */
+ OMX_IndexParamCommonSensorMode, /**< reference: OMX_PARAM_SENSORMODETYPE */
+ OMX_IndexParamCommonInterleave, /**< reference: OMX_PARAM_INTERLEAVETYPE */
+ OMX_IndexConfigCommonColorFormatConversion, /**< reference: OMX_CONFIG_COLORCONVERSIONTYPE */
+ OMX_IndexConfigCommonScale, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
+ OMX_IndexConfigCommonImageFilter, /**< reference: OMX_CONFIG_IMAGEFILTERTYPE */
+ OMX_IndexConfigCommonColorEnhancement, /**< reference: OMX_CONFIG_COLORENHANCEMENTTYPE */
+ OMX_IndexConfigCommonColorKey, /**< reference: OMX_CONFIG_COLORKEYTYPE */
+ OMX_IndexConfigCommonColorBlend, /**< reference: OMX_CONFIG_COLORBLENDTYPE */
+ OMX_IndexConfigCommonFrameStabilisation,/**< reference: OMX_CONFIG_FRAMESTABTYPE */
+ OMX_IndexConfigCommonRotate, /**< reference: OMX_CONFIG_ROTATIONTYPE */
+ OMX_IndexConfigCommonMirror, /**< reference: OMX_CONFIG_MIRRORTYPE */
+ OMX_IndexConfigCommonOutputPosition, /**< reference: OMX_CONFIG_POINTTYPE */
+ OMX_IndexConfigCommonInputCrop, /**< reference: OMX_CONFIG_RECTTYPE */
+ OMX_IndexConfigCommonOutputCrop, /**< reference: OMX_CONFIG_RECTTYPE */
+ OMX_IndexConfigCommonDigitalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE */
+ OMX_IndexConfigCommonOpticalZoom, /**< reference: OMX_CONFIG_SCALEFACTORTYPE*/
+ OMX_IndexConfigCommonWhiteBalance, /**< reference: OMX_CONFIG_WHITEBALCONTROLTYPE */
+ OMX_IndexConfigCommonExposure, /**< reference: OMX_CONFIG_EXPOSURECONTROLTYPE */
+ OMX_IndexConfigCommonContrast, /**< reference: OMX_CONFIG_CONTRASTTYPE */
+ OMX_IndexConfigCommonBrightness, /**< reference: OMX_CONFIG_BRIGHTNESSTYPE */
+ OMX_IndexConfigCommonBacklight, /**< reference: OMX_CONFIG_BACKLIGHTTYPE */
+ OMX_IndexConfigCommonGamma, /**< reference: OMX_CONFIG_GAMMATYPE */
+ OMX_IndexConfigCommonSaturation, /**< reference: OMX_CONFIG_SATURATIONTYPE */
+ OMX_IndexConfigCommonLightness, /**< reference: OMX_CONFIG_LIGHTNESSTYPE */
+ OMX_IndexConfigCommonExclusionRect, /**< reference: OMX_CONFIG_RECTTYPE */
+ OMX_IndexConfigCommonDithering, /**< reference: OMX_CONFIG_DITHERTYPE */
+ OMX_IndexConfigCommonPlaneBlend, /**< reference: OMX_CONFIG_PLANEBLENDTYPE */
+ OMX_IndexConfigCommonExposureValue, /**< reference: OMX_CONFIG_EXPOSUREVALUETYPE */
+ OMX_IndexConfigCommonOutputSize, /**< reference: OMX_FRAMESIZETYPE */
+ OMX_IndexParamCommonExtraQuantData, /**< reference: OMX_OTHER_EXTRADATATYPE */
+ OMX_IndexConfigCommonFocusRegion, /**< reference: OMX_CONFIG_FOCUSREGIONTYPE */
+ OMX_IndexConfigCommonFocusStatus, /**< reference: OMX_PARAM_FOCUSSTATUSTYPE */
+ OMX_IndexConfigCommonTransitionEffect, /**< reference: OMX_CONFIG_TRANSITIONEFFECTTYPE */
+
+ /* Reserved Configuration range */
+ OMX_IndexOtherStartUnused = 0x08000000,
+ OMX_IndexParamOtherPortFormat, /**< reference: OMX_OTHER_PARAM_PORTFORMATTYPE */
+ OMX_IndexConfigOtherPower, /**< reference: OMX_OTHER_CONFIG_POWERTYPE */
+ OMX_IndexConfigOtherStats, /**< reference: OMX_OTHER_CONFIG_STATSTYPE */
+
+
+ /* Reserved Time range */
+ OMX_IndexTimeStartUnused = 0x09000000,
+ OMX_IndexConfigTimeScale, /**< reference: OMX_TIME_CONFIG_SCALETYPE */
+ OMX_IndexConfigTimeClockState, /**< reference: OMX_TIME_CONFIG_CLOCKSTATETYPE */
+ OMX_IndexConfigTimeActiveRefClock, /**< reference: OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE */
+ OMX_IndexConfigTimeCurrentMediaTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */
+ OMX_IndexConfigTimeCurrentWallTime, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (read only) */
+ OMX_IndexConfigTimeCurrentAudioReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+ OMX_IndexConfigTimeCurrentVideoReference, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+ OMX_IndexConfigTimeMediaTimeRequest, /**< reference: OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE (write only) */
+ OMX_IndexConfigTimeClientStartTime, /**<reference: OMX_TIME_CONFIG_TIMESTAMPTYPE (write only) */
+ OMX_IndexConfigTimePosition, /**< reference: OMX_TIME_CONFIG_TIMESTAMPTYPE */
+ OMX_IndexConfigTimeSeekMode, /**< reference: OMX_TIME_CONFIG_SEEKMODETYPE */
+
+
+ OMX_IndexKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ /* Vendor specific area */
+ OMX_IndexVendorStartUnused = 0x7F000000,
+ /* Vendor specific structures should be in the range of 0x7F000000
+ to 0x7FFFFFFE. This range is not broken out by vendor, so
+ private indexes are not guaranteed unique and therefore should
+ only be sent to the appropriate component. */
+
+ OMX_IndexMax = 0x7FFFFFFF
+
+} OMX_INDEXTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_IndexExt.h b/msmcobalt/mm-core/inc/OMX_IndexExt.h
new file mode 100644
index 0000000..468a3a3
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_IndexExt.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_IndexExt.h - OpenMax IL version 1.1.2
+ * The OMX_IndexExt header file contains extensions to the definitions
+ * for both applications and components .
+ */
+
+#ifndef OMX_IndexExt_h
+#define OMX_IndexExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Index.h>
+
+
+/** Khronos standard extension indices.
+
+This enum lists the current Khronos extension indices to OpenMAX IL.
+*/
+typedef enum OMX_INDEXEXTTYPE {
+
+ /* Component parameters and configurations */
+ OMX_IndexExtComponentStartUnused = OMX_IndexKhronosExtensions + 0x00100000,
+ OMX_IndexConfigCallbackRequest, /**< reference: OMX_CONFIG_CALLBACKREQUESTTYPE */
+ OMX_IndexConfigCommitMode, /**< reference: OMX_CONFIG_COMMITMODETYPE */
+ OMX_IndexConfigCommit, /**< reference: OMX_CONFIG_COMMITTYPE */
+
+ /* Port parameters and configurations */
+ OMX_IndexExtPortStartUnused = OMX_IndexKhronosExtensions + 0x00200000,
+
+ /* Audio parameters and configurations */
+ OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,
+
+ /* Image parameters and configurations */
+ OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,
+
+ /* Video parameters and configurations */
+ OMX_IndexExtVideoStartUnused = OMX_IndexKhronosExtensions + 0x00600000,
+ OMX_IndexParamNalStreamFormatSupported, /**< reference: OMX_NALSTREAMFORMATTYPE */
+ OMX_IndexParamNalStreamFormat, /**< reference: OMX_NALSTREAMFORMATTYPE */
+ OMX_IndexParamNalStreamFormatSelect, /**< reference: OMX_NALSTREAMFORMATTYPE */
+ OMX_IndexParamVideoVp8, /**< reference: OMX_VIDEO_PARAM_VP8TYPE */
+ OMX_IndexConfigVideoVp8ReferenceFrame, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMETYPE */
+ OMX_IndexConfigVideoVp8ReferenceFrameType, /**< reference: OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE */
+ OMX_IndexParamVideoReserved, /**< Reserved for future index */
+ OMX_IndexParamVideoHevc, /**< reference: OMX_VIDEO_PARAM_HEVCTYPE */
+ OMX_IndexParamSliceSegments, /**< reference: OMX_VIDEO_SLICESEGMENTSTYPE */
+ OMX_IndexConfigAndroidIntraRefresh, /**< reference: OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE */
+ OMX_IndexParamAndroidVideoTemporalLayering, /**< reference: OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE */
+ OMX_IndexConfigAndroidVideoTemporalLayering, /**< reference: OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE */
+
+ /* Image & Video common configurations */
+ OMX_IndexExtCommonStartUnused = OMX_IndexKhronosExtensions + 0x00700000,
+
+ /* Other configurations */
+ OMX_IndexExtOtherStartUnused = OMX_IndexKhronosExtensions + 0x00800000,
+ OMX_IndexConfigAutoFramerateConversion, /**< reference: OMX_CONFIG_BOOLEANTYPE */
+ OMX_IndexConfigPriority, /**< reference: OMX_PARAM_U32TYPE */
+ OMX_IndexConfigOperatingRate, /**< reference: OMX_PARAM_U32TYPE in Q16 format for video and in Hz for audio */
+
+ /* Time configurations */
+ OMX_IndexExtTimeStartUnused = OMX_IndexKhronosExtensions + 0x00900000,
+
+ OMX_IndexExtMax = 0x7FFFFFFF
+} OMX_INDEXEXTTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_IndexExt_h */
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_Other.h b/msmcobalt/mm-core/inc/OMX_Other.h
new file mode 100644
index 0000000..caf7f38
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Other.h
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** @file OMX_Other.h - OpenMax IL version 1.1.2
+ * The structures needed by Other components to exchange
+ * parameters and configuration data with the components.
+ */
+
+#ifndef OMX_Other_h
+#define OMX_Other_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Each OMX header must include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_Core.h>
+
+
+/**
+ * Enumeration of possible data types which match to multiple domains or no
+ * domain at all. For types which are vendor specific, a value above
+ * OMX_OTHER_VENDORTSTART should be used.
+ */
+typedef enum OMX_OTHER_FORMATTYPE {
+ OMX_OTHER_FormatTime = 0, /**< Transmission of various timestamps, elapsed time,
+ time deltas, etc */
+ OMX_OTHER_FormatPower, /**< Perhaps used for enabling/disabling power
+ management, setting clocks? */
+ OMX_OTHER_FormatStats, /**< Could be things such as frame rate, frames
+ dropped, etc */
+ OMX_OTHER_FormatBinary, /**< Arbitrary binary data */
+ OMX_OTHER_FormatVendorReserved = 1000, /**< Starting value for vendor specific
+ formats */
+
+ OMX_OTHER_FormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_OTHER_FormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_OTHER_FormatMax = 0x7FFFFFFF
+} OMX_OTHER_FORMATTYPE;
+
+/**
+ * Enumeration of seek modes.
+ */
+typedef enum OMX_TIME_SEEKMODETYPE {
+ OMX_TIME_SeekModeFast = 0, /**< Prefer seeking to an approximation
+ * of the requested seek position over
+ * the actual seek position if it
+ * results in a faster seek. */
+ OMX_TIME_SeekModeAccurate, /**< Prefer seeking to the actual seek
+ * position over an approximation
+ * of the requested seek position even
+ * if it results in a slower seek. */
+ OMX_TIME_SeekModeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_TIME_SeekModeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_TIME_SeekModeMax = 0x7FFFFFFF
+} OMX_TIME_SEEKMODETYPE;
+
+/* Structure representing the seekmode of the component */
+typedef struct OMX_TIME_CONFIG_SEEKMODETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_TIME_SEEKMODETYPE eType; /**< The seek mode */
+} OMX_TIME_CONFIG_SEEKMODETYPE;
+
+/** Structure representing a time stamp used with the following configs
+ * on the Clock Component (CC):
+ *
+ * OMX_IndexConfigTimeCurrentWallTime: query of the CC’s current wall
+ * time
+ * OMX_IndexConfigTimeCurrentMediaTime: query of the CC’s current media
+ * time
+ * OMX_IndexConfigTimeCurrentAudioReference and
+ * OMX_IndexConfigTimeCurrentVideoReference: audio/video reference
+ * clock sending SC its reference time
+ * OMX_IndexConfigTimeClientStartTime: a Clock Component client sends
+ * this structure to the Clock Component via a SetConfig on its
+ * client port when it receives a buffer with
+ * OMX_BUFFERFLAG_STARTTIME set. It must use the timestamp
+ * specified by that buffer for nStartTimestamp.
+ *
+ * It’s also used with the following config on components in general:
+ *
+ * OMX_IndexConfigTimePosition: IL client querying component position
+ * (GetConfig) or commanding a component to seek to the given location
+ * (SetConfig)
+ */
+typedef struct OMX_TIME_CONFIG_TIMESTAMPTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version
+ * information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_TICKS nTimestamp; /**< timestamp .*/
+} OMX_TIME_CONFIG_TIMESTAMPTYPE;
+
+/** Enumeration of possible reference clocks to the media time. */
+typedef enum OMX_TIME_UPDATETYPE {
+ OMX_TIME_UpdateRequestFulfillment, /**< Update is the fulfillment of a media time request. */
+ OMX_TIME_UpdateScaleChanged, /**< Update was generated because the scale chagned. */
+ OMX_TIME_UpdateClockStateChanged, /**< Update was generated because the clock state changed. */
+ OMX_TIME_UpdateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_TIME_UpdateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_TIME_UpdateMax = 0x7FFFFFFF
+} OMX_TIME_UPDATETYPE;
+
+/** Enumeration of possible reference clocks to the media time. */
+typedef enum OMX_TIME_REFCLOCKTYPE {
+ OMX_TIME_RefClockNone, /**< Use no references. */
+ OMX_TIME_RefClockAudio, /**< Use references sent through OMX_IndexConfigTimeCurrentAudioReference */
+ OMX_TIME_RefClockVideo, /**< Use references sent through OMX_IndexConfigTimeCurrentVideoReference */
+ OMX_TIME_RefClockKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_TIME_RefClockVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_TIME_RefClockMax = 0x7FFFFFFF
+} OMX_TIME_REFCLOCKTYPE;
+
+/** Enumeration of clock states. */
+typedef enum OMX_TIME_CLOCKSTATE {
+ OMX_TIME_ClockStateRunning, /**< Clock running. */
+ OMX_TIME_ClockStateWaitingForStartTime, /**< Clock waiting until the
+ * prescribed clients emit their
+ * start time. */
+ OMX_TIME_ClockStateStopped, /**< Clock stopped. */
+ OMX_TIME_ClockStateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_TIME_ClockStateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_TIME_ClockStateMax = 0x7FFFFFFF
+} OMX_TIME_CLOCKSTATE;
+
+/** Structure representing a media time request to the clock component.
+ *
+ * A client component sends this structure to the Clock Component via a SetConfig
+ * on its client port to specify a media timestamp the Clock Component
+ * should emit. The Clock Component should fulfill the request by sending a
+ * OMX_TIME_MEDIATIMETYPE when its media clock matches the requested
+ * timestamp.
+ *
+ * The client may require a media time request be fulfilled slightly
+ * earlier than the media time specified. In this case the client specifies
+ * an offset which is equal to the difference between wall time corresponding
+ * to the requested media time and the wall time when it will be
+ * fulfilled.
+ *
+ * A client component may uses these requests and the OMX_TIME_MEDIATIMETYPE to
+ * time events according to timestamps. If a client must perform an operation O at
+ * a time T (e.g. deliver a video frame at its corresponding timestamp), it makes a
+ * media time request at T (perhaps specifying an offset to ensure the request fulfillment
+ * is a little early). When the clock component passes the resulting OMX_TIME_MEDIATIMETYPE
+ * structure back to the client component, the client may perform operation O (perhaps having
+ * to wait a slight amount more time itself as specified by the return values).
+ */
+
+typedef struct OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ OMX_PTR pClientPrivate; /**< Client private data to disabiguate this media time
+ * from others (e.g. the number of the frame to deliver).
+ * Duplicated in the media time structure that fulfills
+ * this request. A value of zero is reserved for time scale
+ * updates. */
+ OMX_TICKS nMediaTimestamp; /**< Media timestamp requested.*/
+ OMX_TICKS nOffset; /**< Amount of wall clock time by which this
+ * request should be fulfilled early */
+} OMX_TIME_CONFIG_MEDIATIMEREQUESTTYPE;
+
+/**< Structure sent from the clock component client either when fulfilling
+ * a media time request or when the time scale has changed.
+ *
+ * In the former case the Clock Component fills this structure and times its emission
+ * to a client component (via the client port) according to the corresponding media
+ * time request sent by the client. The Clock Component should time the emission to occur
+ * when the requested timestamp matches the Clock Component's media time but also the
+ * prescribed offset early.
+ *
+ * Upon scale changes the clock component clears the nClientPrivate data, sends the current
+ * media time and sets the nScale to the new scale via the client port. It emits a
+ * OMX_TIME_MEDIATIMETYPE to all clients independent of any requests. This allows clients to
+ * alter processing to accomodate scaling. For instance a video component might skip inter-frames
+ * in the case of extreme fastforward. Likewise an audio component might add or remove samples
+ * from an audio frame to scale audio data.
+ *
+ * It is expected that some clock components may not be able to fulfill requests
+ * at exactly the prescribed time. This is acceptable so long as the request is
+ * fulfilled at least as early as described and not later. This structure provides
+ * fields the client may use to wait for the remaining time.
+ *
+ * The client may use either the nOffset or nWallTimeAtMedia fields to determine the
+ * wall time until the nMediaTimestamp actually occurs. In the latter case the
+ * client can get a more accurate value for offset by getting the current wall
+ * from the cloc component and subtracting it from nWallTimeAtMedia.
+ */
+
+typedef struct OMX_TIME_MEDIATIMETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nClientPrivate; /**< Client private data to disabiguate this media time
+ * from others. Copied from the media time request.
+ * A value of zero is reserved for time scale updates. */
+ OMX_TIME_UPDATETYPE eUpdateType; /**< Reason for the update */
+ OMX_TICKS nMediaTimestamp; /**< Media time requested. If no media time was
+ * requested then this is the current media time. */
+ OMX_TICKS nOffset; /**< Amount of wall clock time by which this
+ * request was actually fulfilled early */
+
+ OMX_TICKS nWallTimeAtMediaTime; /**< Wall time corresponding to nMediaTimeStamp.
+ * A client may compare this value to current
+ * media time obtained from the Clock Component to determine
+ * the wall time until the media timestamp is really
+ * current. */
+ OMX_S32 xScale; /**< Current media time scale in Q16 format. */
+ OMX_TIME_CLOCKSTATE eState; /* Seeking Change. Added 7/12.*/
+ /**< State of the media time. */
+} OMX_TIME_MEDIATIMETYPE;
+
+/** Structure representing the current media time scale factor. Applicable only to clock
+ * component, other components see scale changes via OMX_TIME_MEDIATIMETYPE buffers sent via
+ * the clock component client ports. Upon recieving this config the clock component changes
+ * the rate by which the media time increases or decreases effectively implementing trick modes.
+ */
+typedef struct OMX_TIME_CONFIG_SCALETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_S32 xScale; /**< This is a value in Q16 format which is used for
+ * scaling the media time */
+} OMX_TIME_CONFIG_SCALETYPE;
+
+/** Bits used to identify a clock port. Used in OMX_TIME_CONFIG_CLOCKSTATETYPE’s nWaitMask field */
+#define OMX_CLOCKPORT0 0x00000001
+#define OMX_CLOCKPORT1 0x00000002
+#define OMX_CLOCKPORT2 0x00000004
+#define OMX_CLOCKPORT3 0x00000008
+#define OMX_CLOCKPORT4 0x00000010
+#define OMX_CLOCKPORT5 0x00000020
+#define OMX_CLOCKPORT6 0x00000040
+#define OMX_CLOCKPORT7 0x00000080
+
+/** Structure representing the current mode of the media clock.
+ * IL Client uses this config to change or query the mode of the
+ * media clock of the clock component. Applicable only to clock
+ * component.
+ *
+ * On a SetConfig if eState is OMX_TIME_ClockStateRunning media time
+ * starts immediately at the prescribed start time. If
+ * OMX_TIME_ClockStateWaitingForStartTime the Clock Component ignores
+ * the given nStartTime and waits for all clients specified in the
+ * nWaitMask to send starttimes (via
+ * OMX_IndexConfigTimeClientStartTime). The Clock Component then starts
+ * the media clock using the earliest start time supplied. */
+typedef struct OMX_TIME_CONFIG_CLOCKSTATETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version
+ * information */
+ OMX_TIME_CLOCKSTATE eState; /**< State of the media time. */
+ OMX_TICKS nStartTime; /**< Start time of the media time. */
+ OMX_TICKS nOffset; /**< Time to offset the media time by
+ * (e.g. preroll). Media time will be
+ * reported to be nOffset ticks earlier.
+ */
+ OMX_U32 nWaitMask; /**< Mask of OMX_CLOCKPORT values. */
+} OMX_TIME_CONFIG_CLOCKSTATETYPE;
+
+/** Structure representing the reference clock currently being used to
+ * compute media time. IL client uses this config to change or query the
+ * clock component's active reference clock */
+typedef struct OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_TIME_REFCLOCKTYPE eClock; /**< Reference clock used to compute media time */
+} OMX_TIME_CONFIG_ACTIVEREFCLOCKTYPE;
+
+/** Descriptor for setting specifics of power type.
+ * Note: this structure is listed for backwards compatibility. */
+typedef struct OMX_OTHER_CONFIG_POWERTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnablePM; /**< Flag to enable Power Management */
+} OMX_OTHER_CONFIG_POWERTYPE;
+
+
+/** Descriptor for setting specifics of stats type.
+ * Note: this structure is listed for backwards compatibility. */
+typedef struct OMX_OTHER_CONFIG_STATSTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ /* what goes here */
+} OMX_OTHER_CONFIG_STATSTYPE;
+
+
+/**
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output other
+ * path.
+ */
+typedef struct OMX_OTHER_PORTDEFINITIONTYPE {
+ OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */
+} OMX_OTHER_PORTDEFINITIONTYPE;
+
+/** Port format parameter. This structure is used to enumerate
+ * the various data input/output format supported by the port.
+ */
+typedef struct OMX_OTHER_PARAM_PORTFORMATTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Indicates which port to set */
+ OMX_U32 nIndex; /**< Indicates the enumeration index for the format from 0x0 to N-1 */
+ OMX_OTHER_FORMATTYPE eFormat; /**< Type of data expected for this channel */
+} OMX_OTHER_PARAM_PORTFORMATTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_QCOMExtns.h b/msmcobalt/mm-core/inc/OMX_QCOMExtns.h
new file mode 100644
index 0000000..e27aadb
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_QCOMExtns.h
@@ -0,0 +1,2023 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009-2016, 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_QCOM_EXTENSIONS_H__
+#define __OMX_QCOM_EXTENSIONS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*============================================================================
+*//** @file OMX_QCOMExtns.h
+ This header contains constants and type definitions that specify the
+ extensions added to the OpenMAX Vendor specific APIs.
+
+*//*========================================================================*/
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Include Files
+///////////////////////////////////////////////////////////////////////////////
+#include "OMX_Core.h"
+#include "OMX_Video.h"
+
+#define OMX_VIDEO_MAX_HP_LAYERS 6
+
+/**
+ * These MACROS used by Camera and Video to decide buffer count.
+ * This is to avoid mismatch of buffer count between Camera and Video.
+ * In Meta mode, read this count as buffer count in Camera and Header
+ * count in Video.
+ * 1) Number of buffers in Non-DCVS mode.
+ * 2) DCVS resolution.
+ * 3) Buffer count when Current resolution is greater than DCVS resolution
+ * defined in 2)
+ */
+
+#define OMX_VIDEO_MIN_CAMERA_BUFFERS 9
+#define OMX_VIDEO_ENC_DCVS_RESOLUTION 3840 * 2160
+#define OMX_VIDEO_MIN_CAMERA_BUFFERS_DCVS 11
+
+/**
+ * This count indicates the number of Ints in the legacy Camera payload
+ * used for HAL1
+ */
+
+#define VIDEO_METADATA_NUM_COMMON_INTS 1
+
+/**
+ * This extension is used to register mapping of a virtual
+ * address to a physical address. This extension is a parameter
+ * which can be set using the OMX_SetParameter macro. The data
+ * pointer corresponding to this extension is
+ * OMX_QCOM_MemMapEntry. This parameter is a 'write only'
+ * parameter (Current value cannot be queried using
+ * OMX_GetParameter macro).
+ */
+#define OMX_QCOM_EXTN_REGISTER_MMAP "OMX.QCOM.index.param.register_mmap"
+
+/**
+ * This structure describes the data pointer corresponding to
+ * the OMX_QCOM_MMAP_REGISTER_EXTN extension. This parameter
+ * must be set only 'after' populating a port with a buffer
+ * using OMX_UseBuffer, wherein the data pointer of the buffer
+ * corresponds to the virtual address as specified in this
+ * structure.
+ */
+struct OMX_QCOM_PARAM_MEMMAPENTRYTYPE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< Port number the structure applies to */
+
+ /**
+ * The virtual address of memory block
+ */
+ OMX_U64 nVirtualAddress;
+
+ /**
+ * The physical address corresponding to the virtual address. The physical
+ * address is contiguous for the entire valid range of the virtual
+ * address.
+ */
+ OMX_U64 nPhysicalAddress;
+};
+
+#define QOMX_VIDEO_IntraRefreshRandom (OMX_VIDEO_IntraRefreshVendorStartUnused + 0)
+
+/* This error event is used for H.264 long-term reference (LTR) encoding.
+ * When IL client specifies an LTR frame with its identifier via
+ * OMX_QCOM_INDEX_CONFIG_VIDEO_LTRUSE to the encoder, if the specified
+ * LTR frame can not be located by the encoder in its LTR list, the encoder
+ * issues this error event to IL client to notify the failure of LTRUse config.
+ */
+#define QOMX_ErrorLTRUseFailed (OMX_ErrorVendorStartUnused + 1)
+
+/*
+ * This rate control will be used for low bitrate applications to get better
+ * video quality for a given bitrate.
+ */
+#define QOMX_Video_ControlRateMaxBitrate (OMX_Video_ControlRateVendorStartUnused + 1)
+
+#define QOMX_Video_ControlRateMaxBitrateSkipFrames (OMX_Video_ControlRateVendorStartUnused + 2)
+
+#define QOMX_VIDEO_BUFFERFLAG_BFRAME 0x00100000
+
+#define QOMX_VIDEO_BUFFERFLAG_EOSEQ 0x00200000
+
+#define QOMX_VIDEO_BUFFERFLAG_MBAFF 0x00400000
+
+#define QOMX_VIDEO_BUFFERFLAG_CANCEL 0x00800000
+
+#define OMX_QCOM_PORTDEFN_EXTN "OMX.QCOM.index.param.portdefn"
+/* Allowed APIs on the above Index: OMX_GetParameter() and OMX_SetParameter() */
+
+typedef enum OMX_QCOMMemoryRegion
+{
+ OMX_QCOM_MemRegionInvalid,
+ OMX_QCOM_MemRegionEBI1,
+ OMX_QCOM_MemRegionSMI,
+ OMX_QCOM_MemRegionMax = 0X7FFFFFFF
+} OMX_QCOMMemoryRegion;
+
+typedef enum OMX_QCOMCacheAttr
+{
+ OMX_QCOM_CacheAttrNone,
+ OMX_QCOM_CacheAttrWriteBack,
+ OMX_QCOM_CacheAttrWriteThrough,
+ OMX_QCOM_CacheAttrMAX = 0X7FFFFFFF
+} OMX_QCOMCacheAttr;
+
+typedef struct OMX_QCOMRectangle
+{
+ OMX_S32 x;
+ OMX_S32 y;
+ OMX_S32 dx;
+ OMX_S32 dy;
+} OMX_QCOMRectangle;
+
+/** OMX_QCOMFramePackingFormat
+ * Input or output buffer format
+ */
+typedef enum OMX_QCOMFramePackingFormat
+{
+ /* 0 - unspecified
+ */
+ OMX_QCOM_FramePacking_Unspecified,
+
+ /* 1 - Partial frames may be present OMX IL 1.1.1 Figure 2-10:
+ * Case 1??Each Buffer Filled In Whole or In Part
+ */
+ OMX_QCOM_FramePacking_Arbitrary,
+
+ /* 2 - Multiple complete frames per buffer (integer number)
+ * OMX IL 1.1.1 Figure 2-11: Case 2—Each Buffer Filled with
+ * Only Complete Frames of Data
+ */
+ OMX_QCOM_FramePacking_CompleteFrames,
+
+ /* 3 - Only one complete frame per buffer, no partial frame
+ * OMX IL 1.1.1 Figure 2-12: Case 3—Each Buffer Filled with
+ * Only One Frame of Compressed Data. Usually at least one
+ * complete unit of data will be delivered in a buffer for
+ * uncompressed data formats.
+ */
+ OMX_QCOM_FramePacking_OnlyOneCompleteFrame,
+
+ /* 4 - Only one complete subframe per buffer, no partial subframe
+ * Example: In H264, one complete NAL per buffer, where one frame
+ * can contatin multiple NAL
+ */
+ OMX_QCOM_FramePacking_OnlyOneCompleteSubFrame,
+
+ OMX_QCOM_FramePacking_MAX = 0X7FFFFFFF
+} OMX_QCOMFramePackingFormat;
+
+typedef struct OMX_QCOM_PARAM_PORTDEFINITIONTYPE {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+
+ /** Platform specific memory region EBI1, SMI, etc.,*/
+ OMX_QCOMMemoryRegion nMemRegion;
+
+ OMX_QCOMCacheAttr nCacheAttr; /** Cache attributes */
+
+ /** Input or output buffer format */
+ OMX_U32 nFramePackingFormat;
+
+} OMX_QCOM_PARAM_PORTDEFINITIONTYPE;
+
+typedef struct OMX_QCOM_VIDEO_PARAM_QPRANGETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 minQP;
+ OMX_U32 maxQP;
+} OMX_QCOM_VIDEO_PARAM_QPRANGETYPE;
+
+typedef struct OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 minIQP;
+ OMX_U32 maxIQP;
+ OMX_U32 minPQP;
+ OMX_U32 maxPQP;
+ OMX_U32 minBQP;
+ OMX_U32 maxBQP;
+} OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE;
+
+#define OMX_QCOM_PLATFORMPVT_EXTN "OMX.QCOM.index.param.platformprivate"
+/** Allowed APIs on the above Index: OMX_SetParameter() */
+
+typedef enum OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE
+{
+ /** Enum for PMEM information */
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM = 0x1
+} OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE;
+
+/** IL client will set the following structure. A failure
+ * code will be returned if component does not support the
+ * value provided for 'type'.
+ */
+struct OMX_QCOM_PLATFORMPRIVATE_EXTN
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX spec version information */
+ OMX_U32 nPortIndex; /** Port number on which usebuffer extn is applied */
+
+ /** Type of extensions should match an entry from
+ OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE
+ */
+ OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE type;
+};
+
+typedef struct OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO
+{
+ /** pmem file descriptor */
+ unsigned long pmem_fd;
+ /** Offset from pmem device base address */
+ OMX_U32 offset;
+ OMX_U32 size;
+ OMX_U32 mapped_size;
+ OMX_PTR buffer;
+}OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO;
+
+typedef struct OMX_QCOM_PLATFORM_PRIVATE_ENTRY
+{
+ /** Entry type */
+ OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE type;
+
+ /** Pointer to platform specific entry */
+ OMX_PTR entry;
+}OMX_QCOM_PLATFORM_PRIVATE_ENTRY;
+
+typedef struct OMX_QCOM_PLATFORM_PRIVATE_LIST
+{
+ /** Number of entries */
+ OMX_U32 nEntries;
+
+ /** Pointer to array of platform specific entries *
+ * Contiguous block of OMX_QCOM_PLATFORM_PRIVATE_ENTRY element
+ */
+ OMX_QCOM_PLATFORM_PRIVATE_ENTRY* entryList;
+}OMX_QCOM_PLATFORM_PRIVATE_LIST;
+
+#define OMX_QCOM_FRAME_PACKING_FORMAT "OMX.QCOM.index.param.framepackfmt"
+/* Allowed API call: OMX_GetParameter() */
+/* IL client can use this index to rerieve the list of frame formats *
+ * supported by the component */
+
+typedef struct OMX_QCOM_FRAME_PACKINGFORMAT_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nIndex;
+ OMX_QCOMFramePackingFormat eframePackingFormat;
+} OMX_QCOM_FRAME_PACKINGFORMAT_TYPE;
+
+
+/**
+ * Following is the enum for color formats supported on Qualcomm
+ * MSMs YVU420SemiPlanar color format is not defined in OpenMAX
+ * 1.1.1 and prior versions of OpenMAX specification.
+ */
+
+enum OMX_QCOM_COLOR_FORMATTYPE
+{
+
+/** YVU420SemiPlanar: YVU planar format, organized with a first
+ * plane containing Y pixels, and a second plane containing
+ * interleaved V and U pixels. V and U pixels are sub-sampled
+ * by a factor of two both horizontally and vertically.
+ */
+ QOMX_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00,
+ QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka,
+ QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka,
+ QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka,
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed,
+ QOMX_COLOR_Format32bitRGBA8888,
+ QOMX_COLOR_Format32bitRGBA8888Compressed,
+ QOMX_COLOR_FormatAndroidOpaque = (OMX_COLOR_FORMATTYPE) OMX_COLOR_FormatVendorStartUnused + 0x789,
+};
+
+enum OMX_QCOM_VIDEO_CODINGTYPE
+{
+/** Codecs support by qualcomm which are not listed in OMX 1.1.x
+ * spec
+ * */
+ OMX_QCOM_VIDEO_CodingVC1 = 0x7FA30C00 ,
+ OMX_QCOM_VIDEO_CodingWMV9 = 0x7FA30C01,
+ QOMX_VIDEO_CodingDivx = 0x7FA30C02, /**< Value when coding is Divx */
+ QOMX_VIDEO_CodingSpark = 0x7FA30C03, /**< Value when coding is Sorenson Spark */
+ QOMX_VIDEO_CodingVp = 0x7FA30C04,
+ QOMX_VIDEO_CodingVp8 = OMX_VIDEO_CodingVP8, /**< keeping old enum for backwards compatibility*/
+ QOMX_VIDEO_CodingHevc = OMX_VIDEO_CodingHEVC, /**< keeping old enum for backwards compatibility*/
+ QOMX_VIDEO_CodingMVC = 0x7FA30C07,
+ QOMX_VIDEO_CodingVp9 = OMX_VIDEO_CodingVP9, /**< keeping old enum for backwards compatibility*/
+};
+
+enum OMX_QCOM_EXTN_INDEXTYPE
+{
+ /** Qcom proprietary extension index list */
+
+ /* "OMX.QCOM.index.param.register_mmap" */
+ OMX_QcomIndexRegmmap = 0x7F000000,
+
+ /* "OMX.QCOM.index.param.platformprivate" */
+ OMX_QcomIndexPlatformPvt = 0x7F000001,
+
+ /* "OMX.QCOM.index.param.portdefn" */
+ OMX_QcomIndexPortDefn = 0x7F000002,
+
+ /* "OMX.QCOM.index.param.framepackingformat" */
+ OMX_QcomIndexPortFramePackFmt = 0x7F000003,
+
+ /*"OMX.QCOM.index.param.Interlaced */
+ OMX_QcomIndexParamInterlaced = 0x7F000004,
+
+ /*"OMX.QCOM.index.config.interlaceformat */
+ OMX_QcomIndexConfigInterlaced = 0x7F000005,
+
+ /*"OMX.QCOM.index.param.syntaxhdr" */
+ QOMX_IndexParamVideoSyntaxHdr = 0x7F000006,
+
+ /*"OMX.QCOM.index.config.intraperiod" */
+ QOMX_IndexConfigVideoIntraperiod = 0x7F000007,
+
+ /*"OMX.QCOM.index.config.randomIntrarefresh" */
+ QOMX_IndexConfigVideoIntraRefresh = 0x7F000008,
+
+ /*"OMX.QCOM.index.config.video.TemporalSpatialTradeOff" */
+ QOMX_IndexConfigVideoTemporalSpatialTradeOff = 0x7F000009,
+
+ /*"OMX.QCOM.index.param.video.EncoderMode" */
+ QOMX_IndexParamVideoEncoderMode = 0x7F00000A,
+
+ /*"OMX.QCOM.index.param.Divxtype */
+ OMX_QcomIndexParamVideoDivx = 0x7F00000B,
+
+ /*"OMX.QCOM.index.param.Sparktype */
+ OMX_QcomIndexParamVideoSpark = 0x7F00000C,
+
+ /*"OMX.QCOM.index.param.Vptype */
+ OMX_QcomIndexParamVideoVp = 0x7F00000D,
+
+ OMX_QcomIndexQueryNumberOfVideoDecInstance = 0x7F00000E,
+
+ OMX_QcomIndexParamVideoSyncFrameDecodingMode = 0x7F00000F,
+
+ OMX_QcomIndexParamVideoDecoderPictureOrder = 0x7F000010,
+
+ /* "OMX.QCOM.index.config.video.FramePackingInfo" */
+ OMX_QcomIndexConfigVideoFramePackingArrangement = 0x7F000011,
+
+ OMX_QcomIndexParamConcealMBMapExtraData = 0x7F000012,
+
+ OMX_QcomIndexParamFrameInfoExtraData = 0x7F000013,
+
+ OMX_QcomIndexParamInterlaceExtraData = 0x7F000014,
+
+ OMX_QcomIndexParamH264TimeInfo = 0x7F000015,
+
+ OMX_QcomIndexParamIndexExtraDataType = 0x7F000016,
+
+ OMX_GoogleAndroidIndexEnableAndroidNativeBuffers = 0x7F000017,
+
+ OMX_GoogleAndroidIndexUseAndroidNativeBuffer = 0x7F000018,
+
+ OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage = 0x7F000019,
+
+ /*"OMX.QCOM.index.config.video.QPRange" */
+ OMX_QcomIndexConfigVideoQPRange = 0x7F00001A,
+
+ /*"OMX.QCOM.index.param.EnableTimeStampReoder"*/
+ OMX_QcomIndexParamEnableTimeStampReorder = 0x7F00001B,
+
+ /*"OMX.google.android.index.storeMetaDataInBuffers"*/
+ OMX_QcomIndexParamVideoMetaBufferMode = 0x7F00001C,
+
+ /*"OMX.google.android.index.useAndroidNativeBuffer2"*/
+ OMX_GoogleAndroidIndexUseAndroidNativeBuffer2 = 0x7F00001D,
+
+ /*"OMX.QCOM.index.param.VideoMaxAllowedBitrateCheck"*/
+ OMX_QcomIndexParamVideoMaxAllowedBitrateCheck = 0x7F00001E,
+
+ OMX_QcomIndexEnableSliceDeliveryMode = 0x7F00001F,
+
+ /* "OMX.QCOM.index.param.video.ExtnUserExtraData" */
+ OMX_QcomIndexEnableExtnUserData = 0x7F000020,
+
+ /*"OMX.QCOM.index.param.video.EnableSmoothStreaming"*/
+ OMX_QcomIndexParamEnableSmoothStreaming = 0x7F000021,
+
+ /*"OMX.QCOM.index.param.video.QPRange" */
+ OMX_QcomIndexParamVideoQPRange = 0x7F000022,
+
+ OMX_QcomIndexEnableH263PlusPType = 0x7F000023,
+
+ /*"OMX.QCOM.index.param.video.LTRCountRangeSupported"*/
+ QOMX_IndexParamVideoLTRCountRangeSupported = 0x7F000024,
+
+ /*"OMX.QCOM.index.param.video.LTRMode"*/
+ QOMX_IndexParamVideoLTRMode = 0x7F000025,
+
+ /*"OMX.QCOM.index.param.video.LTRCount"*/
+ QOMX_IndexParamVideoLTRCount = 0x7F000026,
+
+ /*"OMX.QCOM.index.config.video.LTRPeriod"*/
+ QOMX_IndexConfigVideoLTRPeriod = 0x7F000027,
+
+ /*"OMX.QCOM.index.config.video.LTRUse"*/
+ QOMX_IndexConfigVideoLTRUse = 0x7F000028,
+
+ /*"OMX.QCOM.index.config.video.LTRMark"*/
+ QOMX_IndexConfigVideoLTRMark = 0x7F000029,
+
+ /* OMX.google.android.index.prependSPSPPSToIDRFrames */
+ OMX_QcomIndexParamSequenceHeaderWithIDR = 0x7F00002A,
+
+ OMX_QcomIndexParamH264AUDelimiter = 0x7F00002B,
+
+ OMX_QcomIndexParamVideoDownScalar = 0x7F00002C,
+
+ /* "OMX.QCOM.index.param.video.FramePackingExtradata" */
+ OMX_QcomIndexParamVideoFramePackingExtradata = 0x7F00002D,
+
+ /* "OMX.QCOM.index.config.activeregiondetection" */
+ OMX_QcomIndexConfigActiveRegionDetection = 0x7F00002E,
+
+ /* "OMX.QCOM.index.config.activeregiondetectionstatus" */
+ OMX_QcomIndexConfigActiveRegionDetectionStatus = 0x7F00002F,
+
+ /* "OMX.QCOM.index.config.scalingmode" */
+ OMX_QcomIndexConfigScalingMode = 0x7F000030,
+
+ /* "OMX.QCOM.index.config.noisereduction" */
+ OMX_QcomIndexConfigNoiseReduction = 0x7F000031,
+
+ /* "OMX.QCOM.index.config.imageenhancement" */
+ OMX_QcomIndexConfigImageEnhancement = 0x7F000032,
+
+ /* google smooth-streaming support */
+ OMX_QcomIndexParamVideoAdaptivePlaybackMode = 0x7F000033,
+
+ /* H.264 MVC codec index */
+ QOMX_IndexParamVideoMvc = 0x7F000034,
+
+ /* "OMX.QCOM.index.param.video.QPExtradata" */
+ OMX_QcomIndexParamVideoQPExtraData = 0x7F000035,
+
+ /* "OMX.QCOM.index.param.video.InputBitsInfoExtradata" */
+ OMX_QcomIndexParamVideoInputBitsInfoExtraData = 0x7F000036,
+
+ /* VP8 Hierarchical P support */
+ OMX_QcomIndexHierarchicalStructure = 0x7F000037,
+
+ OMX_QcomIndexParamPerfLevel = 0x7F000038,
+
+ OMX_QcomIndexParamH264VUITimingInfo = 0x7F000039,
+
+ OMX_QcomIndexParamPeakBitrate = 0x7F00003A,
+
+ /* Enable InitialQP index */
+ QOMX_IndexParamVideoInitialQp = 0x7F00003B,
+
+ OMX_QcomIndexParamSetMVSearchrange = 0x7F00003C,
+
+ OMX_QcomIndexConfigPerfLevel = 0x7F00003D,
+
+ /*"OMX.QCOM.index.param.video.LTRCount"*/
+ OMX_QcomIndexParamVideoLTRCount = QOMX_IndexParamVideoLTRCount,
+
+ /*"OMX.QCOM.index.config.video.LTRUse"*/
+ OMX_QcomIndexConfigVideoLTRUse = QOMX_IndexConfigVideoLTRUse,
+
+ /*"OMX.QCOM.index.config.video.LTRMark"*/
+ OMX_QcomIndexConfigVideoLTRMark = QOMX_IndexConfigVideoLTRMark,
+
+ /*"OMX.QCOM.index.param.video.CustomBufferSize"*/
+ OMX_QcomIndexParamVideoCustomBufferSize = 0x7F00003E,
+
+ /* Max Hierarchical P layers */
+ OMX_QcomIndexMaxHierarchicallayers = 0x7F000041,
+
+ /* Set Encoder Performance Index */
+ OMX_QcomIndexConfigVideoVencPerfMode = 0x7F000042,
+
+ /* Set Hybrid Hier-p layers */
+ OMX_QcomIndexParamVideoHybridHierpMode = 0x7F000043,
+
+ OMX_QcomIndexFlexibleYUVDescription = 0x7F000044,
+
+ /* Vpp Hqv Control Type */
+ OMX_QcomIndexParamVppHqvControl = 0x7F000045,
+
+ /* Enable VPP */
+ OMX_QcomIndexParamEnableVpp = 0x7F000046,
+
+ /* MBI statistics mode */
+ OMX_QcomIndexParamMBIStatisticsMode = 0x7F000047,
+
+ /* Set PictureTypeDecode */
+ OMX_QcomIndexConfigPictureTypeDecode = 0x7F000048,
+
+ OMX_QcomIndexConfigH264EntropyCodingCabac = 0x7F000049,
+
+ /* "OMX.QCOM.index.param.video.InputBatch" */
+ OMX_QcomIndexParamBatchSize = 0x7F00004A,
+
+ OMX_QcomIndexConfigNumHierPLayers = 0x7F00004B,
+
+ OMX_QcomIndexConfigRectType = 0x7F00004C,
+
+ OMX_QcomIndexConfigBaseLayerId = 0x7F00004E,
+
+ OMX_QcomIndexParamDriverVersion = 0x7F00004F,
+
+ OMX_QcomIndexConfigQp = 0x7F000050,
+
+ OMX_QcomIndexParamVencAspectRatio = 0x7F000051,
+
+ OMX_QTIIndexParamVQZipSEIExtraData = 0x7F000052,
+
+ /* Enable VQZIP SEI NAL type */
+ OMX_QTIIndexParamVQZIPSEIType = 0x7F000053,
+
+ OMX_QTIIndexParamPassInputBufferFd = 0x7F000054,
+
+ /* Set Prefer-adaptive playback*/
+ /* "OMX.QTI.index.param.video.PreferAdaptivePlayback" */
+ OMX_QTIIndexParamVideoPreferAdaptivePlayback = 0x7F000055,
+
+ /* Set time params */
+ OMX_QTIIndexConfigSetTimeData = 0x7F000056,
+ /* Force Compressed format for DPB when resolution <=1080p
+ * and OPB is cpu_access */
+ /* OMX.QTI.index.param.video.ForceCompressedForDPB */
+ OMX_QTIIndexParamForceCompressedForDPB = 0x7F000057,
+
+ /* Enable ROI info */
+ OMX_QTIIndexParamVideoEnableRoiInfo = 0x7F000058,
+
+ /* Configure ROI info */
+ OMX_QTIIndexConfigVideoRoiInfo = 0x7F000059,
+
+ /* Encoder Low Latency mode */
+ OMX_QcomIndexConfigVideoVencLowLatencyMode = 0x7F00005A,
+
+ /* Set Low Latency Mode */
+ OMX_QTIIndexParamLowLatencyMode = 0x7F00005B,
+
+ /* Force OPB to UnCompressed mode */
+ OMX_QTIIndexParamForceUnCompressedForOPB = 0x7F00005C,
+
+ /* OMX.google.android.index.allocateNativeHandle */
+ OMX_GoogleAndroidIndexAllocateNativeHandle = 0x7F00005D,
+
+ /* Configure BLUR resolution for encode */
+ OMX_QTIIndexConfigVideoBlurResolution = 0x7F00005E,
+
+ /* QP range for I frame B frame P frame */
+ OMX_QcomIndexParamVideoIPBQPRange = 0x7F00005F,
+
+ /* Enable client extradata */
+ OMX_QTIIndexParamVideoClientExtradata = 0x7F000060,
+
+ /* H264 transform 8x8 mode */
+ OMX_QcomIndexConfigH264Transform8x8 = 0x7F000061,
+
+ /*"OMX.google.android.index.describeColorAspects"*/
+ OMX_QTIIndexConfigDescribeColorAspects = 0x7F000062,
+
+ OMX_QTIIndexParamVUIExtraDataExtraData = 0x7F000063,
+
+ OMX_QTIIndexParamMPEG2SeqDispExtraData = 0x7F000064,
+
+ OMX_QTIIndexParamVC1SeqDispExtraData = 0x7F000065,
+
+ OMX_QTIIndexParamVPXColorSpaceExtraData = 0x7F000066,
+
+};
+
+/**
+* This is custom extension to configure Low Latency Mode.
+*
+* STRUCT MEMBERS
+*
+* nSize : Size of Structure in bytes
+* nVersion : OpenMAX IL specification version information
+* bLowLatencyMode : Enable/Disable Low Latency mode
+*/
+
+typedef struct QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bLowLatencyMode;
+} QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE;
+
+/**
+* This is custom extension to configure Encoder Aspect Ratio.
+*
+* STRUCT MEMBERS
+*
+* nSize : Size of Structure in bytes
+* nVersion : OpenMAX IL specification version information
+* nSARWidth : Horizontal aspect size
+* nSARHeight : Vertical aspect size
+*/
+
+typedef struct QOMX_EXTNINDEX_VIDEO_VENC_SAR
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nSARWidth;
+ OMX_U32 nSARHeight;
+} QOMX_EXTNINDEX_VIDEO_VENC_SAR;
+
+/**
+* This is custom extension to configure Hier-p layers.
+* This mode configures Hier-p layers dynamically.
+*
+* STRUCT MEMBERS
+*
+* nSize : Size of Structure in bytes
+* nVersion : OpenMAX IL specification version information
+* nNumHierLayers: Set the number of Hier-p layers for the session
+* - This should be less than the MAX Hier-P
+* layers set for the session.
+*/
+
+typedef struct QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nNumHierLayers;
+} QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS;
+
+
+/**
+* This is custom extension to configure Hybrid Hier-p settings.
+* This mode is different from enabling Hier-p mode. This
+* property enables Hier-p encoding with LTR referencing in each
+* sub-GOP.
+*
+* STRUCT MEMBERS
+*
+* nSize : Size of Structure in bytes
+* nVersion : OpenMAX IL specification version information
+* nKeyFrameInterval : Indicates the I frame interval
+* nHpLayers : Set the number of Hier-p layers for the session
+* - This should be <= 6. (1 Base layer +
+* 5 Enhancement layers)
+* nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HP_LAYERS] : Bitrate to
+* be set for each enhancement layer
+* nMinQuantizer : minimum session QP
+* nMaxQuantizer : Maximun session QP
+*/
+
+typedef struct QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nKeyFrameInterval;
+ OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HP_LAYERS];
+ OMX_U32 nMinQuantizer;
+ OMX_U32 nMaxQuantizer;
+ OMX_U32 nHpLayers;
+} QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE;
+
+/**
+ * Encoder Performance Mode. This structure is used to set
+ * performance mode or power save mode when encoding. The search
+ * range is modified to save power or improve quality.
+ *
+ * STRUCT MEMBERS:
+ * OMX_U32 nPerfMode : Performance mode:
+ * 1: MAX_QUALITY
+ * 2: POWER_SAVE
+ */
+
+typedef struct QOMX_EXTNINDEX_VIDEO_PERFMODE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPerfMode;
+} QOMX_EXTNINDEX_VIDEO_PERFMODE;
+
+/**
+ * Initial QP parameter. This structure is used to enable
+ * vendor specific extension to let client enable setting
+ * initial QP values to I P B Frames
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure in bytes
+ * nVersion : OpenMAX IL specification version information
+ * nPortIndex : Index of the port to which this structure applies
+ * OMX_U32 nQpI : First Iframe QP
+ * OMX_U32 nQpP : First Pframe QP
+ * OMX_U32 nQpB : First Bframe QP
+ * OMX_U32 bEnableInitQp : Bit field indicating which frame type(s) shall
+ * use the specified initial QP.
+ * Bit 0: Enable initial QP for I/IDR
+ * and use value specified in nInitQpI
+ * Bit 1: Enable initial QP for P
+ * and use value specified in nInitQpP
+ * Bit 2: Enable initial QP for B
+ * and use value specified in nInitQpB
+ */
+
+typedef struct QOMX_EXTNINDEX_VIDEO_INITIALQP {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nQpI;
+ OMX_U32 nQpP;
+ OMX_U32 nQpB;
+ OMX_U32 bEnableInitQp;
+} QOMX_EXTNINDEX_VIDEO_INITIALQP;
+
+/**
+ * Extension index parameter. This structure is used to enable
+ * vendor specific extension on input/output port and
+ * to pass the required flags and data, if any.
+ * The format of flags and data being passed is known to
+ * the client and component apriori.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure plus pData size
+ * nVersion : OMX specification version information
+ * nPortIndex : Indicates which port to set
+ * bEnable : Extension index enable (1) or disable (0)
+ * nFlags : Extension index flags, if any
+ * nDataSize : Size of the extension index data to follow
+ * pData : Extension index data, if present.
+ */
+typedef struct QOMX_EXTNINDEX_PARAMTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ OMX_U32 nFlags;
+ OMX_U32 nDataSize;
+ OMX_PTR pData;
+} QOMX_EXTNINDEX_PARAMTYPE;
+
+/**
+ * Range index parameter. This structure is used to enable
+ * vendor specific extension on input/output port and
+ * to pass the required minimum and maximum values
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure in bytes
+ * nVersion : OpenMAX IL specification version information
+ * nPortIndex : Index of the port to which this structure applies
+ * nMin : Minimum value
+ * nMax : Maximum value
+ * nSteSize : Step size
+ */
+typedef struct QOMX_EXTNINDEX_RANGETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nMin;
+ OMX_S32 nMax;
+ OMX_S32 nStepSize;
+} QOMX_EXTNINDEX_RANGETYPE;
+
+/**
+ * Specifies LTR mode types.
+ */
+typedef enum QOMX_VIDEO_LTRMODETYPE
+{
+ QOMX_VIDEO_LTRMode_Disable = 0x0, /**< LTR encoding is disabled */
+ QOMX_VIDEO_LTRMode_Manual = 0x1, /**< In this mode, IL client configures
+ ** the encoder the LTR count and manually
+ ** controls the marking and use of LTR
+ ** frames during video encoding.
+ */
+ QOMX_VIDEO_LTRMode_Auto = 0x2, /**< In this mode, IL client configures
+ ** the encoder the LTR count and LTR
+ ** period. The encoder marks LTR frames
+ ** automatically based on the LTR period
+ ** during video encoding. IL client controls
+ ** the use of LTR frames.
+ */
+ QOMX_VIDEO_LTRMode_MAX = 0x7FFFFFFF /** Maximum LTR Mode type */
+} QOMX_VIDEO_LTRMODETYPE;
+
+/**
+ * LTR mode index parameter. This structure is used
+ * to enable vendor specific extension on output port
+ * to pass the LTR mode information.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure in bytes
+ * nVersion : OpenMAX IL specification version information
+ * nPortIndex : Index of the port to which this structure applies
+ * eLTRMode : Specifies the LTR mode used in encoder
+ */
+typedef struct QOMX_VIDEO_PARAM_LTRMODE_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_LTRMODETYPE eLTRMode;
+} QOMX_VIDEO_PARAM_LTRMODE_TYPE;
+
+/**
+ * LTR count index parameter. This structure is used
+ * to enable vendor specific extension on output port
+ * to pass the LTR count information.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure in bytes
+ * nVersion : OpenMAX IL specification version information
+ * nPortIndex : Index of the port to which this structure applies
+ * nCount : Specifies the number of LTR frames stored in the
+ * encoder component
+ */
+typedef struct QOMX_VIDEO_PARAM_LTRCOUNT_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nCount;
+} QOMX_VIDEO_PARAM_LTRCOUNT_TYPE;
+
+
+/**
+ * This should be used with OMX_QcomIndexParamVideoLTRCount extension.
+ */
+typedef QOMX_VIDEO_PARAM_LTRCOUNT_TYPE OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE;
+
+/**
+ * LTR period index parameter. This structure is used
+ * to enable vendor specific extension on output port
+ * to pass the LTR period information.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure in bytes
+ * nVersion : OpenMAX IL specification version information
+ * nPortIndex : Index of the port to which this structure applies
+ * nFrames : Specifies the number of frames between two consecutive
+ * LTR frames.
+ */
+typedef struct QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nFrames;
+} QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE;
+
+/**
+ * Marks the next encoded frame as an LTR frame.
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure in bytes
+ * nVersion : OpenMAX IL specification version information
+ * nPortIndex : Index of the port to which this structure applies
+ * nID : Specifies the identifier of the LTR frame to be marked
+ * as reference frame for encoding subsequent frames.
+ */
+typedef struct QOMX_VIDEO_CONFIG_LTRMARK_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nID;
+} QOMX_VIDEO_CONFIG_LTRMARK_TYPE;
+
+/**
+ * This should be used with OMX_QcomIndexConfigVideoLTRMark extension.
+ */
+typedef QOMX_VIDEO_CONFIG_LTRMARK_TYPE OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE;
+
+/**
+ * Specifies an LTR frame to encode subsequent frames.
+ * STRUCT MEMBERS:
+ * nSize : Size of Structure in bytes
+ * nVersion : OpenMAX IL specification version information
+ * nPortIndex : Index of the port to which this structure applies
+ * nID : Specifies the identifier of the LTR frame to be used
+ as reference frame for encoding subsequent frames.
+ * nFrames : Specifies the number of subsequent frames to be
+ encoded using the LTR frame with its identifier
+ nID as reference frame. Short-term reference frames
+ will be used thereafter. The value of 0xFFFFFFFF
+ indicates that all subsequent frames will be
+ encodedusing this LTR frame as reference frame.
+ */
+typedef struct QOMX_VIDEO_CONFIG_LTRUSE_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nID;
+ OMX_U32 nFrames;
+} QOMX_VIDEO_CONFIG_LTRUSE_TYPE;
+
+/**
+ * This should be used with OMX_QcomIndexConfigVideoLTRUse extension.
+ */
+typedef QOMX_VIDEO_CONFIG_LTRUSE_TYPE OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE;
+
+/**
+ * Enumeration used to define the video encoder modes
+ *
+ * ENUMS:
+ * EncoderModeDefault : Default video recording mode.
+ * All encoder settings made through
+ * OMX_SetParameter/OMX_SetConfig are applied. No
+ * parameter is overridden.
+ * EncoderModeMMS : Video recording mode for MMS (Multimedia Messaging
+ * Service). This mode is similar to EncoderModeDefault
+ * except that here the Rate control mode is overridden
+ * internally and set as a variant of variable bitrate with
+ * variable frame rate. After this mode is set if the IL
+ * client tries to set OMX_VIDEO_CONTROLRATETYPE via
+ * OMX_IndexParamVideoBitrate that would be rejected. For
+ * this, client should set mode back to EncoderModeDefault
+ * first and then change OMX_VIDEO_CONTROLRATETYPE.
+ */
+typedef enum QOMX_VIDEO_ENCODERMODETYPE
+{
+ QOMX_VIDEO_EncoderModeDefault = 0x00,
+ QOMX_VIDEO_EncoderModeMMS = 0x01,
+ QOMX_VIDEO_EncoderModeMax = 0x7FFFFFFF
+} QOMX_VIDEO_ENCODERMODETYPE;
+
+/**
+ * This structure is used to set the video encoder mode.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nMode : defines the video encoder mode
+ */
+typedef struct QOMX_VIDEO_PARAM_ENCODERMODETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_ENCODERMODETYPE nMode;
+} QOMX_VIDEO_PARAM_ENCODERMODETYPE;
+
+/**
+ * This structure describes the parameters corresponding to the
+ * QOMX_VIDEO_SYNTAXHDRTYPE extension. This parameter can be queried
+ * during the loaded state.
+ */
+
+typedef struct QOMX_VIDEO_SYNTAXHDRTYPE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_U32 nBytes; /** The number of bytes filled in to the buffer */
+ OMX_U8 data[1]; /** Buffer to store the header information */
+} QOMX_VIDEO_SYNTAXHDRTYPE;
+
+/**
+ * This structure describes the parameters corresponding to the
+ * QOMX_VIDEO_TEMPORALSPATIALTYPE extension. This parameter can be set
+ * dynamically during any state except the state invalid. This is primarily
+ * used for setting MaxQP from the application. This is set on the out port.
+ */
+
+typedef struct QOMX_VIDEO_TEMPORALSPATIALTYPE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_U32 nTSFactor; /** Temoral spatial tradeoff factor value in 0-100 */
+} QOMX_VIDEO_TEMPORALSPATIALTYPE;
+
+/**
+ * This structure describes the parameters corresponding to the
+ * OMX_QCOM_VIDEO_CONFIG_INTRAPERIODTYPE extension. This parameter can be set
+ * dynamically during any state except the state invalid. This is set on the out port.
+ */
+
+typedef struct QOMX_VIDEO_INTRAPERIODTYPE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_U32 nIDRPeriod; /** This specifies coding a frame as IDR after every nPFrames
+ of intra frames. If this parameter is set to 0, only the
+ first frame of the encode session is an IDR frame. This
+ field is ignored for non-AVC codecs and is used only for
+ codecs that support IDR Period */
+ OMX_U32 nPFrames; /** The number of "P" frames between two "I" frames */
+ OMX_U32 nBFrames; /** The number of "B" frames between two "I" frames */
+} QOMX_VIDEO_INTRAPERIODTYPE;
+
+/**
+ * This structure describes the parameters corresponding to the
+ * OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE extension. This parameter can be set
+ * dynamically during any state except the state invalid. This is used for the buffer negotiation
+ * with other clients. This is set on the out port.
+ */
+typedef struct OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_U32 nBufferOccupancy; /** The number of bytes to be set for the buffer occupancy */
+} OMX_QCOM_VIDEO_CONFIG_ULBUFFEROCCUPANCYTYPE;
+
+/**
+ * This structure describes the parameters corresponding to the
+ * OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE extension. This parameter can be set
+ * dynamically during any state except the state invalid. This is primarily used for the dynamic/random
+ * intrarefresh. This is set on the out port.
+ */
+typedef struct OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_U32 nRirMBs; /** The number of MBs to be set for intrarefresh */
+} OMX_QCOM_VIDEO_CONFIG_RANDOMINTRAREFRESHTYPE;
+
+
+/**
+ * This structure describes the parameters corresponding to the
+ * OMX_QCOM_VIDEO_CONFIG_QPRANGE extension. This parameter can be set
+ * dynamically during any state except the state invalid. This is primarily
+ * used for the min/max QP to be set from the application. This
+ * is set on the out port.
+ */
+typedef struct OMX_QCOM_VIDEO_CONFIG_QPRANGE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_U32 nMinQP; /** The number for minimum quantization parameter */
+ OMX_U32 nMaxQP; /** The number for maximum quantization parameter */
+} OMX_QCOM_VIDEO_CONFIG_QPRANGE;
+
+/**
+ * This structure describes the parameters for the
+ * OMX_QcomIndexParamH264AUDelimiter extension. It enables/disables
+ * the AU delimiters in the H264 stream, which is used by WFD.
+ */
+typedef struct OMX_QCOM_VIDEO_CONFIG_H264_AUD
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_BOOL bEnable; /** Enable/disable the setting */
+} OMX_QCOM_VIDEO_CONFIG_H264_AUD;
+
+typedef enum QOMX_VIDEO_PERF_LEVEL
+{
+ OMX_QCOM_PerfLevelNominal,
+ OMX_QCOM_PerfLevelTurbo
+} QOMX_VIDEO_PERF_LEVEL;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QcomIndexParamPerfLevel extension. It will set
+ * the performance mode specified as QOMX_VIDEO_PERF_LEVEL.
+ */
+typedef struct OMX_QCOM_VIDEO_PARAM_PERF_LEVEL {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ QOMX_VIDEO_PERF_LEVEL ePerfLevel; /** Performance level */
+} OMX_QCOM_VIDEO_PARAM_PERF_LEVEL;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QcomIndexConfigPerfLevel extension. It will set
+ * the performance mode specified as QOMX_VIDEO_PERF_LEVEL.
+ */
+typedef struct OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ QOMX_VIDEO_PERF_LEVEL ePerfLevel; /** Performance level */
+} OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL;
+
+typedef enum QOMX_VIDEO_PICTURE_TYPE_DECODE
+{
+ OMX_QCOM_PictypeDecode_IPB,
+ OMX_QCOM_PictypeDecode_I
+} QOMX_VIDEO_PICTURE_TYPE_DECODE;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QcomIndexConfigPictureTypeDecode extension. It
+ * will set the picture type decode specified by eDecodeType.
+ */
+typedef struct OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ QOMX_VIDEO_PICTURE_TYPE_DECODE eDecodeType; /** Decode type */
+} OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QcomIndexParamH264VUITimingInfo extension. It
+ * will enable/disable the VUI timing info.
+ */
+typedef struct OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ OMX_BOOL bEnable; /** Enable/disable the setting */
+} OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QcomIndexParamVQZIPSEIType extension. It
+ * will enable/disable the VQZIP SEI info.
+ */
+typedef struct OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ OMX_BOOL bEnable; /** Enable/disable the setting */
+} OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QcomIndexParamPeakBitrate extension. It will
+ * set the peak bitrate specified by nPeakBitrate.
+ */
+typedef struct OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ OMX_U32 nPeakBitrate; /** Peak bitrate value */
+} OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QTIIndexParamForceCompressedForDPB extension. Enabling
+ * this extension will force the split mode DPB(compressed)/OPB(Linear)
+ * for all resolutions.On some chipsets preferred mode would be combined
+ * Linear for both DPB/OPB to save memory. For example on 8996 preferred mode
+ * would be combined linear for resolutions <= 1080p .
+ * Enabling this might save power but with the cost
+ * of increased memory i.e almost double the number on output YUV buffers.
+ */
+typedef struct OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ OMX_BOOL bEnable; /** Enable/disable the setting */
+} OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE;
+
+/**
+ * This structure describes the parameters corresponding
+ * to OMX_QTIIndexParamForceUnCompressedForOPB extension. Enabling this
+ * extension will force the OPB to be linear for the current video session.
+ * If this property is not set, then the OPB will be set to linear or compressed
+ * based on resolution selected and/or if cpu access is requested on the
+ * OPB buffer.
+ */
+typedef struct OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE {
+ OMX_U32 nSize; /** Sizeo f the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /** OMX specification version information */
+ OMX_BOOL bEnable; /** Enable/disable the setting */
+} OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE;
+
+typedef struct OMX_VENDOR_EXTRADATATYPE {
+ OMX_U32 nPortIndex;
+ OMX_U32 nDataSize;
+ OMX_U8 *pData; // cdata (codec_data/extradata)
+} OMX_VENDOR_EXTRADATATYPE;
+
+/**
+ * This structure describes the parameters corresponding to the
+ * OMX_VENDOR_VIDEOFRAMERATE extension. This parameter can be set
+ * dynamically during any state except the state invalid. This is
+ * used for frame rate to be set from the application. This
+ * is set on the in port.
+ */
+typedef struct OMX_VENDOR_VIDEOFRAMERATE {
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_U32 nFps; /** Frame rate value */
+ OMX_BOOL bEnabled; /** Flag to enable or disable client's frame rate value */
+} OMX_VENDOR_VIDEOFRAMERATE;
+
+typedef enum OMX_INDEXVENDORTYPE {
+ OMX_IndexVendorFileReadInputFilename = 0xFF000001,
+ OMX_IndexVendorParser3gpInputFilename = 0xFF000002,
+ OMX_IndexVendorVideoExtraData = 0xFF000003,
+ OMX_IndexVendorAudioExtraData = 0xFF000004,
+ OMX_IndexVendorVideoFrameRate = 0xFF000005,
+} OMX_INDEXVENDORTYPE;
+
+typedef enum OMX_QCOM_VC1RESOLUTIONTYPE
+{
+ OMX_QCOM_VC1_PICTURE_RES_1x1,
+ OMX_QCOM_VC1_PICTURE_RES_2x1,
+ OMX_QCOM_VC1_PICTURE_RES_1x2,
+ OMX_QCOM_VC1_PICTURE_RES_2x2
+} OMX_QCOM_VC1RESOLUTIONTYPE;
+
+typedef enum OMX_QCOM_INTERLACETYPE
+{
+ OMX_QCOM_InterlaceFrameProgressive,
+ OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst,
+ OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst,
+ OMX_QCOM_InterlaceFrameTopFieldFirst,
+ OMX_QCOM_InterlaceFrameBottomFieldFirst,
+ OMX_QCOM_InterlaceFieldTop,
+ OMX_QCOM_InterlaceFieldBottom
+}OMX_QCOM_INTERLACETYPE;
+
+typedef struct OMX_QCOM_PARAM_VIDEO_INTERLACETYPE
+{
+ OMX_U32 nSize; /** Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/** OMX specification version information */
+ OMX_U32 nPortIndex; /** Portindex which is extended by this structure */
+ OMX_BOOL bInterlace; /** Interlace content **/
+}OMX_QCOM_PARAM_VIDEO_INTERLACETYPE;
+
+typedef struct OMX_QCOM_CONFIG_INTERLACETYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nIndex;
+ OMX_QCOM_INTERLACETYPE eInterlaceType;
+}OMX_QCOM_CONFIG_INTERLACETYPE;
+
+#define MAX_PAN_SCAN_WINDOWS 4
+
+typedef struct OMX_QCOM_PANSCAN
+{
+ OMX_U32 numWindows;
+ OMX_QCOMRectangle window[MAX_PAN_SCAN_WINDOWS];
+} OMX_QCOM_PANSCAN;
+
+typedef struct OMX_QCOM_ASPECT_RATIO
+{
+ OMX_U32 aspectRatioX;
+ OMX_U32 aspectRatioY;
+} OMX_QCOM_ASPECT_RATIO;
+
+typedef struct OMX_QCOM_DISPLAY_ASPECT_RATIO
+{
+ OMX_U32 displayVerticalSize;
+ OMX_U32 displayHorizontalSize;
+} OMX_QCOM_DISPLAY_ASPECT_RATIO;
+
+typedef struct OMX_QCOM_FRAME_PACK_ARRANGEMENT
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 id;
+ OMX_U32 cancel_flag;
+ OMX_U32 type;
+ OMX_U32 quincunx_sampling_flag;
+ OMX_U32 content_interpretation_type;
+ OMX_U32 spatial_flipping_flag;
+ OMX_U32 frame0_flipped_flag;
+ OMX_U32 field_views_flag;
+ OMX_U32 current_frame_is_frame0_flag;
+ OMX_U32 frame0_self_contained_flag;
+ OMX_U32 frame1_self_contained_flag;
+ OMX_U32 frame0_grid_position_x;
+ OMX_U32 frame0_grid_position_y;
+ OMX_U32 frame1_grid_position_x;
+ OMX_U32 frame1_grid_position_y;
+ OMX_U32 reserved_byte;
+ OMX_U32 repetition_period;
+ OMX_U32 extension_flag;
+} OMX_QCOM_FRAME_PACK_ARRANGEMENT;
+
+typedef struct OMX_QCOM_EXTRADATA_QP
+{
+ OMX_U32 nQP;
+} OMX_QCOM_EXTRADATA_QP;
+
+typedef struct OMX_QCOM_EXTRADATA_BITS_INFO
+{
+ OMX_U32 header_bits;
+ OMX_U32 frame_bits;
+} OMX_QCOM_EXTRADATA_BITS_INFO;
+
+typedef struct OMX_QCOM_EXTRADATA_USERDATA {
+ OMX_U32 type;
+ OMX_U32 data[1];
+} OMX_QCOM_EXTRADATA_USERDATA;
+
+typedef struct OMX_QCOM_EXTRADATA_FRAMEINFO
+{
+ // common frame meta data. interlace related info removed
+ OMX_VIDEO_PICTURETYPE ePicType;
+ OMX_QCOM_INTERLACETYPE interlaceType;
+ OMX_QCOM_PANSCAN panScan;
+ OMX_QCOM_ASPECT_RATIO aspectRatio;
+ OMX_QCOM_DISPLAY_ASPECT_RATIO displayAspectRatio;
+ OMX_U32 nConcealedMacroblocks;
+ OMX_U32 nFrameRate;
+ OMX_TICKS nTimeStamp;
+} OMX_QCOM_EXTRADATA_FRAMEINFO;
+
+typedef struct OMX_QCOM_EXTRADATA_FRAMEDIMENSION
+{
+ /** Frame Dimensions added to each YUV buffer */
+ OMX_U32 nDecWidth; /** Width rounded to multiple of 16 */
+ OMX_U32 nDecHeight; /** Height rounded to multiple of 16 */
+ OMX_U32 nActualWidth; /** Actual Frame Width */
+ OMX_U32 nActualHeight; /** Actual Frame Height */
+
+} OMX_QCOM_EXTRADATA_FRAMEDIMENSION;
+
+typedef struct OMX_QCOM_H264EXTRADATA
+{
+ OMX_U64 seiTimeStamp;
+} OMX_QCOM_H264EXTRADATA;
+
+typedef struct OMX_QCOM_VC1EXTRADATA
+{
+ OMX_U32 nVC1RangeY;
+ OMX_U32 nVC1RangeUV;
+ OMX_QCOM_VC1RESOLUTIONTYPE eVC1PicResolution;
+} OMX_QCOM_VC1EXTRADATA;
+
+typedef union OMX_QCOM_EXTRADATA_CODEC_DATA
+{
+ OMX_QCOM_H264EXTRADATA h264ExtraData;
+ OMX_QCOM_VC1EXTRADATA vc1ExtraData;
+} OMX_QCOM_EXTRADATA_CODEC_DATA;
+
+typedef struct OMX_QCOM_EXTRADATA_MBINFO
+{
+ OMX_U32 nFormat;
+ OMX_U32 nDataSize;
+ OMX_U8 data[0];
+} OMX_QCOM_EXTRADATA_MBINFO;
+
+typedef struct OMX_QCOM_EXTRADATA_VQZIPSEI {
+ OMX_U32 nSize;
+ OMX_U8 data[0];
+} OMX_QCOM_EXTRADATA_VQZIPSEI;
+
+typedef struct OMX_QTI_VIDEO_PARAM_ENABLE_ROIINFO {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnableRoiInfo;
+} OMX_QTI_VIDEO_PARAM_ENABLE_ROIINFO;
+
+typedef struct OMX_QTI_VIDEO_CONFIG_ROIINFO {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_S32 nUpperQpOffset;
+ OMX_S32 nLowerQpOffset;
+ OMX_BOOL bUseRoiInfo;
+ OMX_S32 nRoiMBInfoSize;
+ OMX_PTR pRoiMBInfo;
+} OMX_QTI_VIDEO_CONFIG_ROIINFO;
+
+typedef enum OMX_QTI_VIDEO_BLUR_RESOLUTION {
+ BLUR_RESOL_DISABLED = 0,
+ BLUR_RESOL_240 = 1,
+ BLUR_RESOL_480 = 2,
+ BLUR_RESOL_720 = 3,
+ BLUR_RESOL_1080 = 4,
+} OMX_QTI_VIDEO_BLUR_RESOLUTION;
+
+typedef struct OMX_QTI_VIDEO_CONFIG_BLURINFO {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_QTI_VIDEO_BLUR_RESOLUTION eTargetResol;
+} OMX_QTI_VIDEO_CONFIG_BLURINFO;
+
+typedef enum OMX_QCOM_EXTRADATATYPE
+{
+ OMX_ExtraDataFrameInfo = 0x7F000001,
+ OMX_ExtraDataH264 = 0x7F000002,
+ OMX_ExtraDataVC1 = 0x7F000003,
+ OMX_ExtraDataFrameDimension = 0x7F000004,
+ OMX_ExtraDataVideoEncoderSliceInfo = 0x7F000005,
+ OMX_ExtraDataConcealMB = 0x7F000006,
+ OMX_ExtraDataInterlaceFormat = 0x7F000007,
+ OMX_ExtraDataPortDef = 0x7F000008,
+ OMX_ExtraDataMP2ExtnData = 0x7F000009,
+ OMX_ExtraDataMP2UserData = 0x7F00000a,
+ OMX_ExtraDataVideoLTRInfo = 0x7F00000b,
+ OMX_ExtraDataFramePackingArrangement = 0x7F00000c,
+ OMX_ExtraDataQP = 0x7F00000d,
+ OMX_ExtraDataInputBitsInfo = 0x7F00000e,
+ OMX_ExtraDataVideoEncoderMBInfo = 0x7F00000f,
+ OMX_ExtraDataVQZipSEI = 0x7F000010,
+ OMX_ExtraDataDisplayColourSEI = 0x7F000011,
+ OMX_ExtraDataLightLevelSEI = 0x7F000012,
+ OMX_ExtraDataEncoderOverrideQPInfo = 0x7F000013,
+} OMX_QCOM_EXTRADATATYPE;
+
+typedef struct OMX_STREAMINTERLACEFORMATTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bInterlaceFormat;
+ OMX_U32 nInterlaceFormats;
+} OMX_STREAMINTERLACEFORMAT;
+
+typedef enum OMX_INTERLACETYPE
+{
+ OMX_InterlaceFrameProgressive,
+ OMX_InterlaceInterleaveFrameTopFieldFirst,
+ OMX_InterlaceInterleaveFrameBottomFieldFirst,
+ OMX_InterlaceFrameTopFieldFirst,
+ OMX_InterlaceFrameBottomFieldFirst
+} OMX_INTERLACES;
+
+
+#define OMX_EXTRADATA_HEADER_SIZE 20
+
+/**
+ * AVC profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ */
+typedef enum QOMX_VIDEO_AVCPROFILETYPE {
+ QOMX_VIDEO_AVCProfileBaseline = OMX_VIDEO_AVCProfileBaseline,
+ QOMX_VIDEO_AVCProfileMain = OMX_VIDEO_AVCProfileMain,
+ QOMX_VIDEO_AVCProfileExtended = OMX_VIDEO_AVCProfileExtended,
+ QOMX_VIDEO_AVCProfileHigh = OMX_VIDEO_AVCProfileHigh,
+ QOMX_VIDEO_AVCProfileHigh10 = OMX_VIDEO_AVCProfileHigh10,
+ QOMX_VIDEO_AVCProfileHigh422 = OMX_VIDEO_AVCProfileHigh422,
+ QOMX_VIDEO_AVCProfileHigh444 = OMX_VIDEO_AVCProfileHigh444,
+ /* QCom specific profile indexes */
+ QOMX_VIDEO_AVCProfileConstrained = OMX_VIDEO_AVCProfileVendorStartUnused,
+ QOMX_VIDEO_AVCProfileConstrainedBaseline,
+ QOMX_VIDEO_AVCProfileConstrainedHigh,
+} QOMX_VIDEO_AVCPROFILETYPE;
+
+
+/**
+ * H.264 MVC Profiles
+ */
+typedef enum QOMX_VIDEO_MVCPROFILETYPE {
+ QOMX_VIDEO_MVCProfileStereoHigh = 0x1,
+ QOMX_VIDEO_MVCProfileMultiViewHigh = 0x2,
+ QOMX_VIDEO_MVCProfileKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_MVCProfileVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_MVCProfileMax = 0x7FFFFFFF
+} QOMX_VIDEO_MVCPROFILETYPE;
+
+/**
+ * H.264 MVC Levels
+ */
+typedef enum QOMX_VIDEO_MVCLEVELTYPE {
+ QOMX_VIDEO_MVCLevel1 = 0x01, /**< Level 1 */
+ QOMX_VIDEO_MVCLevel1b = 0x02, /**< Level 1b */
+ QOMX_VIDEO_MVCLevel11 = 0x04, /**< Level 1.1 */
+ QOMX_VIDEO_MVCLevel12 = 0x08, /**< Level 1.2 */
+ QOMX_VIDEO_MVCLevel13 = 0x10, /**< Level 1.3 */
+ QOMX_VIDEO_MVCLevel2 = 0x20, /**< Level 2 */
+ QOMX_VIDEO_MVCLevel21 = 0x40, /**< Level 2.1 */
+ QOMX_VIDEO_MVCLevel22 = 0x80, /**< Level 2.2 */
+ QOMX_VIDEO_MVCLevel3 = 0x100, /**< Level 3 */
+ QOMX_VIDEO_MVCLevel31 = 0x200, /**< Level 3.1 */
+ QOMX_VIDEO_MVCLevel32 = 0x400, /**< Level 3.2 */
+ QOMX_VIDEO_MVCLevel4 = 0x800, /**< Level 4 */
+ QOMX_VIDEO_MVCLevel41 = 0x1000, /**< Level 4.1 */
+ QOMX_VIDEO_MVCLevel42 = 0x2000, /**< Level 4.2 */
+ QOMX_VIDEO_MVCLevel5 = 0x4000, /**< Level 5 */
+ QOMX_VIDEO_MVCLevel51 = 0x8000, /**< Level 5.1 */
+ QOMX_VIDEO_MVCLevelKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_MVCLevelVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_MVCLevelMax = 0x7FFFFFFF
+} QOMX_VIDEO_MVCLEVELTYPE;
+
+/**
+ * DivX Versions
+ */
+typedef enum QOMX_VIDEO_DIVXFORMATTYPE {
+ QOMX_VIDEO_DIVXFormatUnused = 0x01, /**< Format unused or unknown */
+ QOMX_VIDEO_DIVXFormat311 = 0x02, /**< DivX 3.11 */
+ QOMX_VIDEO_DIVXFormat4 = 0x04, /**< DivX 4 */
+ QOMX_VIDEO_DIVXFormat5 = 0x08, /**< DivX 5 */
+ QOMX_VIDEO_DIVXFormat6 = 0x10, /**< DivX 6 */
+ QOMX_VIDEO_DIVXFormatKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_DIVXFormatVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_DIVXFormatMax = 0x7FFFFFFF
+} QOMX_VIDEO_DIVXFORMATTYPE;
+
+/**
+ * DivX profile types, each profile indicates support for
+ * various performance bounds.
+ */
+typedef enum QOMX_VIDEO_DIVXPROFILETYPE {
+ QOMX_VIDEO_DivXProfileqMobile = 0x01, /**< qMobile Profile */
+ QOMX_VIDEO_DivXProfileMobile = 0x02, /**< Mobile Profile */
+ QOMX_VIDEO_DivXProfileMT = 0x04, /**< Mobile Theatre Profile */
+ QOMX_VIDEO_DivXProfileHT = 0x08, /**< Home Theatre Profile */
+ QOMX_VIDEO_DivXProfileHD = 0x10, /**< High Definition Profile */
+ QOMX_VIDEO_DIVXProfileKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_DIVXProfileVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_DIVXProfileMax = 0x7FFFFFFF
+} QOMX_VIDEO_DIVXPROFILETYPE;
+
+/**
+ * DivX Video Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Version of DivX stream / data
+ * eProfile : Profile of DivX stream / data
+ */
+typedef struct QOMX_VIDEO_PARAM_DIVXTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_DIVXFORMATTYPE eFormat;
+ QOMX_VIDEO_DIVXPROFILETYPE eProfile;
+} QOMX_VIDEO_PARAM_DIVXTYPE;
+
+
+
+/**
+ * VP Versions
+ */
+typedef enum QOMX_VIDEO_VPFORMATTYPE {
+ QOMX_VIDEO_VPFormatUnused = 0x01, /**< Format unused or unknown */
+ QOMX_VIDEO_VPFormat6 = 0x02, /**< VP6 Video Format */
+ QOMX_VIDEO_VPFormat7 = 0x04, /**< VP7 Video Format */
+ QOMX_VIDEO_VPFormat8 = 0x08, /**< VP8 Video Format */
+ QOMX_VIDEO_VPFormat9 = 0x10, /**< VP9 Video Format */
+ QOMX_VIDEO_VPFormatKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_VPFormatVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_VPFormatMax = 0x7FFFFFFF
+} QOMX_VIDEO_VPFORMATTYPE;
+
+/**
+ * VP profile types, each profile indicates support for various
+ * encoding tools.
+ */
+typedef enum QOMX_VIDEO_VPPROFILETYPE {
+ QOMX_VIDEO_VPProfileSimple = 0x01, /**< Simple Profile, applies to VP6 only */
+ QOMX_VIDEO_VPProfileAdvanced = 0x02, /**< Advanced Profile, applies to VP6 only */
+ QOMX_VIDEO_VPProfileVersion0 = 0x04, /**< Version 0, applies to VP7 and VP8 */
+ QOMX_VIDEO_VPProfileVersion1 = 0x08, /**< Version 1, applies to VP7 and VP8 */
+ QOMX_VIDEO_VPProfileVersion2 = 0x10, /**< Version 2, applies to VP8 only */
+ QOMX_VIDEO_VPProfileVersion3 = 0x20, /**< Version 3, applies to VP8 only */
+ QOMX_VIDEO_VPProfileKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_VPProfileVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_VPProfileMax = 0x7FFFFFFF
+} QOMX_VIDEO_VPPROFILETYPE;
+
+/**
+ * VP Video Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Format of VP stream / data
+ * eProfile : Profile or Version of VP stream / data
+ */
+typedef struct QOMX_VIDEO_PARAM_VPTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_VPFORMATTYPE eFormat;
+ QOMX_VIDEO_VPPROFILETYPE eProfile;
+} QOMX_VIDEO_PARAM_VPTYPE;
+
+/**
+ * Spark Versions
+ */
+typedef enum QOMX_VIDEO_SPARKFORMATTYPE {
+ QOMX_VIDEO_SparkFormatUnused = 0x01, /**< Format unused or unknown */
+ QOMX_VIDEO_SparkFormat0 = 0x02, /**< Video Format Version 0 */
+ QOMX_VIDEO_SparkFormat1 = 0x04, /**< Video Format Version 1 */
+ QOMX_VIDEO_SparkFormatKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_SparkFormatVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_SparkFormatMax = 0x7FFFFFFF
+} QOMX_VIDEO_SPARKFORMATTYPE;
+
+/**
+ * Spark Video Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Version of Spark stream / data
+ */
+typedef struct QOMX_VIDEO_PARAM_SPARKTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_SPARKFORMATTYPE eFormat;
+} QOMX_VIDEO_PARAM_SPARKTYPE;
+
+
+typedef struct QOMX_VIDEO_QUERY_DECODER_INSTANCES {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nNumOfInstances;
+} QOMX_VIDEO_QUERY_DECODER_INSTANCES;
+
+typedef struct QOMX_ENABLETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bEnable;
+} QOMX_ENABLETYPE;
+
+typedef enum QOMX_VIDEO_EVENTS {
+ OMX_EventIndexsettingChanged = OMX_EventVendorStartUnused
+} QOMX_VIDEO_EVENTS;
+
+typedef enum QOMX_VIDEO_PICTURE_ORDER {
+ QOMX_VIDEO_DISPLAY_ORDER = 0x1,
+ QOMX_VIDEO_DECODE_ORDER = 0x2
+} QOMX_VIDEO_PICTURE_ORDER;
+
+typedef struct QOMX_VIDEO_DECODER_PICTURE_ORDER {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_PICTURE_ORDER eOutputPictureOrder;
+} QOMX_VIDEO_DECODER_PICTURE_ORDER;
+
+typedef struct QOMX_INDEXEXTRADATATYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnabled;
+ OMX_INDEXTYPE nIndex;
+} QOMX_INDEXEXTRADATATYPE;
+
+typedef struct QOMX_INDEXTIMESTAMPREORDER {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+} QOMX_INDEXTIMESTAMPREORDER;
+
+typedef struct QOMX_INDEXDOWNSCALAR {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+} QOMX_INDEXDOWNSCALAR;
+
+typedef struct QOMX_VIDEO_CUSTOM_BUFFERSIZE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nBufferSize;
+} QOMX_VIDEO_CUSTOM_BUFFERSIZE;
+
+#define OMX_QCOM_INDEX_PARAM_VIDEO_SYNCFRAMEDECODINGMODE "OMX.QCOM.index.param.video.SyncFrameDecodingMode"
+#define OMX_QCOM_INDEX_PARAM_INDEXEXTRADATA "OMX.QCOM.index.param.IndexExtraData"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_SLICEDELIVERYMODE "OMX.QCOM.index.param.SliceDeliveryMode"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA "OMX.QCOM.index.param.video.FramePackingExtradata"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA "OMX.QCOM.index.param.video.QPExtradata"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA "OMX.QCOM.index.param.video.InputBitsInfoExtradata"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA "OMX.QCOM.index.param.video.ExtnUserExtraData"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO "OMX.QCOM.index.config.video.FramePackingInfo"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_MPEG2SEQDISP_EXTRADATA "OMX.QCOM.index.param.video.Mpeg2SeqDispExtraData"
+
+#define OMX_QCOM_INDEX_PARAM_VIDEO_HIERSTRUCTURE "OMX.QCOM.index.param.video.HierStructure"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_LTRCOUNT "OMX.QCOM.index.param.video.LTRCount"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_LTRPERIOD "OMX.QCOM.index.param.video.LTRPeriod"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_LTRUSE "OMX.QCOM.index.config.video.LTRUse"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_LTRMARK "OMX.QCOM.index.config.video.LTRMark"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_HIER_P_LAYERS "OMX.QCOM.index.config.video.hierplayers"
+#define OMX_QCOM_INDEX_CONFIG_RECTANGLE_TYPE "OMX.QCOM.index.config.video.rectangle"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_BASE_LAYER_ID "OMX.QCOM.index.param.video.baselayerid"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_QP "OMX.QCOM.index.config.video.qp"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_SAR "OMX.QCOM.index.param.video.sar"
+#define OMX_QTI_INDEX_PARAM_VIDEO_LOW_LATENCY "OMX.QTI.index.param.video.LowLatency"
+
+#define OMX_QCOM_INDEX_PARAM_VIDEO_PASSINPUTBUFFERFD "OMX.QCOM.index.param.video.PassInputBufferFd"
+#define OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK "OMX.QTI.index.param.video.PreferAdaptivePlayback"
+#define OMX_QTI_INDEX_CONFIG_VIDEO_SETTIMEDATA "OMX.QTI.index.config.video.settimedata"
+#define OMX_QTI_INDEX_PARAM_VIDEO_FORCE_COMPRESSED_FOR_DPB "OMX.QTI.index.param.video.ForceCompressedForDPB"
+#define OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO "OMX.QTI.index.param.enableRoiInfo"
+#define OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO "OMX.QTI.index.config.RoiInfo"
+#define OMX_QTI_INDEX_CONFIG_VIDEO_BLURINFO "OMX.QTI.index.config.BlurInfo"
+#define OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA "OMX.QTI.index.param.client.extradata"
+#define OMX_QTI_INDEX_CONFIG_COLOR_ASPECTS "OMX.google.android.index.describeColorAspects"
+
+typedef enum {
+ QOMX_VIDEO_FRAME_PACKING_CHECKERBOARD = 0,
+ QOMX_VIDEO_FRAME_PACKING_COLUMN_INTERLEAVE = 1,
+ QOMX_VIDEO_FRAME_PACKING_ROW_INTERLEAVE = 2,
+ QOMX_VIDEO_FRAME_PACKING_SIDE_BY_SIDE = 3,
+ QOMX_VIDEO_FRAME_PACKING_TOP_BOTTOM = 4,
+ QOMX_VIDEO_FRAME_PACKING_TEMPORAL = 5,
+} QOMX_VIDEO_FRAME_PACKING_ARRANGEMENT;
+
+typedef enum {
+ QOMX_VIDEO_CONTENT_UNSPECIFIED = 0,
+ QOMX_VIDEO_CONTENT_LR_VIEW = 1,
+ QOMX_VIDEO_CONTENT_RL_VIEW = 2,
+} QOMX_VIDEO_CONTENT_INTERPRETATION;
+
+/**
+ * Specifies the extended picture types. These values should be
+ * OR'd along with the types defined in OMX_VIDEO_PICTURETYPE to
+ * signal all pictures types which are allowed.
+ *
+ * ENUMS:
+ * H.264 Specific Picture Types: IDR
+ */
+typedef enum QOMX_VIDEO_PICTURETYPE {
+ QOMX_VIDEO_PictureTypeIDR = OMX_VIDEO_PictureTypeVendorStartUnused + 0x1000
+} QOMX_VIDEO_PICTURETYPE;
+
+#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION "OMX.QCOM.index.config.activeregiondetection"
+#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS "OMX.QCOM.index.config.activeregiondetectionstatus"
+#define OMX_QCOM_INDEX_CONFIG_SCALING_MODE "OMX.QCOM.index.config.scalingmode"
+#define OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION "OMX.QCOM.index.config.noisereduction"
+#define OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT "OMX.QCOM.index.config.imageenhancement"
+#define OMX_QCOM_INDEX_PARAM_HELDBUFFERCOUNT "OMX.QCOM.index.param.HeldBufferCount" /**< reference: QOMX_HELDBUFFERCOUNTTYPE */
+
+
+typedef struct QOMX_RECTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_S32 nLeft;
+ OMX_S32 nTop;
+ OMX_U32 nWidth;
+ OMX_U32 nHeight;
+} QOMX_RECTTYPE;
+
+typedef struct QOMX_ACTIVEREGIONDETECTIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ QOMX_RECTTYPE sROI;
+ OMX_U32 nNumExclusionRegions;
+ QOMX_RECTTYPE sExclusionRegions[1];
+} QOMX_ACTIVEREGIONDETECTIONTYPE;
+
+typedef struct QOMX_ACTIVEREGIONDETECTION_STATUSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bDetected;
+ QOMX_RECTTYPE sDetectedRegion;
+} QOMX_ACTIVEREGIONDETECTION_STATUSTYPE;
+
+typedef enum QOMX_SCALE_MODETYPE {
+ QOMX_SCALE_MODE_Normal,
+ QOMX_SCALE_MODE_Anamorphic,
+ QOMX_SCALE_MODE_Max = 0x7FFFFFFF
+} QOMX_SCALE_MODETYPE;
+
+typedef struct QOMX_SCALINGMODETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ QOMX_SCALE_MODETYPE eScaleMode;
+} QOMX_SCALINGMODETYPE;
+
+typedef struct QOMX_NOISEREDUCTIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ OMX_BOOL bAutoMode;
+ OMX_S32 nNoiseReduction;
+} QOMX_NOISEREDUCTIONTYPE;
+
+typedef struct QOMX_IMAGEENHANCEMENTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ OMX_BOOL bAutoMode;
+ OMX_S32 nImageEnhancement;
+} QOMX_IMAGEENHANCEMENTTYPE;
+
+/*
+ * these are part of OMX1.2 but JB MR2 branch doesn't have them defined
+ * OMX_IndexParamInterlaceFormat
+ * OMX_INTERLACEFORMATTYPE
+ */
+#ifndef OMX_IndexParamInterlaceFormat
+#define OMX_IndexParamInterlaceFormat (0x7FF00000)
+typedef struct OMX_INTERLACEFORMATTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nFormat;
+ OMX_TICKS nTimeStamp;
+} OMX_INTERLACEFORMATTYPE;
+#endif
+
+/**
+ * This structure is used to indicate the maximum number of buffers
+ * that a port will hold during data flow.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nHeldBufferCount : Read-only, maximum number of buffers that will be held
+ */
+typedef struct QOMX_HELDBUFFERCOUNTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nHeldBufferCount;
+} QOMX_HELDBUFFERCOUNTTYPE;
+
+typedef enum QOMX_VIDEO_HIERARCHICALCODINGTYPE {
+ QOMX_HIERARCHICALCODING_P = 0x01,
+ QOMX_HIERARCHICALCODING_B = 0x02,
+} QOMX_VIDEO_HIERARCHICALCODINGTYPE;
+
+typedef struct QOMX_VIDEO_HIERARCHICALLAYERS {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nNumLayers;
+ QOMX_VIDEO_HIERARCHICALCODINGTYPE eHierarchicalCodingType;
+} QOMX_VIDEO_HIERARCHICALLAYERS;
+
+typedef struct QOMX_VIDEO_H264ENTROPYCODINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL bCabac;
+ OMX_U32 nCabacInitIdc;
+} QOMX_VIDEO_H264ENTROPYCODINGTYPE;
+
+
+/* VIDEO POSTPROCESSING CTRLS AND ENUMS */
+/* MUST KEEP SAME AS IN vpp.h */
+#define QOMX_VPP_HQV_CUSTOMPAYLOAD_SZ 256
+#define VPP_HQV_CONTROL_GLOBAL_START (VPP_HQV_CONTROL_CUST + 1)
+
+typedef enum QOMX_VPP_HQV_MODE {
+ VPP_HQV_MODE_OFF,
+ VPP_HQV_MODE_AUTO,
+ VPP_HQV_MODE_MANUAL,
+ VPP_HQV_MODE_MAX
+} QOMX_VPP_HQV_MODE;
+
+typedef enum QOMX_VPP_HQVCONTROLTYPE {
+ VPP_HQV_CONTROL_CADE = 0x1,
+ VPP_HQV_CONTROL_DI = 0x02,
+ VPP_HQV_CONTROL_CNR = 0x04,
+ VPP_HQV_CONTROL_AIE = 0x05,
+ VPP_HQV_CONTROL_FRC = 0x06,
+ VPP_HQV_CONTROL_CUST = 0x07,
+ VPP_HQV_CONTROL_GLOBAL_DEMO = VPP_HQV_CONTROL_GLOBAL_START,
+ VPP_HQV_CONTROL_MAX,
+} QOMX_VPP_HQVCONTROLTYPE;
+
+typedef enum QOMX_VPP_HQV_DI_MODE {
+ VPP_HQV_DI_MODE_OFF,
+ VPP_HQV_DI_MODE_VIDEO_1F,
+ VPP_HQV_DI_MODE_VIDEO_3F,
+ VPP_HQV_DI_MODE_AUTO,
+ VPP_HQV_DI_MODE_MAX,
+} QOMX_VPP_HQV_DI_MODE;
+
+typedef enum QOMX_VPP_HQV_HUE_MODE {
+ VPP_HQV_HUE_MODE_OFF,
+ VPP_HQV_HUE_MODE_ON,
+ VPP_HQV_HUE_MODE_MAX,
+} QOMX_VPP_HQV_HUE_MODE;
+
+typedef enum QOMX_VPP_SPLIT_DIRECTION {
+ VPP_HQV_SPLIT_LEFT_TO_RIGHT,
+ VPP_HQV_SPLIT_RIGHT_TO_LEFT,
+ VPP_HQV_SPLIT_TOP_TO_BOTTOM,
+ VPP_HQV_SPLIT_BOTTOM_TO_TOP,
+ VPP_HQV_SPLIT_MAX,
+} QOMX_VPP_SPLIT_DIRECTION;
+
+typedef enum QOMX_VPP_HQV_FRC_MODE {
+ VPP_HQV_FRC_MODE_OFF,
+ VPP_HQV_FRC_MODE_LOW,
+ VPP_HQV_FRC_MODE_MED,
+ VPP_HQV_FRC_MODE_HIGH,
+ VPP_HQV_FRC_MODE_MAX,
+} QOMX_VPP_HQV_FRC_MODE;
+
+
+typedef struct QOMX_VPP_HQVCTRL_CADE {
+ QOMX_VPP_HQV_MODE mode;
+ OMX_U32 level;
+ OMX_S32 contrast;
+ OMX_S32 saturation;
+} QOMX_VPP_HQVCTRL_CADE;
+
+typedef struct QOMX_VPP_HQVCTRL_DI {
+ QOMX_VPP_HQV_DI_MODE mode;
+} QOMX_VPP_HQVCTRL_DI;
+
+typedef struct QOMX_VPP_HQVCTRL_CNR {
+ QOMX_VPP_HQV_MODE mode;
+ OMX_U32 level;
+} QOMX_VPP_HQVCTRL_CNR;
+
+typedef struct QOMX_VPP_HQVCTRL_AIE {
+ QOMX_VPP_HQV_MODE mode;
+ QOMX_VPP_HQV_HUE_MODE hue_mode;
+ OMX_U32 cade_level;
+ OMX_U32 ltm_level;
+} QOMX_VPP_HQVCTRL_AIE;
+
+typedef struct QOMX_VPP_HQVCTRL_CUSTOM {
+ OMX_U32 id;
+ OMX_U32 len;
+ OMX_U8 data[QOMX_VPP_HQV_CUSTOMPAYLOAD_SZ];
+} QOMX_VPP_HQVCTRL_CUSTOM;
+
+typedef struct QOMX_VPP_HQVCTRL_GLOBAL_DEMO {
+ OMX_U32 process_percent;
+ QOMX_VPP_SPLIT_DIRECTION process_direction;
+} QOMX_VPP_HQVCTRL_GLOBAL_DEMO;
+
+typedef struct QOMX_VPP_HQVCTRL_FRC {
+ QOMX_VPP_HQV_FRC_MODE mode;
+} QOMX_VPP_HQVCTRL_FRC;
+
+/* VIDEO POSTPROCESSING OMX CTRLS */
+typedef struct QOMX_VPP_HQVCONTROL {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ QOMX_VPP_HQV_MODE mode;
+ QOMX_VPP_HQVCONTROLTYPE ctrl_type;
+ union {
+ QOMX_VPP_HQVCTRL_CADE cade;
+ QOMX_VPP_HQVCTRL_DI di;
+ QOMX_VPP_HQVCTRL_CNR cnr;
+ QOMX_VPP_HQVCTRL_AIE aie;
+ QOMX_VPP_HQVCTRL_CUSTOM custom;
+ QOMX_VPP_HQVCTRL_GLOBAL_DEMO global_demo;
+ QOMX_VPP_HQVCTRL_FRC frc;
+ };
+} QOMX_VPP_HQVCONTROL;
+
+/* STRUCTURE TO TURN VPP ON */
+typedef struct QOMX_VPP_ENABLE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_BOOL enable_vpp;
+} QOMX_VPP_ENABLE;
+
+typedef enum OMX_QOMX_VIDEO_MBISTATISTICSTYPE {
+ QOMX_MBI_STATISTICS_MODE_DEFAULT = 0,
+ QOMX_MBI_STATISTICS_MODE_1 = 0x01,
+ QOMX_MBI_STATISTICS_MODE_2 = 0x02,
+} OMX_QOMX_VIDEO_MBISTATISTICSTYPE;
+
+typedef struct OMX_QOMX_VIDEO_MBI_STATISTICS {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_QOMX_VIDEO_MBISTATISTICSTYPE eMBIStatisticsType;
+} OMX_QOMX_VIDEO_MBI_STATISTICS;
+
+typedef struct QOMX_VIDEO_BATCHSIZETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nBatchSize;
+} QOMX_VIDEO_BATCHSIZETYPE;
+
+typedef struct QOMX_VIDEO_CLIENT_EXTRADATA {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nFd;
+ OMX_U32 nExtradataAllocSize;
+ OMX_U32 nExtradataSize;
+} QOMX_VIDEO_CLIENT_EXTRADATATYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __OMX_QCOM_EXTENSIONS_H__ */
diff --git a/msmcobalt/mm-core/inc/OMX_Skype_VideoExtensions.h b/msmcobalt/mm-core/inc/OMX_Skype_VideoExtensions.h
new file mode 100644
index 0000000..5cc8329
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Skype_VideoExtensions.h
@@ -0,0 +1,155 @@
+/*@@@+++@@@@******************************************************************
+
+ Microsoft Skype Engineering
+ Copyright (C) 2014 Microsoft Corporation.
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+
+*@@@---@@@@******************************************************************/
+
+
+#ifndef __OMX_SKYPE_VIDEOEXTENSIONS_H__
+#define __OMX_SKYPE_VIDEOEXTENSIONS_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <OMX_Core.h>
+
+#pragma pack(push, 1)
+
+
+typedef enum OMX_SKYPE_VIDEO_SliceControlMode
+{
+ OMX_SKYPE_VIDEO_SliceControlModeNone = 0,
+ OMX_SKYPE_VIDEO_SliceControlModeMB = 1,
+ OMX_SKYPE_VIDEO_SliceControlModeByte = 2,
+ OMX_SKYPE_VIDEO_SliceControlModMBRow = 3,
+} OMX_SKYPE_VIDEO_SliceControlMode;
+
+
+typedef enum OMX_SKYPE_VIDEO_HierarType
+{
+ OMX_SKYPE_VIDEO_HierarType_P = 0x01,
+ OMX_SKYPE_VIDEO_HierarType_B = 0x02,
+} OMX_SKYPE_VIDEO_HIERAR_HierarType;
+
+typedef enum OMX_VIDEO_EXTENSION_AVCPROFILETYPE
+{
+ OMX_VIDEO_EXT_AVCProfileConstrainedBaseline = 0x01,
+ OMX_VIDEO_EXT_AVCProfileConstrainedHigh = 0x02,
+} OMX_VIDEO_EXTENSION_AVCPROFILETYPE;
+
+typedef struct OMX_SKYPE_VIDEO_ENCODERPARAMS {
+ OMX_BOOL bLowLatency;
+ OMX_BOOL bUseExtendedProfile;
+ OMX_BOOL bSequenceHeaderWithIDR;
+ OMX_VIDEO_EXTENSION_AVCPROFILETYPE eProfile;
+ OMX_U32 nLTRFrames;
+ OMX_SKYPE_VIDEO_HierarType eHierarType;
+ OMX_U32 nMaxTemporalLayerCount;
+ OMX_SKYPE_VIDEO_SliceControlMode eSliceControlMode;
+ OMX_U32 nSarIndex;
+ OMX_U32 nSarWidth;
+ OMX_U32 nSarHeight;
+} OMX_SKYPE_VIDEO_ENCODERPARAMS;
+
+typedef struct OMX_SKYPE_VIDEO_PARAM_ENCODERSETTING {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_SKYPE_VIDEO_ENCODERPARAMS stEncParam;
+} OMX_SKYPE_VIDEO_PARAM_ENCODESETTING;
+
+typedef struct OMX_SKYPE_VIDEO_ENCODERCAP {
+ OMX_BOOL bLowLatency;
+ OMX_U32 nMaxFrameWidth;
+ OMX_U32 nMaxFrameHeight;
+ OMX_U32 nMaxInstances;
+ OMX_U32 nMaxTemporaLayerCount;
+ OMX_U32 nMaxRefFrames;
+ OMX_U32 nMaxLTRFrames;
+ OMX_VIDEO_AVCLEVELTYPE nMaxLevel;
+ OMX_U32 nSliceControlModesBM;
+ OMX_U32 nMaxMacroblockProcessingRate;
+ OMX_U32 xMinScaleFactor;
+} OMX_SKYPE_VIDEO_ENCODERCAP;
+
+typedef struct OMX_SKYPE_VIDEO_PARAM_ENCODERCAP {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_SKYPE_VIDEO_ENCODERCAP stEncCap;
+} OMX_SKYPE_VIDEO_PARAM_ENCODERCAP;
+
+typedef struct OMX_SKYPE_VIDEO_DECODERCAP {
+ OMX_BOOL bLowLatency;
+ OMX_U32 nMaxFrameWidth;
+ OMX_U32 nMaxFrameHeight;
+ OMX_U32 nMaxInstances;
+ OMX_VIDEO_AVCLEVELTYPE nMaxLevel;
+ OMX_U32 nMaxMacroblockProcessingRate;
+} OMX_SKYPE_VIDEO_DECODERCAP;
+
+typedef struct OMX_SKYPE_VIDEO_PARAM_DECODERCAP {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_SKYPE_VIDEO_DECODERCAP stDecoderCap;
+} OMX_SKYPE_VIDEO_PARAM_DECODERCAP;
+
+typedef struct OMX_SKYPE_VIDEO_CONFIG_QP {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nQP;
+} OMX_SKYPE_VIDEO_CONFIG_QP;
+
+typedef struct OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nPID;
+} OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID;
+
+typedef struct OMX_SKYPE_VIDEO_PARAM_DRIVERVER {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U64 nDriverVersion;
+} OMX_SKYPE_VIDEO_PARAM_DRIVERVER;
+
+typedef enum OMX_SKYPE_VIDEO_DownScaleFactor
+{
+ OMX_SKYPE_VIDEO_DownScaleFactor_1_1 = 0,
+ OMX_SKYPE_VIDEO_DownScaleFactor_Equal_AR = 1,
+ OMX_SKYPE_VIDEO_DownScaleFactor_Any = 2,
+} OMX_SKYPE_VIDEO_DownScaleFactor;
+
+#pragma pack(pop)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/msmcobalt/mm-core/inc/OMX_Types.h b/msmcobalt/mm-core/inc/OMX_Types.h
new file mode 100644
index 0000000..3b9fab4
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Types.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_Types.h - OpenMax IL version 1.1.2
+ * The OMX_Types header file contains the primitive type definitions used by
+ * the core, the application and the component. This file may need to be
+ * modified to be used on systems that do not have "char" set to 8 bits,
+ * "short" set to 16 bits and "long" set to 32 bits.
+ */
+
+#ifndef OMX_Types_h
+#define OMX_Types_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/** The OMX_API and OMX_APIENTRY are platform specific definitions used
+ * to declare OMX function prototypes. They are modified to meet the
+ * requirements for a particular platform */
+#ifdef __SYMBIAN32__
+# ifdef __OMX_EXPORTS
+# define OMX_API __declspec(dllexport)
+# else
+# ifdef _WIN32
+# define OMX_API __declspec(dllexport)
+# else
+# define OMX_API __declspec(dllimport)
+# endif
+# endif
+#else
+# ifdef _WIN32
+# ifdef __OMX_EXPORTS
+# define OMX_API __declspec(dllexport)
+# else
+# define OMX_API __declspec(dllimport)
+# endif
+# else
+# ifdef __OMX_EXPORTS
+# define OMX_API
+# else
+# define OMX_API extern
+# endif
+# endif
+#endif
+
+#ifndef OMX_APIENTRY
+#define OMX_APIENTRY
+#endif
+
+/** OMX_IN is used to identify inputs to an OMX function. This designation
+ will also be used in the case of a pointer that points to a parameter
+ that is used as an output. */
+#ifndef OMX_IN
+#define OMX_IN
+#endif
+
+/** OMX_OUT is used to identify outputs from an OMX function. This
+ designation will also be used in the case of a pointer that points
+ to a parameter that is used as an input. */
+#ifndef OMX_OUT
+#define OMX_OUT
+#endif
+
+
+/** OMX_INOUT is used to identify parameters that may be either inputs or
+ outputs from an OMX function at the same time. This designation will
+ also be used in the case of a pointer that points to a parameter that
+ is used both as an input and an output. */
+#ifndef OMX_INOUT
+#define OMX_INOUT
+#endif
+
+/** OMX_ALL is used to as a wildcard to select all entities of the same type
+ * when specifying the index, or referring to a object by an index. (i.e.
+ * use OMX_ALL to indicate all N channels). When used as a port index
+ * for a config or parameter this OMX_ALL denotes that the config or
+ * parameter applies to the entire component not just one port. */
+#define OMX_ALL 0xFFFFFFFF
+
+/** In the following we define groups that help building doxygen documentation */
+
+/** @defgroup core OpenMAX IL core
+ * Functions and structure related to the OMX IL core
+ */
+
+ /** @defgroup comp OpenMAX IL component
+ * Functions and structure related to the OMX IL component
+ */
+
+/** @defgroup rpm Resource and Policy Management
+ * Structures for resource and policy management of components
+ */
+
+/** @defgroup buf Buffer Management
+ * Buffer handling functions and structures
+ */
+
+/** @defgroup tun Tunneling
+ * @ingroup core comp
+ * Structures and functions to manage tunnels among component ports
+ */
+
+/** @defgroup cp Content Pipes
+ * @ingroup core
+ */
+
+ /** @defgroup metadata Metadata handling
+ *
+ */
+
+/** OMX_U8 is an 8 bit unsigned quantity that is byte aligned */
+typedef unsigned char OMX_U8;
+
+/** OMX_S8 is an 8 bit signed quantity that is byte aligned */
+typedef signed char OMX_S8;
+
+/** OMX_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */
+typedef unsigned short OMX_U16;
+
+/** OMX_S16 is a 16 bit signed quantity that is 16 bit word aligned */
+typedef signed short OMX_S16;
+
+/** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
+typedef unsigned int OMX_U32;
+
+/** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */
+typedef signed int OMX_S32;
+
+
+/* Users with compilers that cannot accept the "long long" designation should
+ define the OMX_SKIP64BIT macro. It should be noted that this may cause
+ some components to fail to compile if the component was written to require
+ 64 bit integral types. However, these components would NOT compile anyway
+ since the compiler does not support the way the component was written.
+*/
+#ifndef OMX_SKIP64BIT
+#ifdef __SYMBIAN32__
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned long long OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed long long OMX_S64;
+
+#elif defined(WIN32)
+
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned __int64 OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed __int64 OMX_S64;
+
+#else /* WIN32 */
+
+/** OMX_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
+typedef unsigned long long OMX_U64;
+
+/** OMX_S64 is a 64 bit signed quantity that is 64 bit word aligned */
+typedef signed long long OMX_S64;
+
+#endif /* WIN32 */
+#endif
+
+
+/** The OMX_BOOL type is intended to be used to represent a true or a false
+ value when passing parameters to and from the OMX core and components. The
+ OMX_BOOL is a 32 bit quantity and is aligned on a 32 bit word boundary.
+ */
+typedef enum OMX_BOOL {
+ OMX_FALSE = 0,
+ OMX_TRUE = !OMX_FALSE,
+ OMX_BOOL_MAX = 0x7FFFFFFF
+} OMX_BOOL;
+
+#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+
+typedef OMX_U32 OMX_PTR;
+typedef OMX_PTR OMX_STRING;
+typedef OMX_PTR OMX_BYTE;
+
+#else
+
+/** The OMX_PTR type is intended to be used to pass pointers between the OMX
+ applications and the OMX Core and components. This is a 32 bit pointer and
+ is aligned on a 32 bit boundary.
+ */
+typedef void* OMX_PTR;
+
+/** The OMX_STRING type is intended to be used to pass "C" type strings between
+ the application and the core and component. The OMX_STRING type is a 32
+ bit pointer to a zero terminated string. The pointer is word aligned and
+ the string is byte aligned.
+ */
+typedef char* OMX_STRING;
+
+/** The OMX_BYTE type is intended to be used to pass arrays of bytes such as
+ buffers between the application and the component and core. The OMX_BYTE
+ type is a 32 bit pointer to a zero terminated string. The pointer is word
+ aligned and the string is byte aligned.
+ */
+typedef unsigned char* OMX_BYTE;
+
+/** OMX_UUIDTYPE is a very long unique identifier to uniquely identify
+ at runtime. This identifier should be generated by a component in a way
+ that guarantees that every instance of the identifier running on the system
+ is unique. */
+
+
+#endif
+
+typedef unsigned char OMX_UUIDTYPE[128];
+
+/** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or
+ an output port. This enumeration is common across all component types.
+ */
+typedef enum OMX_DIRTYPE
+{
+ OMX_DirInput, /**< Port is an input port */
+ OMX_DirOutput, /**< Port is an output port */
+ OMX_DirMax = 0x7FFFFFFF
+} OMX_DIRTYPE;
+
+/** The OMX_ENDIANTYPE enumeration is used to indicate the bit ordering
+ for numerical data (i.e. big endian, or little endian).
+ */
+typedef enum OMX_ENDIANTYPE
+{
+ OMX_EndianBig, /**< big endian */
+ OMX_EndianLittle, /**< little endian */
+ OMX_EndianMax = 0x7FFFFFFF
+} OMX_ENDIANTYPE;
+
+
+/** The OMX_NUMERICALDATATYPE enumeration is used to indicate if data
+ is signed or unsigned
+ */
+typedef enum OMX_NUMERICALDATATYPE
+{
+ OMX_NumericalDataSigned, /**< signed data */
+ OMX_NumericalDataUnsigned, /**< unsigned data */
+ OMX_NumercialDataMax = 0x7FFFFFFF
+} OMX_NUMERICALDATATYPE;
+
+
+/** Unsigned bounded value type */
+typedef struct OMX_BU32 {
+ OMX_U32 nValue; /**< actual value */
+ OMX_U32 nMin; /**< minimum for value (i.e. nValue >= nMin) */
+ OMX_U32 nMax; /**< maximum for value (i.e. nValue <= nMax) */
+} OMX_BU32;
+
+
+/** Signed bounded value type */
+typedef struct OMX_BS32 {
+ OMX_S32 nValue; /**< actual value */
+ OMX_S32 nMin; /**< minimum for value (i.e. nValue >= nMin) */
+ OMX_S32 nMax; /**< maximum for value (i.e. nValue <= nMax) */
+} OMX_BS32;
+
+
+/** Structure representing some time or duration in microseconds. This structure
+ * must be interpreted as a signed 64 bit value. The quantity is signed to accommodate
+ * negative deltas and preroll scenarios. The quantity is represented in microseconds
+ * to accomodate high resolution timestamps (e.g. DVD presentation timestamps based
+ * on a 90kHz clock) and to allow more accurate and synchronized delivery (e.g.
+ * individual audio samples delivered at 192 kHz). The quantity is 64 bit to
+ * accommodate a large dynamic range (signed 32 bit values would allow only for plus
+ * or minus 35 minutes).
+ *
+ * Implementations with limited precision may convert the signed 64 bit value to
+ * a signed 32 bit value internally but risk loss of precision.
+ */
+#ifndef OMX_SKIP64BIT
+typedef OMX_S64 OMX_TICKS;
+#else
+typedef struct OMX_TICKS
+{
+ OMX_U32 nLowPart; /** low bits of the signed 64 bit tick value */
+ OMX_U32 nHighPart; /** high bits of the signed 64 bit tick value */
+} OMX_TICKS;
+#endif
+#define OMX_TICKS_PER_SECOND 1000000
+
+/** Define the public interface for the OMX Handle. The core will not use
+ this value internally, but the application should only use this value.
+ */
+typedef void* OMX_HANDLETYPE;
+
+typedef struct OMX_MARKTYPE
+{
+ OMX_HANDLETYPE hMarkTargetComponent; /**< The component that will
+ generate a mark event upon
+ processing the mark. */
+ OMX_PTR pMarkData; /**< Application specific data associated with
+ the mark sent on a mark event to disambiguate
+ this mark from others. */
+} OMX_MARKTYPE;
+
+
+/** OMX_NATIVE_DEVICETYPE is used to map a OMX video port to the
+ * platform & operating specific object used to reference the display
+ * or can be used by a audio port for native audio rendering */
+typedef void* OMX_NATIVE_DEVICETYPE;
+
+/** OMX_NATIVE_WINDOWTYPE is used to map a OMX video port to the
+ * platform & operating specific object used to reference the window */
+typedef void* OMX_NATIVE_WINDOWTYPE;
+
+/** The OMX_VERSIONTYPE union is used to specify the version for
+ a structure or component. For a component, the version is entirely
+ specified by the component vendor. Components doing the same function
+ from different vendors may or may not have the same version. For
+ structures, the version shall be set by the entity that allocates the
+ structure. For structures specified in the OMX 1.1 specification, the
+ value of the version shall be set to 1.1.0.0 in all cases. Access to the
+ OMX_VERSIONTYPE can be by a single 32 bit access (e.g. by nVersion) or
+ by accessing one of the structure elements to, for example, check only
+ the Major revision.
+ */
+typedef union OMX_VERSIONTYPE
+{
+ struct
+ {
+ OMX_U8 nVersionMajor; /**< Major version accessor element */
+ OMX_U8 nVersionMinor; /**< Minor version accessor element */
+ OMX_U8 nRevision; /**< Revision version accessor element */
+ OMX_U8 nStep; /**< Step version accessor element */
+ } s;
+ OMX_U32 nVersion; /**< 32 bit value to make accessing the
+ version easily done in a single word
+ size copy/compare operation */
+} OMX_VERSIONTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/OMX_Video.h b/msmcobalt/mm-core/inc/OMX_Video.h
new file mode 100644
index 0000000..64dbe87
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_Video.h
@@ -0,0 +1,1082 @@
+/**
+ * Copyright (c) 2008 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/**
+ * @file OMX_Video.h - OpenMax IL version 1.1.2
+ * The structures is needed by Video components to exchange parameters
+ * and configuration data with OMX components.
+ */
+#ifndef OMX_Video_h
+#define OMX_Video_h
+
+/** @defgroup video OpenMAX IL Video Domain
+ * @ingroup iv
+ * Structures for OpenMAX IL Video domain
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/**
+ * Each OMX header must include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+
+#include <OMX_IVCommon.h>
+
+
+/**
+ * Enumeration used to define the possible video compression codings.
+ * NOTE: This essentially refers to file extensions. If the coding is
+ * being used to specify the ENCODE type, then additional work
+ * must be done to configure the exact flavor of the compression
+ * to be used. For decode cases where the user application can
+ * not differentiate between MPEG-4 and H.264 bit streams, it is
+ * up to the codec to handle this.
+ */
+typedef enum OMX_VIDEO_CODINGTYPE {
+ OMX_VIDEO_CodingUnused, /**< Value when coding is N/A */
+ OMX_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */
+ OMX_VIDEO_CodingMPEG2, /**< AKA: H.262 */
+ OMX_VIDEO_CodingH263, /**< H.263 */
+ OMX_VIDEO_CodingMPEG4, /**< MPEG-4 */
+ OMX_VIDEO_CodingWMV, /**< all versions of Windows Media Video */
+ OMX_VIDEO_CodingRV, /**< all versions of Real Video */
+ OMX_VIDEO_CodingAVC, /**< H.264/AVC */
+ OMX_VIDEO_CodingMJPEG, /**< Motion JPEG */
+ OMX_VIDEO_CodingVP8, /**< Google VP8, formerly known as On2 VP8 */
+ OMX_VIDEO_CodingVP9, /**< Google VP9 */
+ OMX_VIDEO_CodingHEVC, /**< HEVC */
+ OMX_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_CodingMax = 0x7FFFFFFF
+} OMX_VIDEO_CODINGTYPE;
+
+
+/**
+ * Data structure used to define a video path. The number of Video paths for
+ * input and output will vary by type of the Video component.
+ *
+ * Input (aka Source) : zero Inputs, one Output,
+ * Splitter : one Input, 2 or more Outputs,
+ * Processing Element : one Input, one output,
+ * Mixer : 2 or more inputs, one output,
+ * Output (aka Sink) : one Input, zero outputs.
+ *
+ * The PortDefinition structure is used to define all of the parameters
+ * necessary for the compliant component to setup an input or an output video
+ * path. If additional vendor specific data is required, it should be
+ * transmitted to the component using the CustomCommand function. Compliant
+ * components will prepopulate this structure with optimal values during the
+ * GetDefaultInitParams command.
+ *
+ * STRUCT MEMBERS:
+ * cMIMEType : MIME type of data for the port
+ * pNativeRender : Platform specific reference for a display if a
+ * sync, otherwise this field is 0
+ * nFrameWidth : Width of frame to be used on channel if
+ * uncompressed format is used. Use 0 for unknown,
+ * don't care or variable
+ * nFrameHeight : Height of frame to be used on channel if
+ * uncompressed format is used. Use 0 for unknown,
+ * don't care or variable
+ * nStride : Number of bytes per span of an image
+ * (i.e. indicates the number of bytes to get
+ * from span N to span N+1, where negative stride
+ * indicates the image is bottom up
+ * nSliceHeight : Height used when encoding in slices
+ * nBitrate : Bit rate of frame to be used on channel if
+ * compressed format is used. Use 0 for unknown,
+ * don't care or variable
+ * xFramerate : Frame rate to be used on channel if uncompressed
+ * format is used. Use 0 for unknown, don't care or
+ * variable. Units are Q16 frames per second.
+ * bFlagErrorConcealment : Turns on error concealment if it is supported by
+ * the OMX component
+ * eCompressionFormat : Compression format used in this instance of the
+ * component. When OMX_VIDEO_CodingUnused is
+ * specified, eColorFormat is used
+ * eColorFormat : Decompressed format used by this component
+ * pNativeWindow : Platform specific reference for a window object if a
+ * display sink , otherwise this field is 0x0.
+ */
+typedef struct OMX_VIDEO_PORTDEFINITIONTYPE {
+ OMX_STRING cMIMEType;
+ OMX_NATIVE_DEVICETYPE pNativeRender;
+ OMX_U32 nFrameWidth;
+ OMX_U32 nFrameHeight;
+ OMX_S32 nStride;
+ OMX_U32 nSliceHeight;
+ OMX_U32 nBitrate;
+ OMX_U32 xFramerate;
+ OMX_BOOL bFlagErrorConcealment;
+ OMX_VIDEO_CODINGTYPE eCompressionFormat;
+ OMX_COLOR_FORMATTYPE eColorFormat;
+ OMX_NATIVE_WINDOWTYPE pNativeWindow;
+} OMX_VIDEO_PORTDEFINITIONTYPE;
+
+/**
+ * Port format parameter. This structure is used to enumerate the various
+ * data input/output format supported by the port.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Indicates which port to set
+ * nIndex : Indicates the enumeration index for the format from
+ * 0x0 to N-1
+ * eCompressionFormat : Compression format used in this instance of the
+ * component. When OMX_VIDEO_CodingUnused is specified,
+ * eColorFormat is used
+ * eColorFormat : Decompressed format used by this component
+ * xFrameRate : Indicates the video frame rate in Q16 format
+ */
+typedef struct OMX_VIDEO_PARAM_PORTFORMATTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nIndex;
+ OMX_VIDEO_CODINGTYPE eCompressionFormat;
+ OMX_COLOR_FORMATTYPE eColorFormat;
+ OMX_U32 xFramerate;
+} OMX_VIDEO_PARAM_PORTFORMATTYPE;
+
+
+/**
+ * This is a structure for configuring video compression quantization
+ * parameter values. Codecs may support different QP values for different
+ * frame types.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nQpI : QP value to use for index frames
+ * nQpP : QP value to use for P frames
+ * nQpB : QP values to use for bidirectional frames
+ */
+typedef struct OMX_VIDEO_PARAM_QUANTIZATIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nQpI;
+ OMX_U32 nQpP;
+ OMX_U32 nQpB;
+} OMX_VIDEO_PARAM_QUANTIZATIONTYPE;
+
+
+/**
+ * Structure for configuration of video fast update parameters.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * bEnableVFU : Enable/Disable video fast update
+ * nFirstGOB : Specifies the number of the first macroblock row
+ * nFirstMB : specifies the first MB relative to the specified first GOB
+ * nNumMBs : Specifies the number of MBs to be refreshed from nFirstGOB
+ * and nFirstMB
+ */
+typedef struct OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnableVFU;
+ OMX_U32 nFirstGOB;
+ OMX_U32 nFirstMB;
+ OMX_U32 nNumMBs;
+} OMX_VIDEO_PARAM_VIDEOFASTUPDATETYPE;
+
+
+/**
+ * Enumeration of possible bitrate control types
+ */
+typedef enum OMX_VIDEO_CONTROLRATETYPE {
+ OMX_Video_ControlRateDisable,
+ OMX_Video_ControlRateVariable,
+ OMX_Video_ControlRateConstant,
+ OMX_Video_ControlRateVariableSkipFrames,
+ OMX_Video_ControlRateConstantSkipFrames,
+ OMX_Video_ControlRateKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_Video_ControlRateVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_Video_ControlRateMax = 0x7FFFFFFF
+} OMX_VIDEO_CONTROLRATETYPE;
+
+
+/**
+ * Structure for configuring bitrate mode of a codec.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the struct in bytes
+ * nVersion : OMX spec version info
+ * nPortIndex : Port that this struct applies to
+ * eControlRate : Control rate type enum
+ * nTargetBitrate : Target bitrate to encode with
+ */
+typedef struct OMX_VIDEO_PARAM_BITRATETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_CONTROLRATETYPE eControlRate;
+ OMX_U32 nTargetBitrate;
+} OMX_VIDEO_PARAM_BITRATETYPE;
+
+
+/**
+ * Enumeration of possible motion vector (MV) types
+ */
+typedef enum OMX_VIDEO_MOTIONVECTORTYPE {
+ OMX_Video_MotionVectorPixel,
+ OMX_Video_MotionVectorHalfPel,
+ OMX_Video_MotionVectorQuarterPel,
+ OMX_Video_MotionVectorEighthPel,
+ OMX_Video_MotionVectorKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_Video_MotionVectorVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_Video_MotionVectorMax = 0x7FFFFFFF
+} OMX_VIDEO_MOTIONVECTORTYPE;
+
+
+/**
+ * Structure for configuring the number of motion vectors used as well
+ * as their accuracy.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the struct in bytes
+ * nVersion : OMX spec version info
+ * nPortIndex : port that this structure applies to
+ * eAccuracy : Enumerated MV accuracy
+ * bUnrestrictedMVs : Allow unrestricted MVs
+ * bFourMV : Allow use of 4 MVs
+ * sXSearchRange : Search range in horizontal direction for MVs
+ * sYSearchRange : Search range in vertical direction for MVs
+ */
+typedef struct OMX_VIDEO_PARAM_MOTIONVECTORTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_MOTIONVECTORTYPE eAccuracy;
+ OMX_BOOL bUnrestrictedMVs;
+ OMX_BOOL bFourMV;
+ OMX_S32 sXSearchRange;
+ OMX_S32 sYSearchRange;
+} OMX_VIDEO_PARAM_MOTIONVECTORTYPE;
+
+
+/**
+ * Enumeration of possible methods to use for Intra Refresh
+ */
+typedef enum OMX_VIDEO_INTRAREFRESHTYPE {
+ OMX_VIDEO_IntraRefreshCyclic,
+ OMX_VIDEO_IntraRefreshAdaptive,
+ OMX_VIDEO_IntraRefreshBoth,
+ OMX_VIDEO_IntraRefreshKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_IntraRefreshVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_IntraRefreshRandom,
+ OMX_VIDEO_IntraRefreshMax = 0x7FFFFFFF
+} OMX_VIDEO_INTRAREFRESHTYPE;
+
+
+/**
+ * Structure for configuring intra refresh mode
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eRefreshMode : Cyclic, Adaptive, or Both
+ * nAirMBs : Number of intra macroblocks to refresh in a frame when
+ * AIR is enabled
+ * nAirRef : Number of times a motion marked macroblock has to be
+ * intra coded
+ * nCirMBs : Number of consecutive macroblocks to be coded as "intra"
+ * when CIR is enabled
+ */
+typedef struct OMX_VIDEO_PARAM_INTRAREFRESHTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_INTRAREFRESHTYPE eRefreshMode;
+ OMX_U32 nAirMBs;
+ OMX_U32 nAirRef;
+ OMX_U32 nCirMBs;
+} OMX_VIDEO_PARAM_INTRAREFRESHTYPE;
+
+
+/**
+ * Structure for enabling various error correction methods for video
+ * compression.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * bEnableHEC : Enable/disable header extension codes (HEC)
+ * bEnableResync : Enable/disable resynchronization markers
+ * nResynchMarkerSpacing : Resynch markers interval (in bits) to be
+ * applied in the stream
+ * bEnableDataPartitioning : Enable/disable data partitioning
+ * bEnableRVLC : Enable/disable reversible variable length
+ * coding
+ */
+typedef struct OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnableHEC;
+ OMX_BOOL bEnableResync;
+ OMX_U32 nResynchMarkerSpacing;
+ OMX_BOOL bEnableDataPartitioning;
+ OMX_BOOL bEnableRVLC;
+} OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE;
+
+
+/**
+ * Configuration of variable block-size motion compensation (VBSMC)
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * b16x16 : Enable inter block search 16x16
+ * b16x8 : Enable inter block search 16x8
+ * b8x16 : Enable inter block search 8x16
+ * b8x8 : Enable inter block search 8x8
+ * b8x4 : Enable inter block search 8x4
+ * b4x8 : Enable inter block search 4x8
+ * b4x4 : Enable inter block search 4x4
+ */
+typedef struct OMX_VIDEO_PARAM_VBSMCTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL b16x16;
+ OMX_BOOL b16x8;
+ OMX_BOOL b8x16;
+ OMX_BOOL b8x8;
+ OMX_BOOL b8x4;
+ OMX_BOOL b4x8;
+ OMX_BOOL b4x4;
+} OMX_VIDEO_PARAM_VBSMCTYPE;
+
+
+/**
+ * H.263 profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ *
+ * ENUMS:
+ * Baseline : Baseline Profile: H.263 (V1), no optional modes
+ * H320 Coding : H.320 Coding Efficiency Backward Compatibility
+ * Profile: H.263+ (V2), includes annexes I, J, L.4
+ * and T
+ * BackwardCompatible : Backward Compatibility Profile: H.263 (V1),
+ * includes annex F
+ * ISWV2 : Interactive Streaming Wireless Profile: H.263+
+ * (V2), includes annexes I, J, K and T
+ * ISWV3 : Interactive Streaming Wireless Profile: H.263++
+ * (V3), includes profile 3 and annexes V and W.6.3.8
+ * HighCompression : Conversational High Compression Profile: H.263++
+ * (V3), includes profiles 1 & 2 and annexes D and U
+ * Internet : Conversational Internet Profile: H.263++ (V3),
+ * includes profile 5 and annex K
+ * Interlace : Conversational Interlace Profile: H.263++ (V3),
+ * includes profile 5 and annex W.6.3.11
+ * HighLatency : High Latency Profile: H.263++ (V3), includes
+ * profile 6 and annexes O.1 and P.5
+ */
+typedef enum OMX_VIDEO_H263PROFILETYPE {
+ OMX_VIDEO_H263ProfileBaseline = 0x01,
+ OMX_VIDEO_H263ProfileH320Coding = 0x02,
+ OMX_VIDEO_H263ProfileBackwardCompatible = 0x04,
+ OMX_VIDEO_H263ProfileISWV2 = 0x08,
+ OMX_VIDEO_H263ProfileISWV3 = 0x10,
+ OMX_VIDEO_H263ProfileHighCompression = 0x20,
+ OMX_VIDEO_H263ProfileInternet = 0x40,
+ OMX_VIDEO_H263ProfileInterlace = 0x80,
+ OMX_VIDEO_H263ProfileHighLatency = 0x100,
+ OMX_VIDEO_H263ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_H263ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_H263ProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_H263PROFILETYPE;
+
+
+/**
+ * H.263 level types, each level indicates support for various frame sizes,
+ * bit rates, decoder frame rates.
+ */
+typedef enum OMX_VIDEO_H263LEVELTYPE {
+ OMX_VIDEO_H263Level10 = 0x01,
+ OMX_VIDEO_H263Level20 = 0x02,
+ OMX_VIDEO_H263Level30 = 0x04,
+ OMX_VIDEO_H263Level40 = 0x08,
+ OMX_VIDEO_H263Level45 = 0x10,
+ OMX_VIDEO_H263Level50 = 0x20,
+ OMX_VIDEO_H263Level60 = 0x40,
+ OMX_VIDEO_H263Level70 = 0x80,
+ OMX_VIDEO_H263LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_H263LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_H263LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_H263LEVELTYPE;
+
+
+/**
+ * Specifies the picture type. These values should be OR'd to signal all
+ * pictures types which are allowed.
+ *
+ * ENUMS:
+ * Generic Picture Types: I, P and B
+ * H.263 Specific Picture Types: SI and SP
+ * H.264 Specific Picture Types: EI and EP
+ * MPEG-4 Specific Picture Types: S
+ */
+typedef enum OMX_VIDEO_PICTURETYPE {
+ OMX_VIDEO_PictureTypeI = 0x01,
+ OMX_VIDEO_PictureTypeP = 0x02,
+ OMX_VIDEO_PictureTypeB = 0x04,
+ OMX_VIDEO_PictureTypeSI = 0x08,
+ OMX_VIDEO_PictureTypeSP = 0x10,
+ OMX_VIDEO_PictureTypeEI = 0x11,
+ OMX_VIDEO_PictureTypeEP = 0x12,
+ OMX_VIDEO_PictureTypeS = 0x14,
+ OMX_VIDEO_PictureTypeKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_PictureTypeVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_PictureTypeMax = 0x7FFFFFFF
+} OMX_VIDEO_PICTURETYPE;
+
+
+/**
+ * H.263 Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nPFrames : Number of P frames between each I frame
+ * nBFrames : Number of B frames between each I frame
+ * eProfile : H.263 profile(s) to use
+ * eLevel : H.263 level(s) to use
+ * bPLUSPTYPEAllowed : Indicating that it is allowed to use PLUSPTYPE
+ * (specified in the 1998 version of H.263) to
+ * indicate custom picture sizes or clock
+ * frequencies
+ * nAllowedPictureTypes : Specifies the picture types allowed in the
+ * bitstream
+ * bForceRoundingTypeToZero : value of the RTYPE bit (bit 6 of MPPTYPE) is
+ * not constrained. It is recommended to change
+ * the value of the RTYPE bit for each reference
+ * picture in error-free communication
+ * nPictureHeaderRepetition : Specifies the frequency of picture header
+ * repetition
+ * nGOBHeaderInterval : Specifies the interval of non-empty GOB
+ * headers in units of GOBs
+ */
+typedef struct OMX_VIDEO_PARAM_H263TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nPFrames;
+ OMX_U32 nBFrames;
+ OMX_VIDEO_H263PROFILETYPE eProfile;
+ OMX_VIDEO_H263LEVELTYPE eLevel;
+ OMX_BOOL bPLUSPTYPEAllowed;
+ OMX_U32 nAllowedPictureTypes;
+ OMX_BOOL bForceRoundingTypeToZero;
+ OMX_U32 nPictureHeaderRepetition;
+ OMX_U32 nGOBHeaderInterval;
+} OMX_VIDEO_PARAM_H263TYPE;
+
+
+/**
+ * MPEG-2 profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ */
+typedef enum OMX_VIDEO_MPEG2PROFILETYPE {
+ OMX_VIDEO_MPEG2ProfileSimple = 0, /**< Simple Profile */
+ OMX_VIDEO_MPEG2ProfileMain, /**< Main Profile */
+ OMX_VIDEO_MPEG2Profile422, /**< 4:2:2 Profile */
+ OMX_VIDEO_MPEG2ProfileSNR, /**< SNR Profile */
+ OMX_VIDEO_MPEG2ProfileSpatial, /**< Spatial Profile */
+ OMX_VIDEO_MPEG2ProfileHigh, /**< High Profile */
+ OMX_VIDEO_MPEG2ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_MPEG2ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_MPEG2ProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_MPEG2PROFILETYPE;
+
+
+/**
+ * MPEG-2 level types, each level indicates support for various frame
+ * sizes, bit rates, decoder frame rates. No need
+ */
+typedef enum OMX_VIDEO_MPEG2LEVELTYPE {
+ OMX_VIDEO_MPEG2LevelLL = 0, /**< Low Level */
+ OMX_VIDEO_MPEG2LevelML, /**< Main Level */
+ OMX_VIDEO_MPEG2LevelH14, /**< High 1440 */
+ OMX_VIDEO_MPEG2LevelHL, /**< High Level */
+ OMX_VIDEO_MPEG2LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_MPEG2LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_MPEG2LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_MPEG2LEVELTYPE;
+
+
+/**
+ * MPEG-2 params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nPFrames : Number of P frames between each I frame
+ * nBFrames : Number of B frames between each I frame
+ * eProfile : MPEG-2 profile(s) to use
+ * eLevel : MPEG-2 levels(s) to use
+ */
+typedef struct OMX_VIDEO_PARAM_MPEG2TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nPFrames;
+ OMX_U32 nBFrames;
+ OMX_VIDEO_MPEG2PROFILETYPE eProfile;
+ OMX_VIDEO_MPEG2LEVELTYPE eLevel;
+} OMX_VIDEO_PARAM_MPEG2TYPE;
+
+
+/**
+ * MPEG-4 profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ *
+ * ENUMS:
+ * - Simple Profile, Levels 1-3
+ * - Simple Scalable Profile, Levels 1-2
+ * - Core Profile, Levels 1-2
+ * - Main Profile, Levels 2-4
+ * - N-bit Profile, Level 2
+ * - Scalable Texture Profile, Level 1
+ * - Simple Face Animation Profile, Levels 1-2
+ * - Simple Face and Body Animation (FBA) Profile, Levels 1-2
+ * - Basic Animated Texture Profile, Levels 1-2
+ * - Hybrid Profile, Levels 1-2
+ * - Advanced Real Time Simple Profiles, Levels 1-4
+ * - Core Scalable Profile, Levels 1-3
+ * - Advanced Coding Efficiency Profile, Levels 1-4
+ * - Advanced Core Profile, Levels 1-2
+ * - Advanced Scalable Texture, Levels 2-3
+ */
+typedef enum OMX_VIDEO_MPEG4PROFILETYPE {
+ OMX_VIDEO_MPEG4ProfileSimple = 0x01,
+ OMX_VIDEO_MPEG4ProfileSimpleScalable = 0x02,
+ OMX_VIDEO_MPEG4ProfileCore = 0x04,
+ OMX_VIDEO_MPEG4ProfileMain = 0x08,
+ OMX_VIDEO_MPEG4ProfileNbit = 0x10,
+ OMX_VIDEO_MPEG4ProfileScalableTexture = 0x20,
+ OMX_VIDEO_MPEG4ProfileSimpleFace = 0x40,
+ OMX_VIDEO_MPEG4ProfileSimpleFBA = 0x80,
+ OMX_VIDEO_MPEG4ProfileBasicAnimated = 0x100,
+ OMX_VIDEO_MPEG4ProfileHybrid = 0x200,
+ OMX_VIDEO_MPEG4ProfileAdvancedRealTime = 0x400,
+ OMX_VIDEO_MPEG4ProfileCoreScalable = 0x800,
+ OMX_VIDEO_MPEG4ProfileAdvancedCoding = 0x1000,
+ OMX_VIDEO_MPEG4ProfileAdvancedCore = 0x2000,
+ OMX_VIDEO_MPEG4ProfileAdvancedScalable = 0x4000,
+ OMX_VIDEO_MPEG4ProfileAdvancedSimple = 0x8000,
+ OMX_VIDEO_MPEG4ProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_MPEG4ProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_MPEG4ProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_MPEG4PROFILETYPE;
+
+
+/**
+ * MPEG-4 level types, each level indicates support for various frame
+ * sizes, bit rates, decoder frame rates. No need
+ */
+typedef enum OMX_VIDEO_MPEG4LEVELTYPE {
+ OMX_VIDEO_MPEG4Level0 = 0x01, /**< Level 0 */
+ OMX_VIDEO_MPEG4Level0b = 0x02, /**< Level 0b */
+ OMX_VIDEO_MPEG4Level1 = 0x04, /**< Level 1 */
+ OMX_VIDEO_MPEG4Level2 = 0x08, /**< Level 2 */
+ OMX_VIDEO_MPEG4Level3 = 0x10, /**< Level 3 */
+ OMX_VIDEO_MPEG4Level4 = 0x20, /**< Level 4 */
+ OMX_VIDEO_MPEG4Level4a = 0x40, /**< Level 4a */
+ OMX_VIDEO_MPEG4Level5 = 0x80, /**< Level 5 */
+ OMX_VIDEO_MPEG4LevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_MPEG4LevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_MPEG4LEVELTYPE;
+
+
+/**
+ * MPEG-4 configuration. This structure handles configuration options
+ * which are specific to MPEG4 algorithms
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nSliceHeaderSpacing : Number of macroblocks between slice header (H263+
+ * Annex K). Put zero if not used
+ * bSVH : Enable Short Video Header mode
+ * bGov : Flag to enable GOV
+ * nPFrames : Number of P frames between each I frame (also called
+ * GOV period)
+ * nBFrames : Number of B frames between each I frame
+ * nIDCVLCThreshold : Value of intra DC VLC threshold
+ * bACPred : Flag to use ac prediction
+ * nMaxPacketSize : Maximum size of packet in bytes.
+ * nTimeIncRes : Used to pass VOP time increment resolution for MPEG4.
+ * Interpreted as described in MPEG4 standard.
+ * eProfile : MPEG-4 profile(s) to use.
+ * eLevel : MPEG-4 level(s) to use.
+ * nAllowedPictureTypes : Specifies the picture types allowed in the bitstream
+ * nHeaderExtension : Specifies the number of consecutive video packet
+ * headers within a VOP
+ * bReversibleVLC : Specifies whether reversible variable length coding
+ * is in use
+ */
+typedef struct OMX_VIDEO_PARAM_MPEG4TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nSliceHeaderSpacing;
+ OMX_BOOL bSVH;
+ OMX_BOOL bGov;
+ OMX_U32 nPFrames;
+ OMX_U32 nBFrames;
+ OMX_U32 nIDCVLCThreshold;
+ OMX_BOOL bACPred;
+ OMX_U32 nMaxPacketSize;
+ OMX_U32 nTimeIncRes;
+ OMX_VIDEO_MPEG4PROFILETYPE eProfile;
+ OMX_VIDEO_MPEG4LEVELTYPE eLevel;
+ OMX_U32 nAllowedPictureTypes;
+ OMX_U32 nHeaderExtension;
+ OMX_BOOL bReversibleVLC;
+} OMX_VIDEO_PARAM_MPEG4TYPE;
+
+
+/**
+ * WMV Versions
+ */
+typedef enum OMX_VIDEO_WMVFORMATTYPE {
+ OMX_VIDEO_WMVFormatUnused = 0x01, /**< Format unused or unknown */
+ OMX_VIDEO_WMVFormat7 = 0x02, /**< Windows Media Video format 7 */
+ OMX_VIDEO_WMVFormat8 = 0x04, /**< Windows Media Video format 8 */
+ OMX_VIDEO_WMVFormat9 = 0x08, /**< Windows Media Video format 9 */
+ OMX_VIDEO_WMFFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_WMFFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_WMVFormatMax = 0x7FFFFFFF
+} OMX_VIDEO_WMVFORMATTYPE;
+
+
+/**
+ * WMV Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Version of WMV stream / data
+ */
+typedef struct OMX_VIDEO_PARAM_WMVTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_WMVFORMATTYPE eFormat;
+} OMX_VIDEO_PARAM_WMVTYPE;
+
+
+/**
+ * Real Video Version
+ */
+typedef enum OMX_VIDEO_RVFORMATTYPE {
+ OMX_VIDEO_RVFormatUnused = 0, /**< Format unused or unknown */
+ OMX_VIDEO_RVFormat8, /**< Real Video format 8 */
+ OMX_VIDEO_RVFormat9, /**< Real Video format 9 */
+ OMX_VIDEO_RVFormatG2, /**< Real Video Format G2 */
+ OMX_VIDEO_RVFormatKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_RVFormatVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_RVFormatMax = 0x7FFFFFFF
+} OMX_VIDEO_RVFORMATTYPE;
+
+
+/**
+ * Real Video Params
+ *
+ * STUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Version of RV stream / data
+ * nBitsPerPixel : Bits per pixel coded in the frame
+ * nPaddedWidth : Padded width in pixel of a video frame
+ * nPaddedHeight : Padded Height in pixels of a video frame
+ * nFrameRate : Rate of video in frames per second
+ * nBitstreamFlags : Flags which internal information about the bitstream
+ * nBitstreamVersion : Bitstream version
+ * nMaxEncodeFrameSize: Max encoded frame size
+ * bEnablePostFilter : Turn on/off post filter
+ * bEnableTemporalInterpolation : Turn on/off temporal interpolation
+ * bEnableLatencyMode : When enabled, the decoder does not display a decoded
+ * frame until it has detected that no enhancement layer
+ * frames or dependent B frames will be coming. This
+ * detection usually occurs when a subsequent non-B
+ * frame is encountered
+ */
+typedef struct OMX_VIDEO_PARAM_RVTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_RVFORMATTYPE eFormat;
+ OMX_U16 nBitsPerPixel;
+ OMX_U16 nPaddedWidth;
+ OMX_U16 nPaddedHeight;
+ OMX_U32 nFrameRate;
+ OMX_U32 nBitstreamFlags;
+ OMX_U32 nBitstreamVersion;
+ OMX_U32 nMaxEncodeFrameSize;
+ OMX_BOOL bEnablePostFilter;
+ OMX_BOOL bEnableTemporalInterpolation;
+ OMX_BOOL bEnableLatencyMode;
+} OMX_VIDEO_PARAM_RVTYPE;
+
+
+/**
+ * AVC profile types, each profile indicates support for various
+ * performance bounds and different annexes.
+ */
+typedef enum OMX_VIDEO_AVCPROFILETYPE {
+ OMX_VIDEO_AVCProfileBaseline = 0x01, /**< Baseline profile */
+ OMX_VIDEO_AVCProfileMain = 0x02, /**< Main profile */
+ OMX_VIDEO_AVCProfileExtended = 0x04, /**< Extended profile */
+ OMX_VIDEO_AVCProfileHigh = 0x08, /**< High profile */
+ OMX_VIDEO_AVCProfileHigh10 = 0x10, /**< High 10 profile */
+ OMX_VIDEO_AVCProfileHigh422 = 0x20, /**< High 4:2:2 profile */
+ OMX_VIDEO_AVCProfileHigh444 = 0x40, /**< High 4:4:4 profile */
+ OMX_VIDEO_AVCProfileKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_AVCProfileVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_AVCProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCPROFILETYPE;
+
+
+/**
+ * AVC level types, each level indicates support for various frame sizes,
+ * bit rates, decoder frame rates. No need
+ */
+typedef enum OMX_VIDEO_AVCLEVELTYPE {
+ OMX_VIDEO_AVCLevel1 = 0x01, /**< Level 1 */
+ OMX_VIDEO_AVCLevel1b = 0x02, /**< Level 1b */
+ OMX_VIDEO_AVCLevel11 = 0x04, /**< Level 1.1 */
+ OMX_VIDEO_AVCLevel12 = 0x08, /**< Level 1.2 */
+ OMX_VIDEO_AVCLevel13 = 0x10, /**< Level 1.3 */
+ OMX_VIDEO_AVCLevel2 = 0x20, /**< Level 2 */
+ OMX_VIDEO_AVCLevel21 = 0x40, /**< Level 2.1 */
+ OMX_VIDEO_AVCLevel22 = 0x80, /**< Level 2.2 */
+ OMX_VIDEO_AVCLevel3 = 0x100, /**< Level 3 */
+ OMX_VIDEO_AVCLevel31 = 0x200, /**< Level 3.1 */
+ OMX_VIDEO_AVCLevel32 = 0x400, /**< Level 3.2 */
+ OMX_VIDEO_AVCLevel4 = 0x800, /**< Level 4 */
+ OMX_VIDEO_AVCLevel41 = 0x1000, /**< Level 4.1 */
+ OMX_VIDEO_AVCLevel42 = 0x2000, /**< Level 4.2 */
+ OMX_VIDEO_AVCLevel5 = 0x4000, /**< Level 5 */
+ OMX_VIDEO_AVCLevel51 = 0x8000, /**< Level 5.1 */
+ OMX_VIDEO_AVCLevel52 = 0x10000, /**< Level 5.2 */
+ OMX_VIDEO_AVCLevelKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_AVCLevelVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_AVCLevelMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCLEVELTYPE;
+
+
+/**
+ * AVC loop filter modes
+ *
+ * OMX_VIDEO_AVCLoopFilterEnable : Enable
+ * OMX_VIDEO_AVCLoopFilterDisable : Disable
+ * OMX_VIDEO_AVCLoopFilterDisableSliceBoundary : Disabled on slice boundaries
+ */
+typedef enum OMX_VIDEO_AVCLOOPFILTERTYPE {
+ OMX_VIDEO_AVCLoopFilterEnable = 0,
+ OMX_VIDEO_AVCLoopFilterDisable,
+ OMX_VIDEO_AVCLoopFilterDisableSliceBoundary,
+ OMX_VIDEO_AVCLoopFilterKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_AVCLoopFilterVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_AVCLoopFilterMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCLOOPFILTERTYPE;
+
+
+/**
+ * AVC params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nSliceHeaderSpacing : Number of macroblocks between slice header, put
+ * zero if not used
+ * nPFrames : Number of P frames between each I frame
+ * nBFrames : Number of B frames between each I frame
+ * bUseHadamard : Enable/disable Hadamard transform
+ * nRefFrames : Max number of reference frames to use for inter
+ * motion search (1-16)
+ * nRefIdxTrailing : Pic param set ref frame index (index into ref
+ * frame buffer of trailing frames list), B frame
+ * support
+ * nRefIdxForward : Pic param set ref frame index (index into ref
+ * frame buffer of forward frames list), B frame
+ * support
+ * bEnableUEP : Enable/disable unequal error protection. This
+ * is only valid of data partitioning is enabled.
+ * bEnableFMO : Enable/disable flexible macroblock ordering
+ * bEnableASO : Enable/disable arbitrary slice ordering
+ * bEnableRS : Enable/disable sending of redundant slices
+ * eProfile : AVC profile(s) to use
+ * eLevel : AVC level(s) to use
+ * nAllowedPictureTypes : Specifies the picture types allowed in the
+ * bitstream
+ * bFrameMBsOnly : specifies that every coded picture of the
+ * coded video sequence is a coded frame
+ * containing only frame macroblocks
+ * bMBAFF : Enable/disable switching between frame and
+ * field macroblocks within a picture
+ * bEntropyCodingCABAC : Entropy decoding method to be applied for the
+ * syntax elements for which two descriptors appear
+ * in the syntax tables
+ * bWeightedPPrediction : Enable/disable weighted prediction shall not
+ * be applied to P and SP slices
+ * nWeightedBipredicitonMode : Default weighted prediction is applied to B
+ * slices
+ * bconstIpred : Enable/disable intra prediction
+ * bDirect8x8Inference : Specifies the method used in the derivation
+ * process for luma motion vectors for B_Skip,
+ * B_Direct_16x16 and B_Direct_8x8 as specified
+ * in subclause 8.4.1.2 of the AVC spec
+ * bDirectSpatialTemporal : Flag indicating spatial or temporal direct
+ * mode used in B slice coding (related to
+ * bDirect8x8Inference) . Spatial direct mode is
+ * more common and should be the default.
+ * nCabacInitIdx : Index used to init CABAC contexts
+ * eLoopFilterMode : Enable/disable loop filter
+ */
+typedef struct OMX_VIDEO_PARAM_AVCTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nSliceHeaderSpacing;
+ OMX_U32 nPFrames;
+ OMX_U32 nBFrames;
+ OMX_BOOL bUseHadamard;
+ OMX_U32 nRefFrames;
+ OMX_U32 nRefIdx10ActiveMinus1;
+ OMX_U32 nRefIdx11ActiveMinus1;
+ OMX_BOOL bEnableUEP;
+ OMX_BOOL bEnableFMO;
+ OMX_BOOL bEnableASO;
+ OMX_BOOL bEnableRS;
+ OMX_VIDEO_AVCPROFILETYPE eProfile;
+ OMX_VIDEO_AVCLEVELTYPE eLevel;
+ OMX_U32 nAllowedPictureTypes;
+ OMX_BOOL bFrameMBsOnly;
+ OMX_BOOL bMBAFF;
+ OMX_BOOL bEntropyCodingCABAC;
+ OMX_BOOL bWeightedPPrediction;
+ OMX_U32 nWeightedBipredicitonMode;
+ OMX_BOOL bconstIpred ;
+ OMX_BOOL bDirect8x8Inference;
+ OMX_BOOL bDirectSpatialTemporal;
+ OMX_U32 nCabacInitIdc;
+ OMX_VIDEO_AVCLOOPFILTERTYPE eLoopFilterMode;
+} OMX_VIDEO_PARAM_AVCTYPE;
+
+typedef struct OMX_VIDEO_PARAM_PROFILELEVELTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 eProfile; /**< type is OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE,
+ or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
+ OMX_U32 eLevel; /**< type is OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE,
+ or OMX_VIDEO_MPEG4PROFILETYPE depending on context */
+ OMX_U32 nProfileIndex; /**< Used to query for individual profile support information,
+ This parameter is valid only for
+ OMX_IndexParamVideoProfileLevelQuerySupported index,
+ For all other indices this parameter is to be ignored. */
+} OMX_VIDEO_PARAM_PROFILELEVELTYPE;
+
+/**
+ * Structure for dynamically configuring bitrate mode of a codec.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the struct in bytes
+ * nVersion : OMX spec version info
+ * nPortIndex : Port that this struct applies to
+ * nEncodeBitrate : Target average bitrate to be generated in bps
+ */
+typedef struct OMX_VIDEO_CONFIG_BITRATETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nEncodeBitrate;
+} OMX_VIDEO_CONFIG_BITRATETYPE;
+
+/**
+ * Defines Encoder Frame Rate setting
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * xEncodeFramerate : Encoding framerate represented in Q16 format
+ */
+typedef struct OMX_CONFIG_FRAMERATETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 xEncodeFramerate; /* Q16 format */
+} OMX_CONFIG_FRAMERATETYPE;
+
+typedef struct OMX_CONFIG_INTRAREFRESHVOPTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL IntraRefreshVOP;
+} OMX_CONFIG_INTRAREFRESHVOPTYPE;
+
+typedef struct OMX_CONFIG_MACROBLOCKERRORMAPTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nErrMapSize; /* Size of the Error Map in bytes */
+ OMX_U8 ErrMap[1]; /* Error map hint */
+} OMX_CONFIG_MACROBLOCKERRORMAPTYPE;
+
+typedef struct OMX_CONFIG_MBERRORREPORTINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnabled;
+} OMX_CONFIG_MBERRORREPORTINGTYPE;
+
+typedef struct OMX_PARAM_MACROBLOCKSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nMacroblocks;
+} OMX_PARAM_MACROBLOCKSTYPE;
+
+/**
+ * AVC Slice Mode modes
+ *
+ * OMX_VIDEO_SLICEMODE_AVCDefault : Normal frame encoding, one slice per frame
+ * OMX_VIDEO_SLICEMODE_AVCMBSlice : NAL mode, number of MBs per frame
+ * OMX_VIDEO_SLICEMODE_AVCByteSlice : NAL mode, number of bytes per frame
+ */
+typedef enum OMX_VIDEO_AVCSLICEMODETYPE {
+ OMX_VIDEO_SLICEMODE_AVCDefault = 0,
+ OMX_VIDEO_SLICEMODE_AVCMBSlice,
+ OMX_VIDEO_SLICEMODE_AVCByteSlice,
+ OMX_VIDEO_SLICEMODE_AVCKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */
+ OMX_VIDEO_SLICEMODE_AVCVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ OMX_VIDEO_SLICEMODE_AVCLevelMax = 0x7FFFFFFF
+} OMX_VIDEO_AVCSLICEMODETYPE;
+
+/**
+ * AVC FMO Slice Mode Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nNumSliceGroups : Specifies the number of slice groups
+ * nSliceGroupMapType : Specifies the type of slice groups
+ * eSliceMode : Specifies the type of slice
+ */
+typedef struct OMX_VIDEO_PARAM_AVCSLICEFMO {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U8 nNumSliceGroups;
+ OMX_U8 nSliceGroupMapType;
+ OMX_VIDEO_AVCSLICEMODETYPE eSliceMode;
+} OMX_VIDEO_PARAM_AVCSLICEFMO;
+
+/**
+ * AVC IDR Period Configs
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nIDRPeriod : Specifies periodicity of IDR frames
+ * nPFrames : Specifies internal of coding Intra frames
+ */
+typedef struct OMX_VIDEO_CONFIG_AVCINTRAPERIOD {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nIDRPeriod;
+ OMX_U32 nPFrames;
+} OMX_VIDEO_CONFIG_AVCINTRAPERIOD;
+
+/**
+ * AVC NAL Size Configs
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nNaluBytes : Specifies the NAL unit size
+ */
+typedef struct OMX_VIDEO_CONFIG_NALSIZE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nNaluBytes;
+} OMX_VIDEO_CONFIG_NALSIZE;
+
+
+/**
+ * Deinterlace Config
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nEnable : Specifies to enable deinterlace
+ */
+typedef struct OMX_VIDEO_CONFIG_DEINTERLACE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nEnable;
+} OMX_VIDEO_CONFIG_DEINTERLACE;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+/* File EOF */
+
diff --git a/msmcobalt/mm-core/inc/OMX_VideoExt.h b/msmcobalt/mm-core/inc/OMX_VideoExt.h
new file mode 100644
index 0000000..8abe5e4
--- /dev/null
+++ b/msmcobalt/mm-core/inc/OMX_VideoExt.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2010 The Khronos Group Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject
+ * to the following conditions:
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/** OMX_VideoExt.h - OpenMax IL version 1.1.2
+ * The OMX_VideoExt header file contains extensions to the
+ * definitions used by both the application and the component to
+ * access video items.
+ */
+
+#ifndef OMX_VideoExt_h
+#define OMX_VideoExt_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Each OMX header shall include all required header files to allow the
+ * header to compile without errors. The includes below are required
+ * for this header file to compile successfully
+ */
+#include <OMX_Core.h>
+
+/** NALU Formats */
+typedef enum OMX_NALUFORMATSTYPE {
+ OMX_NaluFormatStartCodes = 1,
+ OMX_NaluFormatOneNaluPerBuffer = 2,
+ OMX_NaluFormatOneByteInterleaveLength = 4,
+ OMX_NaluFormatTwoByteInterleaveLength = 8,
+ OMX_NaluFormatFourByteInterleaveLength = 16,
+ OMX_NaluFormatCodingMax = 0x7FFFFFFF
+} OMX_NALUFORMATSTYPE;
+
+/** NAL Stream Format */
+typedef struct OMX_NALSTREAMFORMATTYPE{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_NALUFORMATSTYPE eNaluFormat;
+} OMX_NALSTREAMFORMATTYPE;
+
+/** VP8 profiles */
+typedef enum OMX_VIDEO_VP8PROFILETYPE {
+ OMX_VIDEO_VP8ProfileMain = 0x01,
+ OMX_VIDEO_VP8ProfileUnknown = 0x6EFFFFFF,
+ OMX_VIDEO_VP8ProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_VP8PROFILETYPE;
+
+/** VP8 levels */
+typedef enum OMX_VIDEO_VP8LEVELTYPE {
+ OMX_VIDEO_VP8Level_Version0 = 0x01,
+ OMX_VIDEO_VP8Level_Version1 = 0x02,
+ OMX_VIDEO_VP8Level_Version2 = 0x04,
+ OMX_VIDEO_VP8Level_Version3 = 0x08,
+ OMX_VIDEO_VP8LevelUnknown = 0x6EFFFFFF,
+ OMX_VIDEO_VP8LevelMax = 0x7FFFFFFF
+} OMX_VIDEO_VP8LEVELTYPE;
+
+/** VP8 Param */
+typedef struct OMX_VIDEO_PARAM_VP8TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_VP8PROFILETYPE eProfile;
+ OMX_VIDEO_VP8LEVELTYPE eLevel;
+ OMX_U32 nDCTPartitions;
+ OMX_BOOL bErrorResilientMode;
+} OMX_VIDEO_PARAM_VP8TYPE;
+
+/** Structure for configuring VP8 reference frames */
+typedef struct OMX_VIDEO_VP8REFERENCEFRAMETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bPreviousFrameRefresh;
+ OMX_BOOL bGoldenFrameRefresh;
+ OMX_BOOL bAlternateFrameRefresh;
+ OMX_BOOL bUsePreviousFrame;
+ OMX_BOOL bUseGoldenFrame;
+ OMX_BOOL bUseAlternateFrame;
+} OMX_VIDEO_VP8REFERENCEFRAMETYPE;
+
+/** Structure for querying VP8 reference frame type */
+typedef struct OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bIsIntraFrame;
+ OMX_BOOL bIsGoldenOrAlternateFrame;
+} OMX_VIDEO_VP8REFERENCEFRAMEINFOTYPE;
+
+/** HEVC Profiles */
+typedef enum OMX_VIDEO_HEVCPROFILETYPE {
+ OMX_VIDEO_HEVCProfileMain = 0x01,
+ OMX_VIDEO_HEVCProfileMain10 = 0x02,
+ OMX_VIDEO_HEVCProfileUnknown = 0x6EFFFFFF,
+ OMX_VIDEO_HEVCProfileMax = 0x7FFFFFFF
+} OMX_VIDEO_HEVCPROFILETYPE;
+
+/** HEVC levels */
+typedef enum OMX_VIDEO_HEVCLEVELTYPE {
+ OMX_VIDEO_HEVCLevel_Version0 = 0x0,
+ OMX_VIDEO_HEVCMainTierLevel1 = 0x1,
+ OMX_VIDEO_HEVCHighTierLevel1 = 0x2,
+ OMX_VIDEO_HEVCMainTierLevel2 = 0x4,
+ OMX_VIDEO_HEVCHighTierLevel2 = 0x8,
+ OMX_VIDEO_HEVCMainTierLevel21 = 0x10,
+ OMX_VIDEO_HEVCHighTierLevel21 = 0x20,
+ OMX_VIDEO_HEVCMainTierLevel3 = 0x40,
+ OMX_VIDEO_HEVCHighTierLevel3 = 0x80,
+ OMX_VIDEO_HEVCMainTierLevel31 = 0x100,
+ OMX_VIDEO_HEVCHighTierLevel31 = 0x200,
+ OMX_VIDEO_HEVCMainTierLevel4 = 0x400,
+ OMX_VIDEO_HEVCHighTierLevel4 = 0x800,
+ OMX_VIDEO_HEVCMainTierLevel41 = 0x1000,
+ OMX_VIDEO_HEVCHighTierLevel41 = 0x2000,
+ OMX_VIDEO_HEVCMainTierLevel5 = 0x4000,
+ OMX_VIDEO_HEVCHighTierLevel5 = 0x8000,
+ OMX_VIDEO_HEVCMainTierLevel51 = 0x10000,
+ OMX_VIDEO_HEVCHighTierLevel51 = 0x20000,
+ OMX_VIDEO_HEVCMainTierLevel52 = 0x40000,
+ OMX_VIDEO_HEVCHighTierLevel52 = 0x80000,
+ OMX_VIDEO_HEVCMainTierLevel6 = 0x100000,
+ OMX_VIDEO_HEVCHighTierLevel6 = 0x200000,
+ OMX_VIDEO_HEVCMainTierLevel61 = 0x400000,
+ OMX_VIDEO_HEVCHighTierLevel61 = 0x800000,
+ OMX_VIDEO_HEVCMainTierLevel62 = 0x1000000,
+ OMX_VIDEO_HEVCLevelUnknown = 0x6EFFFFFF,
+ OMX_VIDEO_HEVCLevelMax = 0x7FFFFFFF
+} OMX_VIDEO_HEVCLEVELTYPE;
+
+/** HEVC Param */
+typedef struct OMX_VIDEO_PARAM_HEVCTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_HEVCPROFILETYPE eProfile;
+ OMX_VIDEO_HEVCLEVELTYPE eLevel;
+ OMX_U32 nKeyFrameInterval;
+} OMX_VIDEO_PARAM_HEVCTYPE;
+
+/**
+ * Structure for configuring video compression intra refresh period
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nRefreshPeriod : Intra refreh period in frames. Value 0 means disable intra refresh
+*/
+typedef struct OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nRefreshPeriod;
+} OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE;
+
+/** Maximum number of temporal layers supported by AVC/HEVC */
+#define OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS 8
+
+/** temporal layer patterns */
+typedef enum OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE {
+ OMX_VIDEO_AndroidTemporalLayeringPatternNone = 0,
+ // pattern as defined by WebRTC
+ OMX_VIDEO_AndroidTemporalLayeringPatternWebRTC = 1 << 0,
+ // pattern where frames in any layer other than the base layer only depend on at most the very
+ // last frame from each preceding layer (other than the base layer.)
+ OMX_VIDEO_AndroidTemporalLayeringPatternAndroid = 1 << 1,
+} OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE;
+
+/**
+ * Android specific param for configuration of temporal layering.
+ * Android only supports temporal layering where successive layers each double the
+ * previous layer's framerate.
+ * NOTE: Reading this parameter at run-time SHALL return actual run-time values.
+ *
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to (output port for encoders)
+ * eSupportedPatterns : A bitmask of supported layering patterns
+ * nLayerCountMax : Max number of temporal coding layers supported
+ * by the encoder (must be at least 1, 1 meaning temporal layering
+ * is NOT supported)
+ * nBLayerCountMax : Max number of layers that can contain B frames
+ * (0) to (nLayerCountMax - 1)
+ * ePattern : Layering pattern.
+ * nPLayerCountActual : Number of temporal layers to be coded with non-B frames,
+ * starting from and including the base-layer.
+ * (1 to nLayerCountMax - nBLayerCountActual)
+ * If nPLayerCountActual is 1 and nBLayerCountActual is 0, temporal
+ * layering is disabled. Otherwise, it is enabled.
+ * nBLayerCountActual : Number of temporal layers to be coded with B frames,
+ * starting after non-B layers.
+ * (0 to nBLayerCountMax)
+ * bBitrateRatiosSpecified : Flag to indicate if layer-wise bitrate
+ * distribution is specified.
+ * nBitrateRatios : Bitrate ratio (100 based) per layer (index 0 is base layer).
+ * Honored if bBitrateRatiosSpecified is set.
+ * i.e for 4 layers with desired distribution (25% 25% 25% 25%),
+ * nBitrateRatio = {25, 50, 75, 100, ... }
+ * Values in indices not less than 'the actual number of layers
+ * minus 1' MAY be ignored and assumed to be 100.
+ */
+typedef struct OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE eSupportedPatterns;
+ OMX_U32 nLayerCountMax;
+ OMX_U32 nBLayerCountMax;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+ OMX_U32 nPLayerCountActual;
+ OMX_U32 nBLayerCountActual;
+ OMX_BOOL bBitrateRatiosSpecified;
+ OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE;
+
+/**
+ * Android specific config for changing the temporal-layer count or
+ * bitrate-distribution at run-time.
+ *
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to (output port for encoders)
+ * ePattern : Layering pattern.
+ * nPLayerCountActual : Number of temporal layers to be coded with non-B frames.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ * nBLayerCountActual : Number of temporal layers to be coded with B frames.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ * bBitrateRatiosSpecified : Flag to indicate if layer-wise bitrate
+ * distribution is specified.
+ * nBitrateRatios : Bitrate ratio (100 based, Q16 values) per layer (0 is base layer).
+ * Honored if bBitrateRatiosSpecified is set.
+ * (same OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE limits apply.)
+ */
+typedef struct OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern;
+ OMX_U32 nPLayerCountActual;
+ OMX_U32 nBLayerCountActual;
+ OMX_BOOL bBitrateRatiosSpecified;
+ OMX_U32 nBitrateRatios[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+} OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE;
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* OMX_VideoExt_h */
+/* File EOF */
diff --git a/msmcobalt/mm-core/inc/QCMediaDefs.h b/msmcobalt/mm-core/inc/QCMediaDefs.h
new file mode 100644
index 0000000..d86f0a8
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QCMediaDefs.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012 - 2015, 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 QC_MEDIA_DEFS_H_
+
+#define QC_MEDIA_DEFS_H_
+
+namespace android {
+
+extern const char *MEDIA_MIMETYPE_AUDIO_EVRC;
+extern const char *MEDIA_MIMETYPE_VIDEO_WMV;
+extern const char *MEDIA_MIMETYPE_VIDEO_WMV_VC1;
+extern const char *MEDIA_MIMETYPE_AUDIO_WMA;
+extern const char *MEDIA_MIMETYPE_AUDIO_WMA_PRO;
+extern const char *MEDIA_MIMETYPE_AUDIO_WMA_LOSSLESS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_ASF;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX;
+extern const char *MEDIA_MIMETYPE_AUDIO_AC3;
+extern const char *MEDIA_MIMETYPE_CONTAINER_AAC;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCP;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX311;
+extern const char *MEDIA_MIMETYPE_VIDEO_DIVX4;
+extern const char *MEDIA_MIMETYPE_CONTAINER_MPEG2;
+extern const char *MEDIA_MIMETYPE_CONTAINER_3G2;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS;
+extern const char *MEDIA_MIMETYPE_AUDIO_DTS_LBR;
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
+extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS;
+extern const char *MEDIA_MIMETYPE_AUDIO_AIFF;
+extern const char *MEDIA_MIMETYPE_AUDIO_ALAC;
+extern const char *MEDIA_MIMETYPE_AUDIO_APE;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2TS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_NB;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_WB;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCWAV;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCFLV;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2PS;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG4;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCMATROSKA;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QCOGG;
+extern const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC;
+extern const char *MEDIA_MIMETYPE_VIDEO_VPX; //backward compatibility
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3_JOC;
+} // namespace android
+
+#endif //QC_MEDIA_DEFS_H_
diff --git a/msmcobalt/mm-core/inc/QCMetaData.h b/msmcobalt/mm-core/inc/QCMetaData.h
new file mode 100644
index 0000000..5990637
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QCMetaData.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012-2015, 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 QC_META_DATA_H_
+
+#define QC_META_DATA_H_
+
+namespace android {
+
+enum {
+ kKeyAacCodecSpecificData = 'nacc' , // for native aac files
+
+ kKeyRawCodecSpecificData = 'rcsd', // raw data - added to support mmParser
+ kKeyDivXVersion = 'DivX', // int32_t
+ kKeyDivXDrm = 'QDrm', // void *
+ kKeyWMAEncodeOpt = 'eopt', // int32_t
+ kKeyWMABlockAlign = 'blka', // int32_t
+ kKeyWMAVersion = 'wmav', // int32_t
+ kKeyWMAAdvEncOpt1 = 'ade1', // int16_t
+ kKeyWMAAdvEncOpt2 = 'ade2', // int32_t
+ kKeyWMAFormatTag = 'fmtt', // int64_t
+ kKeyWMABitspersample = 'bsps', // int64_t
+ kKeyWMAVirPktSize = 'vpks', // int64_t
+ kKeyWMAChannelMask = 'chmk', // int32_t
+ kKeyVorbisData = 'vdat', // raw data
+
+ kKeyFileFormat = 'ffmt', // cstring
+
+ kkeyAacFormatAdif = 'adif', // bool (int32_t)
+ kKeyInterlace = 'intL', // bool (int32_t)
+ kkeyAacFormatLtp = 'ltp ',
+
+
+ //DTS subtype
+ kKeyDTSSubtype = 'dtss', //int32_t
+
+ //Extractor sets this
+ kKeyUseArbitraryMode = 'ArbM', //bool (int32_t)
+ kKeySmoothStreaming = 'ESmS', //bool (int32_t)
+ kKeyHFR = 'hfr ', // int32_t
+ kKeyHSR = 'hsr ', // int32_t
+
+ kKeySampleBits = 'sbit', // int32_t (audio sample bit-width)
+ kKeyPcmFormat = 'pfmt', //int32_t (pcm format)
+ kKeyMinBlkSize = 'mibs', //int32_t
+ kKeyMaxBlkSize = 'mabs', //int32_t
+ kKeyMinFrmSize = 'mifs', //int32_t
+ kKeyMaxFrmSize = 'mafs', //int32_t
+ kKeyMd5Sum = 'md5s', //cstring
+
+ kKeyBatchSize = 'btch', //int32_t
+ kKeyIsByteMode = 'bytm', //int32_t
+ kKeyUseSetBuffers = 'setb', //bool (int32_t)
+};
+
+enum {
+ kTypeDivXVer_3_11,
+ kTypeDivXVer_4,
+ kTypeDivXVer_5,
+ kTypeDivXVer_6,
+};
+enum {
+ kTypeWMA,
+ kTypeWMAPro,
+ kTypeWMALossLess,
+};
+
+//This enum should be keep in sync with "enum Flags" in MediaExtractor.h in AOSP,
+//Value should reflect as last entry in the enum
+enum {
+ CAN_SEEK_TO_ZERO = 16, // the "previous button"
+};
+
+enum {
+ USE_SET_BUFFERS = 0x1,
+ USE_AUDIO_BIG_BUFFERS = 0x2,
+};
+} // namespace android
+
+#endif // QC_META_DATA_H_
diff --git a/msmcobalt/mm-core/inc/QOMX_AudioExtensions.h b/msmcobalt/mm-core/inc/QOMX_AudioExtensions.h
new file mode 100644
index 0000000..e904018
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_AudioExtensions.h
@@ -0,0 +1,617 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 2011, 2015 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 QOMX_AudioExtensions.h
+ This module contains the extensions for Audio
+
+*//*========================================================================*/
+
+#ifndef __H_QOMX_AUDIOEXTENSIONS_H__
+#define __H_QOMX_AUDIOEXTENSIONS_H__
+
+/*========================================================================
+
+ INCLUDE FILES FOR MODULE
+
+========================================================================== */
+#include <OMX_Audio.h>
+
+/*========================================================================
+
+ DEFINITIONS AND DECLARATIONS
+
+========================================================================== */
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif /* end of macro __cplusplus */
+
+/* Audio extension strings */
+#define OMX_QCOM_INDEX_PARAM_AMRWBPLUS "OMX.Qualcomm.index.audio.amrwbplus"
+#define OMX_QCOM_INDEX_PARAM_WMA10PRO "OMX.Qualcomm.index.audio.wma10pro"
+#define OMX_QCOM_INDEX_PARAM_SESSIONID "OMX.Qualcomm.index.audio.sessionId"
+#define OMX_QCOM_INDEX_PARAM_VOICERECORDTYPE "OMX.Qualcomm.index.audio.VoiceRecord"
+#define OMX_QCOM_INDEX_PARAM_AC3TYPE "OMX.Qualcomm.index.audio.ac3"
+#define OMX_QCOM_INDEX_PARAM_AC3PP "OMX.Qualcomm.index.audio.postproc.ac3"
+#define OMX_QCOM_INDEX_PARAM_DAK_BUNDLE "OMX.Qualcomm.index.audio.dakbundle"
+#define OMX_QCOM_INDEX_PARAM_DAK_M2S "OMX.Qualcomm.index.audio.dak_m2s"
+#define OMX_QCOM_INDEX_PARAM_DAK_SSE "OMX.Qualcomm.index.audio.dak_sse"
+#define OMX_QCOM_INDEX_PARAM_DAK_SLC "OMX.Qualcomm.index.audio.dak_slc"
+#define OMX_QCOM_INDEX_PARAM_DAK_VOL "OMX.Qualcomm.index.audio.dak_vol"
+#define OMX_QCOM_INDEX_PARAM_DAK_NB "OMX.Qualcomm.index.audio.dak_nb"
+#define OMX_QCOM_INDEX_PARAM_DAK_GEQ "OMX.Qualcomm.index.audio.dak_geq"
+#define OMX_QCOM_INDEX_PARAM_DAK_MSR "OMX.Qualcomm.index.audio.dak_msr"
+#define OMX_QCOM_INDEX_PARAM_DAK_HFE "OMX.Qualcomm.index.audio.dak_hfe"
+#define OMX_QCOM_INDEX_PARAM_DAK_FADE "OMX.Qualcomm.index.audio.dak_fade"
+#define OMX_QCOM_INDEX_PARAM_DAK_SEQ "OMX.Qualcomm.index.audio.dak_seq"
+#define OMX_QCOM_INDEX_CONFIG_DUALMONO "OMX.Qualcomm.index.audio.dualmono"
+#define OMX_QCOM_INDEX_CONFIG_AAC_SEL_MIX_COEF "OMX.Qualcomm.index.audio.aac_sel_mix_coef"
+#define OMX_QCOM_INDEX_PARAM_ALAC "OMX.Qualcomm.index.audio.alac"
+#define OMX_QCOM_INDEX_PARAM_APE "OMX.Qualcomm.index.audio.ape"
+#define OMX_QCOM_INDEX_PARAM_DSD "OMX.Qualcomm.index.audio.dsd"
+#define OMX_QCOM_INDEX_PARAM_FLAC_DEC "OMX.Qualcomm.index.audio.flacdec"
+
+#define ALAC_CSD_SIZE 24
+#define APE_CSD_SIZE 32
+
+typedef enum QOMX_AUDIO_AMRBANDMODETYPE {
+ QOMX_AUDIO_AMRBandModeWB9 = 0x7F000001,/**< AMRWB Mode 9 = SID*/
+ QOMX_AUDIO_AMRBandModeWB10 = 0x7F000002,/**< AMRWB Mode 10 = 13600 bps */
+ QOMX_AUDIO_AMRBandModeWB11 = 0x7F000003,/**< AMRWB Mode 11 = 18000 bps */
+ QOMX_AUDIO_AMRBandModeWB12 = 0x7F000004,/**< AMRWB Mode 12 = 24000 bps */
+ QOMX_AUDIO_AMRBandModeWB13 = 0x7F000005,/**< AMRWB Mode 13 = 24000 bps */
+ QOMX_AUDIO_AMRBandModeWB14 = 0x7F000006,/**< AMRWB Mode 14 = FRAME_ERASE*/
+ QOMX_AUDIO_AMRBandModeWB15 = 0x7F000007,/**< AMRWB Mode 15 = NO_DATA */
+}QOMX_AUDIO_AMRBANDMODETYPE;
+
+typedef enum QOMX_AUDIO_CODINGTYPE {
+ QOMX_AUDIO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */
+ QOMX_AUDIO_CodingEVRCB = 0x7F000001,
+ QOMX_AUDIO_CodingEVRCWB = 0x7F000002,
+ QOMX_AUDIO_CodingFLAC = 0x7F000003,
+ QOMX_AUDIO_CodingMax = 0x7FFFFFFF
+}QOMX_AUDIO_CODINGTYPE;
+
+
+/**
+ * AMR WB PLUS type
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nChannels : Number of channels
+ * nBitRate : Bit rate read only field
+ * nSampleRate : Sampling frequency for the clip(16/24/32/48KHz)
+ * eAMRBandMode : AMR Band Mode enumeration
+ * eAMRDTXMode : AMR DTX Mode enumeration
+ * eAMRFrameFormat : AMR frame format enumeration
+ */
+
+typedef struct QOMX_AUDIO_PARAM_AMRWBPLUSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nChannels;
+ OMX_U32 nBitRate;
+ OMX_U32 nSampleRate;
+ OMX_AUDIO_AMRBANDMODETYPE eAMRBandMode;
+ OMX_AUDIO_AMRDTXMODETYPE eAMRDTXMode;
+ OMX_AUDIO_AMRFRAMEFORMATTYPE eAMRFrameFormat;
+} QOMX_AUDIO_PARAM_AMRWBPLUSTYPE;
+
+typedef enum QOMX_AUDIO_WMAFORMATTYPE {
+ QOMX_AUDIO_WMAFormat10Pro = 0x7F000001, /**< Windows Media Audio format 10*/
+} QOMX_AUDIO_WMAFORMATTYPE;
+
+/**
+ * WMA 10 PRO type
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nChannels : Number of channels
+ * nBitRate : Bit rate read only field
+ * eFormat : Version of WMA stream / data
+ * eProfile : Profile of WMA stream / data
+ * nSamplingRate : Sampling rate of the source data
+ * nBlockAlign : block alignment, or block size, in bytes of the audio codec
+ * nEncodeOptions : WMA Type-specific data
+ * nSuperBlockAlign : WMA Type-specific data
+ * validBitsPerSample : encoded stream (24-bit or 16-bit)
+ * formatTag : codec ID(0x162 or 0x166)
+ * advancedEncodeOpt : bit packed words indicating the features supported for LBR bitstream
+ * advancedEncodeOpt2 : bit packed words indicating the features supported for LBR bitstream
+ */
+typedef struct QOMX_AUDIO_PARAM_WMA10PROTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U16 nChannels;
+ OMX_U32 nBitRate;
+ QOMX_AUDIO_WMAFORMATTYPE eFormat;
+ OMX_AUDIO_WMAPROFILETYPE eProfile;
+ OMX_U32 nSamplingRate;
+ OMX_U16 nBlockAlign;
+ OMX_U16 nEncodeOptions;
+ OMX_U32 nSuperBlockAlign;
+ OMX_U32 validBitsPerSample;
+ OMX_U32 formatTag;
+ OMX_U32 advancedEncodeOpt;
+ OMX_U32 advancedEncodeOpt2;
+ OMX_U16 nVirtualPktSize;
+} QOMX_AUDIO_PARAM_WMA10PROTYPE;
+
+
+typedef enum OMX_AUDIO_AC3FORMATTYPE {
+ omx_audio_ac3 = 0x7f000001, /**< ac-3 */
+ omx_audio_eac3 = 0x7f000002 /**< eac-3 */
+} OMX_AUDIO_AC3FORMATTYPE;
+
+typedef enum OMX_AUDIO_AC3_CHANNEL_CONFIG
+{
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_RSVD = 0,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_1_0,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_2_0,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_3_0,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_2_1,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_3_1,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_2_2,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_3_2,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_3_0_1,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_2_2_1,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_3_2_1,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_3_0_2,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_2_2_2,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_3_2_2,
+ OMX_AUDIO_AC3_CHANNEL_CONFIG_DEFAULT = 0xFFFF
+} OMX_AUDIO_AC3_CHANNEL_CONFIG;
+
+/**
+ * AC-3 type
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nChannels : Number of channels
+ * nBitRate : Bitrate
+ * nSamplingRate : Sampling rate, 32K, 44.1K, 48K only supported
+ * eFormat : AC-3 or EAC-3
+ * eChannelConfig : Channel configuration
+ * nProgramID : Indication of ProgramID, 0-7
+ * bCompressionOn : Flag to enable Compression
+ * bLfeOn : Flag for LFE on/off
+ * bDelaySurroundChannels : Flag to put delay on surround channels
+ *
+ */
+typedef struct QOMX_AUDIO_PARAM_AC3TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U16 nChannels;
+ OMX_U32 nBitRate;
+ OMX_U32 nSamplingRate;
+ OMX_AUDIO_AC3FORMATTYPE eFormat;
+ OMX_AUDIO_AC3_CHANNEL_CONFIG eChannelConfig;
+ OMX_U8 nProgramID;
+ OMX_BOOL bCompressionOn;
+ OMX_BOOL bLfeOn;
+ OMX_BOOL bDelaySurroundChannels;
+} QOMX_AUDIO_PARAM_AC3TYPE;
+
+typedef enum OMX_AUDIO_AC3_CHANNEL_ROUTING
+{
+ OMX_AUDIO_AC3_CHANNEL_LEFT,
+ OMX_AUDIO_AC3_CHANNEL_CENTER,
+ OMX_AUDIO_AC3_CHANNEL_RIGHT,
+ OMX_AUDIO_AC3_CHANNEL_LEFT_SURROUND,
+ OMX_AUDIO_AC3_CHANNEL_RIGHT_SURROUND,
+ OMX_AUDIO_AC3_CHANNEL_SURROUND,
+ OMX_AUDIO_AC3_CHANNEL_EXTENSION_1,
+ OMX_AUDIO_AC3_CHANNEL_EXTENSION_2,
+ OMX_AUDIO_AC3_CHANNEL_DEFAULT = 0xFFFF
+} OMX_AUDIO_AC3_CHANNEL_ROUTING;
+
+typedef enum OMX_AUDIO_AC3_COMPRESSION_MODE
+{
+ OMX_AUDIO_AC3_COMPRESSION_MODE_ANALOG_DIALNORM,
+ OMX_AUDIO_AC3_COMPRESSION_MODE_DIGITAL_DIALNORM,
+ OMX_AUDIO_AC3_COMPRESSION_MODE_LINE_OUT,
+ OMX_AUDIO_AC3_COMPRESSION_MODE_RF_REMOD
+} OMX_AUDIO_AC3_COMPRESSION_MODE;
+
+typedef enum OMX_AUDIO_AC3_STEREO_MODE
+{
+ OMX_AUDIO_AC3_STEREO_MODE_AUTO_DETECT,
+ OMX_AUDIO_AC3_STEREO_MODE_LT_RT,
+ OMX_AUDIO_AC3_STEREO_MODE_LO_RO,
+ OMX_AUDIO_AC3_STEREO_MODE_DEFAULT = 0xFFFF
+} OMX_AUDIO_AC3_STEREO_MODE;
+
+typedef enum OMX_AUDIO_AC3_DUAL_MONO_MODE
+{
+ OMX_AUDIO_AC3_DUAL_MONO_MODE_STEREO,
+ OMX_AUDIO_AC3_DUAL_MONO_MODE_LEFT_MONO,
+ OMX_AUDIO_AC3_DUAL_MONO_MODE_RIGHT_MONO,
+ OMX_AUDIO_AC3_DUAL_MONO_MODE_MIXED_MONO,
+ OMX_AUDIO_AC3_DUAL_MONO_MODE_DEFAULT = 0xFFFF
+} OMX_AUDIO_AC3_DUAL_MONO_MODE;
+
+typedef enum OMX_AUDIO_AC3_KARAOKE_MODE
+{
+ OMX_AUDIO_AC3_KARAOKE_MODE_NO_VOCAL,
+ OMX_AUDIO_AC3_KARAOKE_MODE_LEFT_VOCAL,
+ OMX_AUDIO_AC3_KARAOKE_MODE_RIGHT_VOCAL,
+ OMX_AUDIO_AC3_KARAOKE_MODE_BOTH_VOCAL,
+ OMX_AUDIO_AC3_KARAOKE_MODE_DEFAULT = 0xFFFF
+} OMX_AUDIO_AC3_KARAOKE_MODE;
+
+
+typedef struct QOMX_AUDIO_PARAM_AC3PP
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_AUDIO_AC3_CHANNEL_ROUTING eChannelRouting[8];
+ OMX_AUDIO_AC3_COMPRESSION_MODE eCompressionMode;
+ OMX_AUDIO_AC3_STEREO_MODE eStereoMode;
+ OMX_AUDIO_AC3_DUAL_MONO_MODE eDualMonoMode;
+ OMX_U32 usPcmScale;
+ OMX_U32 usDynamicScaleBoost;
+ OMX_U32 usDynamicScaleCut;
+ OMX_AUDIO_AC3_KARAOKE_MODE eKaraokeMode;
+} QOMX_AUDIO_PARAM_AC3PP;
+
+
+/**
+ * Stream info data
+ *
+ * STRUCT MEMBERS:
+ * sessionId : session Id for alsa to route data
+ */
+typedef struct QOMX_AUDIO_STREAM_INFO_DATA {
+ OMX_U8 sessionId;
+} QOMX_AUDIO_STREAM_INFO_DATA;
+
+
+/**
+ * Record Path
+ *
+ * STRUCT MEMBERS:
+ * recPath : Record Path for encoding
+ */
+typedef enum{
+
+QOMX_AUDIO_VOICE_TX,
+QOMX_AUDIO_VOICE_RX,
+QOMX_AUDIO_VOICE_MIXED,
+
+} QOMX_AUDIO_VOICERECORDMODETYPE;
+typedef struct QOMX_AUDIO_CONFIG_VOICERECORDTYPE {
+
+OMX_U32 nSize;
+OMX_VERSIONTYPE nVersion;
+QOMX_AUDIO_VOICERECORDMODETYPE eVoiceRecordMode;
+} QOMX_AUDIO_CONFIG_VOICERECORDTYPE;
+
+/* Enum for mapping dual-mono contents to left and right channels */
+typedef enum OMX_AUDIO_DUAL_MONO_CHANNEL_CONFIG {
+ OMX_AUDIO_DUAL_MONO_MODE_FL_FR,/* 1st SCE to left & right */
+ OMX_AUDIO_DUAL_MONO_MODE_SL_SR,/* 2nd SCE to left & right */
+ OMX_AUDIO_DUAL_MONO_MODE_SL_FR,/* 2nd SCE to left, 1st SCE to right */
+ OMX_AUDIO_DUAL_MONO_MODE_FL_SR,/* 1st SCE to left, 2nd SCE to right default */
+ OMX_AUDIO_DUAL_MONO_MODE_DEFAULT = OMX_AUDIO_DUAL_MONO_MODE_FL_SR,
+ OMX_AUDIO_DUAL_MONO_MODE_INVALID = -1
+} OMX_AUDIO_DUAL_MONO_CHANNEL_CONFIG;
+
+/************************************/
+/* DAK */
+/*************************************/
+
+/** this is the list of custom vendor index */
+typedef enum OMX_INDEX_DAK_TYPE {
+ OMX_IndexConfigDAK_BUNDLE = OMX_IndexVendorStartUnused /*0x7F000000*/, /**< reference: OMX_DAK_CONFIG_BUNDLETYPE */
+ OMX_IndexConfigDAK_M2S, /**< reference: OMX_DAK_CONFIG_M2STYPE */
+ OMX_IndexConfigDAK_SSE, /**< reference: OMX_DAK_CONFIG_SSETYPE */
+ OMX_IndexConfigDAK_SLC, /**< reference: OMX_DAK_CONFIG_SLCTYPE */
+ OMX_IndexConfigDAK_VOL, /**< reference: OMX_DAK_CONFIG_VOLTYPE */
+ OMX_IndexConfigDAK_NB, /**< reference: OMX_DAK_CONFIG_NBTYPE */
+ OMX_IndexConfigDAK_GEQ, /**< reference: OMX_DAK_CONFIG_GEQTYPE */
+ OMX_IndexConfigDAK_MSR, /**< reference: OMX_DAK_CONFIG_MSRTYPE */
+ OMX_IndexConfigDAK_HFE, /**< reference: OMX_DAK_CONFIG_HFETYPE */
+ OMX_IndexConfigDAK_FADE, /**< reference: OMX_DAK_CONFIG_FADETYPE */
+ OMX_IndexConfigDAK_SEQ, /**< reference: OMX_DAK_CONFIG_SEQTYPE */
+
+} OMX_INDEX_DAK_TYPE;
+
+
+/** Dolby Audio Kernel TDAS bundle */
+typedef struct OMX_DAK_CONFIG_BUNDLETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nDAK_Version; /**< Dolby Audio Kernel version information */
+ OMX_U32 nDAK_Revision; /**< Dolby Audio Kernel revision information */
+ OMX_U8 nLfeMixLevel; /**< level at which the LFE channel is mixed into the output audio */
+ OMX_U8 nSampleRateIndex; /**< Output sample rate */
+ OMX_U8 nInChans; /**< Channel format of input audio */
+ OMX_U8 nInMatrix; /**< L/R mixing specification for stereo audio input */
+ OMX_U8 nBypass; /**< Audio Processing bypass */
+ OMX_U8 nRateMultipier; /**< Sample-rate multiplier (output with respect to input) */
+ OMX_U8 nInChanFormat; /**< Input/Output channel format */
+ OMX_U8 nMsrMaxProfile; /**< Maximum number of virtual rendering channels in Mobile Surround */
+ OMX_BOOL bPortablemodeEnable; /**< Enable or disable Pulse Portable Mode */
+ OMX_S16 nPotablemodeGain; /**< Send the Portable Mode gain value from the Pulse decoder */
+ OMX_U8 nORL; /**< Device specific target signal level (output reference level) */
+ OMX_BOOL bPulsedownmixEnable; /**< Enable the Pulse Downmix compensation */
+ OMX_S8 nPulsedownmixAtten; /**< Attenuation value that Pulse is currently applying */
+ OMX_U8 nOutChans; /**< Channel format of output audio */
+
+} OMX_DAK_CONFIG_BUNDLETYPE;
+
+/** Dolby Audio Kernel Mono-to-Stereo Creator */
+typedef struct OMX_DAK_CONFIG_M2STYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Mono-to-Stereo Creator enable */
+ OMX_BOOL bDetector; /**< Stereo detector status */
+} OMX_DAK_CONFIG_M2STYPE;
+
+/** Dolby Audio Kernel Sound Space Expander */
+typedef struct OMX_DAK_CONFIG_SSETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Sound Space Expander enable */
+ OMX_U8 nWidth; /**< Width of expansion effect */
+ OMX_U8 nSpkMode; /**< Speaker Mode */
+} OMX_DAK_CONFIG_SSETYPE;
+
+/** Dolby Audio Kernel Sound Level Controller */
+typedef struct OMX_DAK_CONFIG_SLCTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Sound Level Controller enable */
+ OMX_U8 nLevel; /**< Source audio RMS level */
+ OMX_U8 nDepth; /**< Depth of effect */
+} OMX_DAK_CONFIG_SLCTYPE;
+
+/** Dolby Audio Kernel Volume */
+typedef struct OMX_DAK_CONFIG_VOLTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Volume enable */
+ OMX_U8 nGainType; /**< Linear/Logarithmic audio scaling */
+ OMX_U8 nInternalGain; /**< Audio volume scale */
+ OMX_U8 nExternalGain; /**< Audio volume scale applied by external volume control */
+ OMX_S8 nBalance; /**< L/R panning for output audio */
+ OMX_BOOL bMute; /**< Audio Mute */
+} OMX_DAK_CONFIG_VOLTYPE;
+
+/** Dolby Audio Kernel Natural Bass */
+typedef struct OMX_DAK_CONFIG_NBTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Natural Bass enable */
+ OMX_U8 nCutoff; /**< Speakers/headphones lower cutoff frequency */
+ OMX_U8 nBoost; /**< Strength of effect */
+ OMX_U8 nLevel; /**< Maximum output level capability of speakers/headphones */
+} OMX_DAK_CONFIG_NBTYPE;
+
+/** Dolby Audio Kernel Graphic EQ */
+typedef struct OMX_DAK_CONFIG_GEQTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Graphic EQ enable */
+ OMX_U8 nNbands; /**< Number of frequency bands */
+ OMX_S8 nPreamp; /**< Global attenuation to apply prior to band level adjustment */
+ OMX_U8 nMaxboost; /**< Maximum absolute boost with respect to the source audio */
+ OMX_S8 nBand1; /**< Boost/cut for 1st frequency band */
+ OMX_S8 nBand2; /**< Boost/cut for 2nd frequency band */
+ OMX_S8 nBand3; /**< Boost/cut for 3rd frequency band */
+ OMX_S8 nBand4; /**< Boost/cut for 4th frequency band */
+ OMX_S8 nBand5; /**< Boost/cut for 5th frequency band */
+ OMX_S8 nBand6; /**< Boost/cut for 6th frequency band */
+ OMX_S8 nBand7; /**< Boost/cut for 7th frequency band */
+} OMX_DAK_CONFIG_GEQTYPE;
+
+/** Dolby Audio Kernel, Mobile Surround and Surround Upmixer */
+typedef struct OMX_DAK_CONFIG_MSRTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bMsrEnable; /**< Mobile Surround enable */
+ OMX_U8 nMsrRoom; /**< Room Size control */
+ OMX_U8 nMsrBright; /**< Brightness control */
+ OMX_BOOL bMupEnable; /**< Mobile Surround Upmixer enable */
+} OMX_DAK_CONFIG_MSRTYPE;
+
+/** Dolby Audio Kernel High Frequency Enhancer */
+typedef struct OMX_DAK_CONFIG_HFETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< High Frequency Enhancer enable */
+ OMX_U8 nDepth; /**< Strength of effect */
+} OMX_DAK_CONFIG_HFETYPE;
+
+/** Dolby Audio Kernel Fade */
+typedef struct OMX_DAK_CONFIG_FADETYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Fade enable */
+ OMX_U8 nTarget; /**< Target fade level */
+ OMX_U16 nTime; /**< Fade time interval */
+} OMX_DAK_CONFIG_FADETYPE;
+
+/** Dolby Audio Kernel Speaker EQ */
+typedef struct OMX_DAK_CONFIG_SEQTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL bEnable; /**< Speaker EQ enable */
+ OMX_S8 nLeftGainDB; /**< Additional gain for Left channel */
+ OMX_S8 nRightGainDB; /**< Additional gain for Right channel */
+ OMX_U8 nCoef48000Size; /**< Length of the block of coefficients for 48KHz Sampling Rate case */
+ OMX_PTR pCoef48000; /**< Pointer to the block of coefficients for the 48KHz case */
+ OMX_U8 nCoef44100Size; /**< Length of the block of coefficients for 44.1KHz Sampling Rate case */
+ OMX_PTR pCoef44100; /**< Pointer to the block of coefficients for the 44.1KHz case */
+ OMX_U8 nCoef32000Size; /**< Length of the block of coefficients for 32KHz Sampling Rate case */
+ OMX_PTR pCoef32000; /**< Pointer to the block of coefficients for the 32KHz case */
+ OMX_U8 nCoef24000Size; /**< Length of the block of coefficients for 24KHz Sampling Rate case */
+ OMX_PTR pCoef24000; /**< Pointer to the block of coefficients for the 24KHz case */
+
+} OMX_DAK_CONFIG_SEQTYPE;
+
+
+typedef enum OMX_AUDIO_CHANNELTYPE_EXTENSION {
+ OMX_AUDIO_ChannelTS = OMX_AUDIO_ChannelVendorStartUnused, /**< Top Surround */
+ OMX_AUDIO_ChannelCVH /**< Central Vertical Height */
+} OMX_AUDIO_CHANNELTYPE_EXTENSION;
+
+/**
+ * DUAL-MONO type
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eChannelConfig : Enum for channel config
+ *
+ */
+typedef struct QOMX_AUDIO_CONFIG_DUALMONOTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_AUDIO_DUAL_MONO_CHANNEL_CONFIG eChannelConfig;
+} QOMX_AUDIO_CONFIG_DUALMONOTYPE;
+
+typedef struct QOMX_AUDIO_PARAM_ALACTYPE {
+ OMX_U32 nSize; /* Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /* Port that this structure applies to */
+ OMX_BOOL bBytesStreamMode; /*enable byte stream mode*/
+ OMX_U32 nFrameLength; /* Frames per packet when no explicit frames per packet setting is present in the packet header */
+ OMX_U8 nCompatibleVersion; /* Indicates the compatible version */
+ OMX_U8 nBitDepth; /* Bit depth of the source PCM data */
+ OMX_U8 nPb; /* Tuning Parameter; currently not used */
+ OMX_U8 nMb; /* Tuning Parameter; currently not used */
+ OMX_U8 nKb; /* Tuning Parameter; currently not used */
+ OMX_U8 nChannels; /* Number of channels for multichannel decoding */
+ OMX_U16 nMaxRun; /* Currently not used */
+ OMX_U32 nMaxFrameBytes; /* Max size of an Apple Lossless packet within the encoded stream */
+ OMX_U32 nAvgBitRate; /* Average bit rate in bits per second of the Apple Lossless stream */
+ OMX_U32 nSampleRate; /* Number of samples per second in Hertz */
+ OMX_U32 nChannelLayoutTag; /*Indicates whether channel layout information is present in the bitstream */
+} QOMX_AUDIO_PARAM_ALACTYPE;
+
+typedef struct QOMX_AUDIO_PARAM_APETYPE {
+ OMX_U32 nSize; /* Size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /* Port that this structure applies to */
+ OMX_BOOL bBytesStreamMode; /*enable byte stream mode*/
+ OMX_U16 nCompatibleVersion; /* Indicates the compatible version */
+ OMX_U16 nCompressionLevel; /* The compression level present in the encoded packet */
+ OMX_U32 nFormatFlags; /* Reserved parameter for future use */
+ OMX_U32 nBlocksPerFrame; /* Indicates the number of audio blocks in one frame present in the encoded packet header */
+ OMX_U32 nFinalFrameBlocks; /* Indicates the number of audio blocks in the final frame present in the encoded packet header */
+ OMX_U32 nTotalFrames; /* Indicates the total number of frames */
+ OMX_U16 nBitsPerSample; /* Bit depth of the source PCM data */
+ OMX_U16 nChannels; /* Number of channels for decoding */
+ OMX_U32 nSampleRate; /* Samples per second in Hertz */
+ OMX_U32 nSeekTablePresent; /* Flag to indicate if seek table is present or not */
+} QOMX_AUDIO_PARAM_APETYPE;
+
+typedef struct QOMX_AUDIO_PARAM_FLAC_DEC_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nChannels;
+ OMX_U32 nSampleRate;
+ OMX_U32 nBitsPerSample;
+ OMX_U32 nMinBlkSize;
+ OMX_U32 nMaxBlkSize;
+ OMX_U32 nMinFrmSize;
+ OMX_U32 nMaxFrmSize;
+} QOMX_AUDIO_PARAM_FLAC_DEC_TYPE;
+
+typedef struct QOMX_AUDIO_PARAM_DSD_TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bBytesStreamMode; /*enable byte stream mode*/
+ OMX_U32 nSampleRate;
+ OMX_U32 nOutSamplePerCh;
+ OMX_U32 nChannels;
+ OMX_U32 nBitsPerSample;
+} QOMX_AUDIO_PARAM_DSD_TYPE;
+
+enum {
+ kKeyIndexAlacFrameLength = 0,
+ kKeyIndexAlacCompatibleVersion = 4,
+ kKeyIndexAlacBitDepth = 5,
+ kKeyIndexAlacPb = 6,
+ kKeyIndexAlacMb = 7,
+ kKeyIndexAlacKb = 8,
+ kKeyIndexAlacNumChannels = 9,
+ kKeyIndexAlacMaxRun = 10,
+ kKeyIndexAlacMaxFrameBytes = 12,
+ kKeyIndexAlacAvgBitRate = 16,
+ kKeyIndexAlacSamplingRate = 20,
+ kKeyIndexAlacChannelLayoutTag = 24,
+ kKeyIndexAlacMax = kKeyIndexAlacChannelLayoutTag,
+};
+
+enum {
+ kKeyIndexApeCompatibleVersion = 0,
+ kKeyIndexApeCompressionLevel = 2,
+ kKeyIndexApeFormatFlags = 4,
+ kKeyIndexApeBlocksPerFrame = 8,
+ kKeyIndexApeFinalFrameBlocks = 12,
+ kKeyIndexApeTotalFrames = 16,
+ kKeyIndexApeBitsPerSample = 20,
+ kKeyIndexApeNumChannels = 22,
+ kKeyIndexApeSampleRate = 24,
+ kKeyIndexApeSeekTablePresent = 28,
+ kKeyIndexApeMax = kKeyIndexApeSeekTablePresent,
+};
+
+enum {
+ APE_COMPRESSION_LEVEL_FAST = 1000,
+ APE_COMPRESSION_LEVEL_NORMAL = 2000,
+ APE_COMPRESSION_LEVEL_HIGH = 3000,
+ APE_COMPRESSION_LEVEL_EXTRA_HIGH = 4000,
+ APE_COMPRESSION_LEVEL_INSANE = 5000,
+};
+
+#if defined( __cplusplus )
+}
+#endif /* end of macro __cplusplus */
+
+#endif /* end of macro __H_QOMX_AUDIOEXTENSIONS_H__ */
diff --git a/msmcobalt/mm-core/inc/QOMX_AudioIndexExtensions.h b/msmcobalt/mm-core/inc/QOMX_AudioIndexExtensions.h
new file mode 100644
index 0000000..34e4667
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_AudioIndexExtensions.h
@@ -0,0 +1,85 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 2015 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 QOMX_AudioIndexExtensions.h
+ This module contains the index extensions for Audio
+
+*//*========================================================================*/
+
+
+#ifndef __H_QOMX_AUDIOINDEXEXTENSIONS_H__
+#define __H_QOMX_AUDIOINDEXEXTENSIONS_H__
+
+/*========================================================================
+
+ INCLUDE FILES FOR MODULE
+
+========================================================================== */
+#include <OMX_Core.h>
+
+/*========================================================================
+
+ DEFINITIONS AND DECLARATIONS
+
+========================================================================== */
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif /* end of macro __cplusplus */
+
+/**
+ * Enumeration used to define Qualcomm's vendor extensions for
+ * audio. The audio extensions occupy a range of
+ * 0x7F100000-0x7F1FFFFF, inclusive.
+ */
+typedef enum QOMX_AUDIO_EXTENSIONS_INDEXTYPE
+{
+ QOMX_IndexParamAudioAmrWbPlus = 0x7F200000, /**< "OMX.Qualcomm.index.audio.amrwbplus" */
+ QOMX_IndexParamAudioWma10Pro = 0x7F200001, /**< "OMX.Qualcomm.index.audio.wma10pro" */
+ QOMX_IndexParamAudioSessionId = 0x7F200002, /**< "OMX.Qualcomm.index.audio.sessionId" */
+ QOMX_IndexParamAudioVoiceRecord = 0x7F200003, /**< "OMX.Qualcomm.index.audio.VoiceRecord" */
+ QOMX_IndexConfigAudioDualMono = 0x7F200004, /**< "OMX.Qualcomm.index.audio.dualmono" */
+ QOMX_IndexParamAudioAc3 = 0x7F200005, /**< "OMX.Qualcomm.index.audio.ac3" */
+ QOMX_IndexParamAudioAc3PostProc = 0x7F200006, /**< "OMX.Qualcomm.index.audio.postproc.ac3" */
+ QOMX_IndexParamAudioAacSelectMixCoef = 0x7F200007, /** "OMX.Qualcomm.index.audio.aac_sel_mix_coef**/
+ QOMX_IndexParamAudioAlac = 0x7F200008, /** "OMX.Qualcomm.index.audio.alac" */
+ QOMX_IndexParamAudioApe = 0x7F200009, /** "OMX.Qualcomm.index.audio.ape" */
+ QOMX_IndexParamAudioFlacDec = 0x7F20000A, /** "OMX.Qualcomm.index.audio.flacdec**/
+ QOMX_IndexParamAudioDsdDec = 0x7F20000B, /** "OMX.Qualcomm.index.audio.Dsddec**/
+ QOMX_IndexParamAudioUnused = 0x7F2FFFFF
+} QOMX_AUDIO_EXTENSIONS_INDEXTYPE;
+
+#if defined( __cplusplus )
+}
+#endif /* end of macro __cplusplus */
+
+#endif /* end of macro __H_QOMX_AUDIOINDEXEXTENSIONS_H__ */
diff --git a/msmcobalt/mm-core/inc/QOMX_CoreExtensions.h b/msmcobalt/mm-core/inc/QOMX_CoreExtensions.h
new file mode 100644
index 0000000..9addb90
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_CoreExtensions.h
@@ -0,0 +1,164 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 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 __H_QOMX_COREEXTENSIONS_H__
+#define __H_QOMX_COREEXTENSIONS_H__
+
+
+
+/*========================================================================
+
+ INCLUDE FILES FOR MODULE
+
+========================================================================== */
+#include <OMX_Core.h>
+
+/*========================================================================
+
+ DEFINITIONS AND DECLARATIONS
+
+========================================================================== */
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif /* end of macro __cplusplus */
+
+/**
+ * Qualcom vendor extensions.
+ */
+#define OMX_QCOM_INDEX_PARAM_INDEXEXTRADATA "OMX.QCOM.index.param.IndexExtraData" /**< reference: QOMX_INDEXEXTRADATATYPE */
+#define OMX_QCOM_INDEX_PARAM_HELDBUFFERCOUNT "OMX.QCOM.index.param.HeldBufferCount" /**< reference: QOMX_HELDBUFFERCOUNTTYPE */
+
+/**
+ * Buffer header nFlags field extension.
+ *
+ * The source of a stream sets the TIMESTAMPINVALID flag to
+ * indicate that the buffer header nTimeStamp field does not
+ * hold valid timestamp information. The component that updates
+ * the nTimeStamp field to reflect a valid timestamp shall clear
+ * this flag.
+ */
+#define QOMX_BUFFERFLAG_TIMESTAMPINVALID 0x80000000
+
+/**
+ * Buffer header nFlags field extension.
+ *
+ * The READONLY flag is set when the component emitting the
+ * buffer on an output port identifies the buffer's contents to
+ * be read-only. The IL client or input port that receives a
+ * filled read-only buffer cannot alter the contents of the
+ * buffer. This flag can be cleared by the component when the
+ * emptied buffer is returned to it.
+ */
+#define QOMX_BUFFERFLAG_READONLY 0x40000000
+
+/**
+ * Buffer header nFlags field extension.
+ *
+ * The ENDOFSUBFRAME flag is an optional flag that is set by an
+ * output port when the last byte that a buffer payload contains
+ * is an end-of-subframe. Any component that implements setting
+ * the ENDOFSUBFRAME flag on an output port shall set this flag
+ * for every buffer sent from the output port containing an
+ * end-of-subframe.
+ *
+ * A subframe is defined by the next level of natural
+ * partitioning in a logical unit for a given format. For
+ * example, a subframe in an H.264 access unit is defined as the
+ * "network abstraction layer" unit, or NAL unit.
+ */
+#define QOMX_BUFFERFLAG_ENDOFSUBFRAME 0x20000000
+
+/**
+ * A component sends this error to the IL client (via the EventHandler callback)
+ * in the event that application of a config or parameter has failed some time
+ * after the return of OMX_SetConfig or OMX_SetParameter. This may happen when a
+ * component transitions between states and discovers some incompatibility
+ * between multiple settings. Configuration indicies sent via extra data may also
+ * fail when set to a down stream component. The index that failed will be
+ * included as the nData2 parameter of the EventHandler callback.
+ */
+#define QOMX_ErrorAsyncIndexFailed (OMX_ErrorVendorStartUnused+1)
+
+/* In some scenarios there may be a possibilty to run out of the storage space
+ * and components may want to notify this error to IL client to take appropriate
+ * action by the IL client.
+ *
+ * For example, In recording scenario, MUX component can know the available
+ * space in the recording media and can compute peridically to accommodate the
+ * meta data before we reach to a stage where we end up no space to write even
+ * the meta data. When the space limit reached in recording media, MUX component
+ * would like to notify the IL client with QOMX_ErrorSpaceLimitReached.
+ * After this error all the buffers that are returned will have nFilledLen
+ * unchanges i.e not consumed.
+ */
+#define QOMX_ErrorStorageLimitReached (OMX_ErrorVendorStartUnused + 2)
+
+/**
+ * This structure is used to enable/disable the generation or
+ * consumption of the QOMX_ExtraDataOMXIndex extra data type for
+ * the specified OpenMax index.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * bEnabled : Enable/Disable the extra data processing
+ * nIndex : The index associated with the extra data
+ */
+typedef struct QOMX_INDEXEXTRADATATYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnabled;
+ OMX_INDEXTYPE nIndex;
+} QOMX_INDEXEXTRADATATYPE;
+
+/**
+ * This structure is used to indicate the maximum number of buffers
+ * that a port will hold during data flow.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nHeldBufferCount : Read-only, maximum number of buffers that will be held
+ */
+typedef struct QOMX_HELDBUFFERCOUNTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nHeldBufferCount;
+} QOMX_HELDBUFFERCOUNTTYPE;
+
+#if defined( __cplusplus )
+}
+#endif /* end of macro __cplusplus */
+
+#endif /* end of macro __H_QOMX_COREEXTENSIONS_H__ */
diff --git a/msmcobalt/mm-core/inc/QOMX_FileFormatExtensions.h b/msmcobalt/mm-core/inc/QOMX_FileFormatExtensions.h
new file mode 100644
index 0000000..c88bec2
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_FileFormatExtensions.h
@@ -0,0 +1,155 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 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 __QOMX_FILE_FORMAT_EXTENSIONS_H__
+#define __QOMX_FILE_FORMAT_EXTENSIONS_H__
+
+/*============================================================================
+*//** @file QOMX_FileFormatExtensions.h
+ This header contains constants and type definitions that specify the
+ extensions added to the OpenMAX Vendor specific APIs.
+*//*========================================================================*/
+
+/*============================================================================
+ Edit History
+
+when who what, where, why
+-------- --- -------------------------------------------------------
+
+============================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+#include "OMX_Core.h"
+
+
+/* :OMX.QCOM.index.param.container.info*/
+#define QOMX_QcomIndexParamContainerInfo 0x7F000009
+
+/**<OMX.Qualcomm.index.video.param.encrypttypeconfigparameters*/
+#define QOMX_FilemuxIndexEncryptionTypeConfigParameters 0x7F00000A
+
+#define QOMX_INDEX_CONTAINER_INFO_STRING "QOMX.Qualcomm.index.param.containerinfo"
+#define OMX_QCOM_INDEX_FILE_FORMAT "OMX.QCOM.index.config.FileFormat"
+#define QOMX_INDEX_CONFIG_ENCRYPT_TYPE "QOMX.Qualcomm.index.config.EncryptType"
+
+/**-----------------------------------------------------------------------------
+ OMX.QCOM.index.param.container.info
+--------------------------------------------------------------------------------
+*/
+
+typedef enum QOMX_CONTAINER_FORMATTYPE {
+ QOMX_FORMAT_RAW,
+ QOMX_FORMAT_MP4,
+ QOMX_FORMAT_3GP,
+ QOMX_FORMAT_3G2,
+ QOMX_FORMAT_AMC,
+ QOMX_FORMAT_SKM,
+ QOMX_FORMAT_K3G,
+ QOMX_FORMAT_VOB,
+ QOMX_FORMAT_AVI,
+ QOMX_FORMAT_ASF,
+ QOMX_FORMAT_RM ,
+ QOMX_FORMAT_MPEG_ES,
+ QOMX_FORMAT_DIVX,
+ QOMX_FORMATMPEG_TS,
+ QOMX_FORMAT_QT,
+ QOMX_FORMAT_M4A,
+ QOMX_FORMAT_MP3,
+ QOMX_FORMAT_WAVE,
+ QOMX_FORMAT_XMF,
+ QOMX_FORMAT_AMR,
+ QOMX_FORMAT_AAC,
+ QOMX_FORMAT_EVRC,
+ QOMX_FORMAT_QCP,
+ QOMX_FORMAT_SMF,
+ QOMX_FORMAT_OGG,
+ QOMX_FORMAT_BMP,
+ QOMX_FORMAT_JPG,
+ QOMX_FORMAT_JPG2000
+}QOMX_CONTAINER_FORMATTYPE;
+
+typedef struct QOMX_CONTAINER_INFOTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ QOMX_CONTAINER_FORMATTYPE eFmtType;
+} QOMX_CONTAINER_INFOTYPE;
+
+typedef enum QOMX_FILEFORMATTYPE {
+ QOMX_FileFormatNone, /**< no file format naming convention is followed. */
+ QOMX_FileFormatDCF, /**< DCF file naming convention. */
+ QOMX_FileFormatMax = 0x7FFFFFFF
+} QOMX_FILEFORMATTYPE;
+
+/** QOMX_CONFIG_FILEFORMATTYPE is used to determine how the file writer will interpret
+the provided content URI and whether it will increment the index of the file name. */
+typedef struct QOMX_CONFIG_FILEFORMATTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_U32 nPortIndex; /**< port that this structure applies to */
+ QOMX_FILEFORMATTYPE eFileFormat; /** file format type */
+} QOMX_CONFIG_FILEFORMATTYPE;
+
+/**The QOMX_RECORDINGSTATISTICSINTERVALTYPE structure is used to enable
+IL client to indicate the interval of the statistics notification to file mux
+component. Time interval will indicate the frequency(in ms) when client needs
+the statistics data*/
+typedef struct QOMX_RECORDINGSTATISTICSINTERVALTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/**< OMX specification version information */
+ OMX_TICKS interval;/**< specifies the time(milliseconds) between updates */
+ }QOMX_RECORDINGSTATISTICSINTERVALTYPE;
+
+/**QOMX_RECORDINGSTATISTICSTYPE indicates the current recording
+time and space statistics of this session, which can be used by client to
+identify current status of recorded data in milliseconds and bytes */
+typedef struct QOMX_RECORDINGSTATISTICSTYPE {
+ OMX_U32 nSize;/**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion;/**< OMX specification version information */
+ OMX_TICKS nRecordedTime; /** duration that we already recorded*/
+ OMX_TICKS nTimeCanRecord;/** the time we can record at the same bitrate*/
+ OMX_U64 nSpaceConsumed;/** space that consumed in bytes*/
+ OMX_U64 nSpaceLeft;/** space left in bytes*/
+} QOMX_RECORDINGSTATISTICSTYPE;
+
+/**QOMX_ENCRYPT_TYPE indicates the type of encryption */
+typedef enum QOMX_ENCRYPT_TYPE {
+ QOMX_ENCRYPT_TYPE_HDCP,
+ QOMX_ENCRYPT_TYPE_INVALID
+}QOMX_ENCRYPT_TYPE;
+
+/**QOMX_ENCRYPTIONTYPE indicates the encrypt type */
+typedef struct QOMX_ENCRYPTIONTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_BOOL nStreamEncrypted; /** stream is encrypted or not */
+ QOMX_ENCRYPT_TYPE nType; /** type of Encryption */
+ OMX_U32 nEncryptVersion; /** Encrypt version */
+} QOMX_ENCRYPTIONTYPE;
+#endif /*__QOMX_FILE_FORMAT_EXTENSIONS_H__*/
diff --git a/msmcobalt/mm-core/inc/QOMX_IVCommonExtensions.h b/msmcobalt/mm-core/inc/QOMX_IVCommonExtensions.h
new file mode 100644
index 0000000..e9f1fd5
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_IVCommonExtensions.h
@@ -0,0 +1,486 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2011-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 __H_QOMX_IVCOMMONEXTENSIONS_H__
+#define __H_QOMX_IVCOMMONEXTENSIONS_H__
+
+/*========================================================================
+
+*//** @file QOMX_CommonExtensions.h
+
+@par FILE SERVICES:
+ common extensions API for OpenMax IL.
+
+ This file contains the description of the Qualcomm OpenMax IL
+ common extention interface, through which the IL client and OpenMax
+ components can access additional capabilities.
+
+*//*====================================================================== */
+
+
+/*========================================================================
+
+ INCLUDE FILES FOR MODULE
+
+========================================================================== */
+#include <OMX_Core.h>
+
+/*========================================================================
+
+ DEFINITIONS AND DECLARATIONS
+
+========================================================================== */
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif /* end of macro __cplusplus */
+
+/* IV common extension strings */
+#define OMX_QCOM_INDEX_CONFIG_MEDIAINFO "OMX.QCOM.index.config.mediainfo" /**< reference: QOMX_MEDIAINFOTYPE */
+#define OMX_QCOM_INDEX_CONFIG_CONTENTURI "OMX.QCOM.index.config.contenturi" /**< reference: OMX_PARAM_CONTENTURITYPE */
+#define OMX_QCOM_INDEX_PARAM_IMAGESIZECONTROL "OMX.Qualcomm.index.param.ImageSizeControl" /**< reference: QOMX_IMAGE_IMAGESIZECONTROLTYPE */
+#define OMX_QCOM_INDEX_CONFIG_PAUSEPORT "OMX.QCOM.index.config.PausePort" /**< reference: QOMX_CONFIG_PAUSEPORTTYPE */
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give width in pixels */
+#define OMX_QCOM_INDEX_PARAM_FRAMEWIDTHRANGESUPPORTED "OMX.QCOM.index.param.FrameWidthRangeSupported"
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give height in pixels */
+#define OMX_QCOM_INDEX_PARAM_FRAMEHEIGHTRANGESUPPORTED "OMX.QCOM.index.param.FrameHeightRangeSupported"
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give the number of macroblocks per
+ * frame. */
+#define OMX_QCOM_INDEX_PARAM_MACROBLOCKSPERFRAMERANGESUPPORTED "OMX.QCOM.index.param.MacroblocksPerFrameRangeSupported"
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give the number of macroblocks per
+ * second. */
+#define OMX_QCOM_INDEX_PARAM_MACROBLOCKSPERSECONDRANGESUPPORTED "OMX.QCOM.index.param.MacroblocksPerSecondRangeSupported"
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give frame rate in frames per second
+ * in Q16 format. */
+#define OMX_QCOM_INDEX_PARAM_FRAMERATERANGESUPPORTED "OMX.QCOM.index.param.FrameRateRangeSupported"
+
+#define OMX_QCOM_INDEX_PARAM_PLANEDEFINITION "OMX.QCOM.index.param.PlaneDefinition" /** reference: QOMX_PLANEDEFINITIONTYPE */
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give the crop width in pixels */
+#define OMX_QOMX_INDEX_PARAM_CROPWIDTHRANGESUPPORTED "OMX.QCOM.index.param.CropWidthRangeSupported"
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give the crop height in pixels */
+#define OMX_QOMX_INDEX_PARAM_CROPHEIGHTRANGESUPPORTED "OMX.QCOM.index.param.CropHeightRangeSupported"
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give the digital zoom factor on width
+ * in Q16 format. */
+#define OMX_QCOM_INDEX_PARAM_DIGITALZOOMWIDTHRANGESUPPORTED "OMX.QCOM.index.param.DigitalZoomWidthRangeSupported"
+
+/** reference: QOMX_URANGETYPE
+ * nMin, nMax, nStepSize give the digital zoom factor on height
+ * in Q16 format. */
+#define OMX_QCOM_INDEX_PARAM_DIGITALZOOMHEIGHTRANGESUPPORTED "OMX.QCOM.index.param.DigitalZoomHeightRangeSupported"
+
+ // new externsions for vidpp
+#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION "OMX.QCOM.index.config.activeregiondetection"
+#define OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS "OMX.QCOM.index.config.activeregiondetectionstatus"
+#define OMX_QCOM_INDEX_CONFIG_SCALING_MODE "OMX.QCOM.index.config.scalingmode"
+#define OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION "OMX.QCOM.index.config.noisereduction"
+#define OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT "OMX.QCOM.index.config.imageenhancement"
+/**
+ * Enumeration defining the extended uncompressed image/video
+ * formats.
+ *
+ * ENUMS:
+ * YVU420PackedSemiPlanar : Buffer containing all Y, and then V and U
+ * interleaved.
+ * YVU420PackedSemiPlanar32m4ka : YUV planar format, similar to the
+ * YVU420PackedSemiPlanar format, but with the
+ * following restrictions:
+ *
+ * 1. The width and height of both plane must
+ * be a multiple of 32 texels.
+ *
+ * 2. The base address of both planes must be
+ * aligned to a 4kB boundary.
+ *
+ * YUV420PackedSemiPlanar16m2ka : YUV planar format, similar to the
+ * YUV420PackedSemiPlanar format, but with the
+ * following restrictions:
+ *
+ * 1. The width of the luma plane must be a
+ * multiple of 16 pixels.
+ *
+ * 2. The address of both planes must be
+ * aligned to a 2kB boundary.
+ *
+ * YUV420PackedSemiPlanar64x32Tile2m8ka : YUV planar format, similar to the
+ * YUV420PackedSemiPlanar format, but with the
+ * following restrictions:
+ *
+ * 1. The data is laid out in a 4x2 MB tiling
+ * memory structure
+ *
+ * 2. The width of each plane is a multiple of
+ * 2 4x2 MB tiles.
+ *
+ * 3. The height of each plan is a multiple of
+ * a 4x2 MB tile.
+ *
+ * 4. The base address of both planes must be
+ * aligned to an 8kB boundary.
+ *
+ * 5. The tiles are scanned in the order
+ * defined in the MFCV5.1 User's Manual.
+ */
+typedef enum QOMX_COLOR_FORMATTYPE
+{
+ QOMX_COLOR_FormatYVU420PackedSemiPlanar = 0x7F000001,
+ QOMX_COLOR_FormatYVU420PackedSemiPlanar32m4ka,
+ QOMX_COLOR_FormatYUV420PackedSemiPlanar16m2ka,
+ QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka,
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+} QOMX_COLOR_FORMATTYPE;
+
+typedef enum QOMX_MEDIAINFOTAGTYPE {
+ QOMX_MediaInfoTagVersion, /**< OMX_VERSIONTYPE. Version of the standard specifying the media information.*/
+ QOMX_MediaInfoTagUID, /**< OMX_U8*. Unique ID of the media data, ie image unique ID.*/
+ QOMX_MediaInfoTagDescription, /**< OMX_U8*. Comments about the media.*/
+ QOMX_MediaInfoTagTitle, /**< OMX_U8*. Title of the media.*/
+ QOMX_MediaInfoTagAuthor, /**< OMX_U8*. Author of the media.*/
+ QOMX_MediaInfoTagCopyright, /**< OMX_U8*. Copyright information.*/
+ QOMX_MediaInfoTagTrackNum, /**< OMX_U32. Track number.*/
+ QOMX_MediaInfoTagGenre, /**< OMX_U8*. The genre of the media.*/
+ QOMX_MediaInfoTagEquipmentMake, /**< OMX_U8*. Manufacturer of recording equipment.*/
+ QOMX_MediaInfoTagEquipmentModel,/**< OMX_U8*. Model or name of the recording equipment.*/
+ QOMX_MediaInfoTagSoftware, /**< OMX_U8*. Name and version of the software or firmware of the device generating the media.*/
+ QOMX_MediaInfoTagAssociatedFile,/**< OMX_U8*. The name of the file related to the media. For example, an audio file related to an image file.*/
+ QOMX_MediaInfoTagResolution, /**< QOMX_RESOLUTIONTYPE. Number of pixels per resolution unit.*/
+ QOMX_MediaInfoTagDateCreated, /**< QOMX_DATESTAMPTYPE. Date when media was created.*/
+ QOMX_MediaInfoTagTimeCreated, /**< QOMX_TIMESTAMPTYPE. Time when media was created.*/
+ QOMX_MediaInfoTagDateModified, /**< QOMX_DATESTAMPETYPE. Date when file was last modified.*/
+ QOMX_MediaInfoTagTimeModified, /**< QOMX_TIMESTAMPTYPE. Time when file was last modified.*/
+ QOMX_MediaInfoTagGPSAreaName, /**< OMX_U8*. The name of the location.*/
+ QOMX_MediaInfoTagGPSVersion, /**< OMX_VERSIONTYPE. GPS version.*/
+ QOMX_MediaInfoTagGPSCoordinates,/**< QOMX_GEODETICTYPE. The longitude, latitude, and altitude.*/
+ QOMX_MediaInfoTagGPSSatellites, /**< OMX_U8*. The GPS satellites used for measurements.*/
+ QOMX_MediaInfoTagGPSPrecision, /**< OMX_U32. GPS degree of precision.*/
+ QOMX_MediaInfoTagGPSDateStamp, /**< QOMX_DATESTAMPTYPE. Date of the GPS data.*/
+ QOMX_MediaInfoTagGPSTimeStamp, /**< QOMX_TIMESTAMPTYPE. Time of the GPS data.*/
+ QOMX_MediaInfoTagMediaStreamType,/**< QOMX_MEDIASTREAMTYPE. Type of the stream. */
+ QOMX_MediaInfoDuration, /**< OMX_TICKS. Total duration of the media.*/
+ QOMX_MediaInfoSize, /**< OMX_U32. Total size of the media in bytes.*/
+ QOMX_MediaInfoTagAlbum, /**< OMX_U8*. Name of album/movie/show.*/
+ QOMX_MediaInfoTagLocation, /**< OMX_U8*. Recording location information.*/
+ QOMX_MediaInfoTagClassification, /**< OMX_U8*. Classification information of media.*/
+ QOMX_MediaInfoTagRatings, /**< OMX_U8*. Media Ratings based on popularity & rating criteria.*/
+ QOMX_MediaInfoTagKeyword, /**< OMX_U8*. Keyword associated with media which are intended to reflect mood of the A/V.*/
+ QOMX_MediaInfoTagPerformance, /**< OMX_U8*. Media Performer information..*/
+ QOMX_MediaInfoTagYear, /**< OMX_U8*. Production year information of media.*/
+ QOMX_MediaInfoTagComposer, /**< OMX_U8*. Name of the composer of media i.e. audio.*/
+ QOMX_MediaInfoTagEncoderName, /**< OMX_U8*. Name of the person or organisation who encoded media.*/
+ QOMX_MediaInfoTagCopyProhibitFlag, /**< OMX_U8*. Flag to indicate if copy is allowed or not.*/
+ QOMX_MediaInfoTagLyricist, /**< OMX_U8*. Name of the lyricist or text writer in recording. Specific to ID3 tag.*/
+ QOMX_MediaInfoTagSubtitle, /**< OMX_U8*. Subtitle/Description used for informaton directly related to title of media.*/
+ QOMX_MediaInfoTagOriginalFileName, /**< OMX_U8*. Original file name.*/
+ QOMX_MediaInfoTagOriginalLyricist, /**< OMX_U8*. Name of the original lyricist/text writer of original recording.*/
+ QOMX_MediaInfoTagOriginalArtist, /**< OMX_U8*. Name of the original artist.*/
+ QOMX_MediaInfoTagOriginalReleaseYear, /**< OMX_U8*. Original release year of recorded media.*/
+ QOMX_MediaInfoTagFileOwner, /**< OMX_U8*. Licensee or name of the file owner.*/
+ QOMX_MediaInfoTagOrchestra, /**< OMX_U8*. Name of the orchestra or performers during recording.*/
+ QOMX_MediaInfoTagConductor, /**< OMX_U8*. Name of the conductor.*/
+ QOMX_MediaInfoTagRemixedBy, /**< OMX_U8*. Person or organization name who did the remix.*/
+ QOMX_MediaInfoTagAlbumArtist, /**< OMX_U8*. Name of the album artist.*/
+ QOMX_MediaInfoTagPublisher, /**< OMX_U8*. Name of the publisher or label.*/
+ QOMX_MediaInfoTagRecordingDates, /**< OMX_U8*. Recording date of media.*/
+ QOMX_MediaInfoTagInternetRadioStationName, /**< OMX_U8*. Name of the Internet radio station from which the audio is streamed.*/
+ QOMX_MediaInfoTagInternetRadioStationOwner, /**< OMX_U8*. Name of the owner of the Internet radio station from which the audio is streamed.*/
+ QOMX_MediaInfoTagInternationalRecordingCode,/**< OMX_U8*. International standard recording code.*/
+ QOMX_MediaInfoTagEncoderSwHwSettings, /**< OMX_U8*. Software,hardware settings used by encoder.*/
+ QOMX_MediaInfoTagInvolvedPeopleList, /**< OMX_U8*. List of people involved. Specific to ID3 tag.*/
+ QOMX_MediaInfoTagComments, /**< OMX_U8*. Comments about the media. It can be any kind of full text informaton.*/
+ QOMX_MediaInfoTagCommissioned, /**< OMX_U8*. Commissioned information of media.*/
+ QOMX_MediaInfoTagSubject, /**< OMX_U8*. Subject associated with media.*/
+ QOMX_MediaInfoTagContact, /**< OMX_U8*. Conatct information. URL information of the seller.*/
+ QOMX_MediaInfoTagValidityPeriod, /**< OMX_U8*. Length or period of validity of media.*/
+ QOMX_MediaInfoTagValidityEffectiveDate, /**< OMX_U8*. Validity effective date of media*/
+ QOMX_MediaInfoTagNumberOfAllowedPlaybacks, /**< OMX_U8*. Number of allowed playbacks for this media*/
+ QOMX_MediaInfoTagPlayCounter, /**< OMX_U8*. Current play counter of the media.Its number of times a file has been played.*/
+ QOMX_MediaInfoTagMemo, /**< OMX_U8*. Memo associatd with media.*/
+ QOMX_MediaInfoTagDeviceName, /**< OMX_U8*. Name of the devices used in creating media.*/
+ QOMX_MediaInfoTagURL, /**< OMX_U8*. List artist /genre /movie sites URL.*/
+ QOMX_MediaInfoTagFileType, /**< OMX_U8*. Indicates type of audio track.*/
+ QOMX_MediaInfoTagContentGroupDesc, /**< OMX_U8*. Content group description if the sound belongs to a larger category of of music /sound.*/
+ QOMX_MediaInfoTagInitialKeys, /**< OMX_U8*. Contains the musical key in which media starts.*/
+ QOMX_MediaInfoTagLanguages, /**< OMX_U8*. Languages of the text or lyrics spoken or sung in the media.*/
+ QOMX_MediaInfoTagMediaType, /**< OMX_U8*. Describes from which media the media sound originated.*/
+ QOMX_MediaInfoTagPlaylistDelay, /**< OMX_U8*. Denotes number of milliseconds between each song of the playlist.*/
+ QOMX_MediaInfoTagBeatsPerMinute, /**< OMX_U8*. Number of beats per minute in main part of audio.*/
+ QOMX_MediaInfoTagPartOfSet, /**< OMX_U8*. Describes part of the set selected or played. */
+ QOMX_MediaInfoTagInstrumentName, /**< OMX_U8*. Name of the instrument used in creating media.*/
+ QOMX_MediaInfoTagLyrics, /**< OMX_U8*. Lyrics of the media/audio track.*/
+ QOMX_MediaInfoTagTrackName, /**< OMX_U8*. Name of the media/audio track.*/
+ QOMX_MediaInfoTagMarker, /**< OMX_U8*. Text string cotnents placed at a specific location to denote information about the music at that point.*/
+ QOMX_MediaInfoTagCuePoint, /**< OMX_U8*. Subset of the content which can be optionally played.*/
+ QOMX_MediaInfoTagGPSPositioningName, /**< OMX_U8*. GPS positioning name. */
+ QOMX_MediaInfoTagGPSPositioningMethod, /**< OMX_U8*. GPS positioning method.*/
+ QOMX_MediaInfoTagGPSSurveyData, /**< OMX_U8*. GPS survey data. */
+ QOMX_MediaInfoTagGPSByteOrder, /**< OMX_U16.GPS byte order. */
+ QOMX_MediaInfoTagGPSLatitudeRef, /**< OMX_U32.Reference GPS latitude. */
+ QOMX_MediaInfoTagGPSLongitudeRef, /**< OMX_U32.Reference GPS longitude */
+ QOMX_MediaInfoTagGPSAltitudeRef, /**< OMX_U32. Reference GPS altitude.*/
+ QOMX_MediaInfoTagGPSExtensionMapScaleInfo, /**< OMX_U64. GPS extension map scale information.*/
+ QOMX_MediaInfoTagUUIDAtomInfo, /**< OMX_U8*. The user defined data associated with UUID.*/
+ QOMX_MediaInfoTagUUIDAtomCount, /**< OMX_U32 UUID atom count.*/
+ QOMX_MediaInfoTagLocationRole, /**< OMX_32. Indicates the role of the place. i.e. ‘0’ indicate ‘shooting location'. ‘1’ ‘real location’.*/
+ QOMX_MediaInfoTagAstronomicalBody, /**< OMX_U8*. Astronomical body on which the location exists.*/
+ QOMX_MediaInfoTagUserInfoData /**< OMX_U8*. The user defined tag informaton.*/
+} QOMX_MEDIAINFOTAGTYPE;
+
+typedef struct QOMX_MEDIAINFOTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex; /**< Read-only value containing the index of the output port. */
+ QOMX_MEDIAINFOTAGTYPE eTag; /**< The type of media info being specified. */
+ OMX_U32 nDataSize; /**< The size of the associated cData. Set nDataSize to 0 to retrieve the size required for cData. */
+ OMX_U8 cData[1]; /**< The media data info */
+} QOMX_MEDIAINFOTYPE;
+
+
+typedef enum QOMX_RESOLUTIONUNITTYPE {
+ QOMX_ResolutionUnitInch,
+ QOMX_ResolutionCentimeter
+} QOMX_RESOLUTIONUNITTYPE;
+
+typedef struct QOMX_RESOLUTIONTYPE {
+ QOMX_RESOLUTIONUNITTYPE eUnit; /**< The unit of measurement. */
+ OMX_U32 nX; /**< The number of pixels per unit in the width direction. */
+ OMX_U32 nY; /**< The number of pixels per unit in the height direction. */
+} QOMX_RESOLUTIONTYPE;
+
+typedef struct QOMX_TIMESTAMPTYPE {
+ OMX_U32 nHour; /**< The hour portion of the time stamp, based on a 24-hour format. */
+ OMX_U32 nMinute; /**< The minute portion of the time stamp. */
+ OMX_U32 nSecond; /**< The second portion of the time stamp. */
+ OMX_U32 nMillisecond; /**< the millisecond portion of the time stamp. */
+} QOMX_TIMESTAMPTYPE;
+
+typedef struct QOMX_DATESTAMPTYPE {
+ OMX_U32 nYear; /**< The year portion of the date stamp. */
+ OMX_U32 nMonth; /**< The monthportion of the date stamp. Valid values are 1 to 12.*/
+ OMX_U32 nDay; /**< The day portion of the date stamp. Valid values are 1 to 31 depending on the month specified.*/
+} QOMX_DATESTAMPTYPE;
+
+typedef enum QOMX_GEODETICREFTYPE {
+ QOMX_GeodeticRefNorth, /**< North latitude. */
+ QOMX_GeodeticRefSouth, /**< South latitude. */
+ QOMX_GeodeticRefEast, /**< East longitude. */
+ QOMX_GeodeticRefWest /**< West longitude. */
+} QOMX_GEODETICREFTYPE;
+
+/** QOMX_GEODETICANGLETYPE is used to set geodetic angle coordinates on an ellipsoid (the Earth),
+and is explicitly used to specify latitude and longitude. This structure is referenced by QOMX_GEODETICTYPE. */
+typedef struct QOMX_GEODETICANGLETYPE {
+ QOMX_GEODETICREFTYPE eReference; /**< Indicates whether the geodetic angle is a latitude or longitude. */
+ OMX_U32 nDegree; /**< The degree of the latitude or longitude. */
+ OMX_U32 nMinute; /**< The minute of the latitude or longitude. */
+ OMX_U32 nSecond; /**< The second of the latitude or longitude. */
+} QOMX_GEODETICANGLETYPE;
+
+typedef enum QOMX_ALTITUDEREFTYPE {
+ QOMX_AltitudeRefSeaLevel, /**< At sea level. */
+ QOMX_AltitudeRefBelowSeaLevel /**< Below sea level. */
+} QOMX_ALTITUDEREFTYPE;
+
+typedef struct QOMX_ALTITUDETYPE {
+ QOMX_ALTITUDEREFTYPE eReference; /**< The reference point for the altitude. */
+ OMX_U32 nMeter; /**< The absolute value of the number of meters above or below sea level. */
+ OMX_U32 nMillimeter; /**< The absolute value of the number of millimeters above or below sea level. */
+} QOMX_ALTITUDETYPE;
+
+/** QOMX_GEODETICTYPE is used to set geodetic coordinates such as longitude, latitude, and altitude.
+This structure references QOMX_GEODETICANGLETYPE and QOMX_ALTITUDETYPE. */
+typedef struct QOMX_GEODETICTYPE {
+ QOMX_GEODETICANGLETYPE sLatitude; /**< Indicates the latitude.*/
+ QOMX_GEODETICANGLETYPE sLongitude; /**< Indicates the longitude.*/
+ QOMX_ALTITUDETYPE sAltitude; /**< Indicates the altitude.*/
+} QOMX_GEODETICTYPE;
+
+
+typedef struct QOMX_IMAGE_IMAGESIZECONTROLTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex; /**< port index on which size control needs to be applied */
+ OMX_U32 nTargetImageSize; /**< expected max target size in Bytes */
+} QOMX_IMAGE_IMAGESIZECONTROLTYPE;
+
+typedef enum QOMX_URITYPE {
+ QOMX_URITYPE_RTSP, /**< RTSP URI Type. */
+ QOMX_URITYPE_HTTP, /**< HTTP URI Type. */
+ QOMX_URITYPE_LOCAL /**< Local URI Type.(i.e Non Network) */
+}QOMX_URITYPE;
+
+
+typedef enum QOMX_STREAMTYPE {
+ QOMX_STREAMTYPE_VOD, /**< Video On demand Stream */
+ QOMX_STREAMTYPE_LIVE,/**< Live Stream */
+ QOMX_STREAMTYPE_FILE /**< File based Stream */
+}QOMX_STREAMTYPE;
+
+
+typedef struct QOMX_MEDIASTREAMTYPE{
+ QOMX_URITYPE eURIType;
+ QOMX_STREAMTYPE eStreamType;
+}QOMX_MEDIASTREAMTYPE;
+
+
+/**
+ * This structure specifies the parameters associated with each
+ * plane of the uncompressed image/video format.
+ */
+typedef struct QOMX_PLANEDEFINITIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex; /**< Represents the port that this structure applies to */
+ OMX_U32 nPlaneIndex; /**< Specifies the plane enumeration index that this structure applies to, starting with a base value of 1 */
+ OMX_U32 nMinStride; /**< Read-only parameter that specifies the minimum buffer stride */
+ OMX_U32 nMaxStride; /**< Read-only parameter that specifies the maximum buffer stride */
+ OMX_U32 nStrideMultiples; /**< Read-only parameter that specifies the buffer stride multiple supported */
+ OMX_S32 nActualStride; /**< Specifies the actual stride to be applied */
+ OMX_U32 nMinPlaneBufferHeight; /**< Read-only parameter that specifies the minimum buffer height (number of stride lines) */
+ OMX_U32 nActualPlaneBufferHeight; /**< Specifies the actual buffer height (number of stride lines) to be applied */
+ OMX_U32 nBufferSize; /**< Read-only parameter that specifies the minimum size of the buffer, in bytes */
+ OMX_U32 nBufferAlignment; /**< Read-only field that specifies the required alignment of the buffer, in bytes */
+} QOMX_PLANEDEFINITIONTYPE;
+
+/**
+ * Pause port parameters
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Index of port that this structure represent
+ * bPausePort : Boolean field which indicates if port is paused or resume. By default bPausePort = OMX_FALSE
+ * & port will be paused when bPausePort = OMX_TRUE
+ */
+typedef struct QOMX_CONFIG_PAUSEPORTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex; /**< Represents the port that this structure applies to */
+ OMX_BOOL bPausePort; /**< Specifies if port need to PAUSE or RESUME */
+} QOMX_CONFIG_PAUSEPORTTYPE;
+
+
+typedef struct QOMX_RECTTYPE {
+ OMX_S32 nLeft;
+ OMX_S32 nTop;
+ OMX_U32 nWidth;
+ OMX_U32 nHeight;
+} QOMX_RECTTYPE;
+
+typedef struct QOMX_ACTIVEREGIONDETECTIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ QOMX_RECTTYPE sROI;
+ OMX_U32 nNumExclusionRegions;
+ QOMX_RECTTYPE sExclusionRegions[1];
+} QOMX_ACTIVEREGIONDETECTIONTYPE;
+
+typedef struct QOMX_ACTIVEREGIONDETECTION_STATUSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bDetected;
+ QOMX_RECTTYPE sDetectedRegion;
+} QOMX_ACTIVEREGIONDETECTION_STATUSTYPE;
+
+typedef enum QOMX_SCALE_MODETYPE {
+ QOMX_SCALE_MODE_Normal,
+ QOMX_SCALE_MODE_Anamorphic,
+ QOMX_SCALE_MODE_Max = 0x7FFFFFFF
+} QOMX_SCALE_MODETYPE;
+
+typedef struct QOMX_SCALINGMODETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ QOMX_SCALE_MODETYPE eScaleMode;
+} QOMX_SCALINGMODETYPE;
+
+typedef struct QOMX_NOISEREDUCTIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ OMX_BOOL bAutoMode;
+ OMX_S32 nNoiseReduction;
+} QOMX_NOISEREDUCTIONTYPE;
+
+typedef struct QOMX_IMAGEENHANCEMENTTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnable;
+ OMX_BOOL bAutoMode;
+ OMX_S32 nImageEnhancement;
+} QOMX_IMAGEENHANCEMENTTYPE;
+
+/*
+ * these are part of OMX1.2 but JB MR2 branch doesn't have them defined
+ * OMX_IndexParamInterlaceFormat
+ * OMX_INTERLACEFORMATTYPE
+ */
+#ifndef OMX_IndexParamInterlaceFormat
+#define OMX_IndexParamInterlaceFormat (0x7FF00000)
+typedef enum OMX_INTERLACETYPE
+{
+ OMX_InterlaceFrameProgressive,
+ OMX_InterlaceInterleaveFrameTopFieldFirst,
+ OMX_InterlaceInterleaveFrameBottomFieldFirst,
+ OMX_InterlaceFrameTopFieldFirst,
+ OMX_InterlaceFrameBottomFieldFirst
+}OMX_INTERLACEs;
+
+typedef struct OMX_INTERLACEFORMATTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nFormat;
+ OMX_TICKS nTimeStamp;
+} OMX_INTERLACEFORMATTYPE;
+#endif
+#if defined( __cplusplus )
+}
+#endif /* end of macro __cplusplus */
+
+#endif /* end of macro __H_QOMX_IVCOMMONEXTENSIONS_H__ */
diff --git a/msmcobalt/mm-core/inc/QOMX_SourceExtensions.h b/msmcobalt/mm-core/inc/QOMX_SourceExtensions.h
new file mode 100644
index 0000000..08eac3b
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_SourceExtensions.h
@@ -0,0 +1,157 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2011-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 __H_QOMX_SOURCEEXTENSIONS_H__
+#define __H_QOMX_SOURCEEXTENSIONS_H__
+/*========================================================================
+*//** @file QOMX_SourceExtensions.h
+
+@par FILE SERVICES:
+ Qualcomm extensions API for OpenMax IL demuxer component.
+
+ This file contains the description of the Qualcomm OpenMax IL
+ demuxer component extention interface, through which the IL client and
+ OpenMax components can access additional capabilities of the demuxer.
+
+*//*====================================================================== */
+
+
+/*========================================================================
+ INCLUDE FILES FOR MODULE
+========================================================================== */
+#include <OMX_Core.h>
+/*========================================================================
+ DEFINITIONS AND DECLARATIONS
+========================================================================== */
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif /* end of macro __cplusplus */
+/* Frame size query supported extension string */
+#define OMX_QCOM_INDEX_PARAM_FRAMESIZEQUERYSUPPORTED "OMX.QCOM.index.param.FrameSizeQuerySupported" /**< reference: QOMX_FRAMESIZETYPE */
+
+/* Content interface extension strings */
+#define OMX_QCOM_INDEX_PARAM_CONTENTINTERFACE_IXSTREAM "OMX.QCOM.index.param.contentinterface.ixstream" /**< reference: QOMX_CONTENTINTERFACETYPE*/
+#define OMX_QCOM_INDEX_PARAM_CONTENTINTERFACE_ISTREAMPORT "OMX.QCOM.index.param.contentinterface.istreamport" /**< reference: QOMX_CONTENTINTERFACETYPE*/
+
+/* Source seek access extension string */
+#define OMX_QCOM_INDEX_PARAM_SEEK_ACCESS "OMX.QCOM.index.param.SeekAccess" /**< reference: QOMX_PARAM_SEEKACCESSTYPE*/
+
+/* Media duration extension string*/
+#define OMX_QCOM_INDEX_CONFIG_MEDIADURATION "OMX.QCOM.index.config.MediaDuration" /**< reference: OMX_TIME_CONFIG_MEDIADURATIONTYPE*/
+
+/**
+ * Data interface Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nInterfaceSize : Size of the data pointed by pInterface
+ * pInterface : Interface pointer
+ */
+typedef struct QOMX_CONTENTINTERFACETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nInterfaceSize;
+ OMX_U8 pInterface[1];
+} QOMX_DATAINTERFACETYPE;
+
+/**
+ * Seek Access Parameters
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Index of port
+ * bSeekAllowed : Flag to indicate whether seek is supported or not
+ */
+typedef struct QOMX_PARAM_SEEKACCESSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bSeekAllowed;
+} QOMX_PARAM_SEEKACCESSTYPE;
+
+/**
+ * Media Duration parameters
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Index of port
+ * nDuration : Total duration of the media
+*/
+typedef struct OMX_TIME_CONFIG_MEDIADURATIONTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_TICKS nDuration;
+} OMX_TIME_CONFIG_MEDIADURATIONTYPE;
+
+/**
+ * The parameters for QOMX_FRAMESIZETYPE are defined as
+ * follows:
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Represents the port that this structure
+ * applies to
+ * sFrameSize : Indicates the size of the frame
+ * nFrameSizeIndex : Enumerates the possible frame sizes for
+ * the given session/URL configuration. The
+ * caller specifies all fields and the
+ * OMX_GetParameter call returns the value of
+ * the frame size. The value of
+ * nFrameSizeIndex goes from 0 to N-1, where
+ * N is the number of frame sizes that may be
+ * emitted by the port. The port does not
+ * need to report N as the caller can
+ * determine N by enumerating all the frame
+ * sizes supported by the port. If the port
+ * does not have advance knowledge of the
+ * possible frame sizes, it may report no
+ * frame sizes. If there are no more frame
+ * sizes, OMX_GetParameter returns
+ * OMX_ErrorNoMore.
+ */
+typedef struct QOMX_FRAMESIZETYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_FRAMESIZETYPE sFrameSize;
+ OMX_U32 nFrameSizeIndex;
+} QOMX_FRAMESIZETYPE;
+
+#if defined( __cplusplus )
+}
+#endif /* end of macro __cplusplus */
+
+#endif /* end of macro __H_QOMX_SOURCEEXTENSIONS_H__ */
diff --git a/msmcobalt/mm-core/inc/QOMX_StreamingExtensions.h b/msmcobalt/mm-core/inc/QOMX_StreamingExtensions.h
new file mode 100644
index 0000000..37023a2
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_StreamingExtensions.h
@@ -0,0 +1,486 @@
+#ifndef QOMX_STREAMINGEXTENSIONS_H_
+#define QOMX_STREAMINGEXTENSIONS_H_
+/*--------------------------------------------------------------------------
+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 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.
+--------------------------------------------------------------------------*/
+/*========================================================================
+
+*//** @file QOMX_StreamingExtensions.h
+
+@par FILE SERVICES:
+ Qualcomm extensions API for OpenMax IL Streaming Components.
+
+ This file contains the description of the Qualcomm OpenMax IL
+ streaming extention interface, through which the IL client and OpenMax
+ components can access additional streaming capabilities.
+
+*//*====================================================================== */
+
+/*========================================================================
+ Edit History
+
+$Header: //source/qcom/qct/multimedia2/api/OpenMax/QCOM/main/latest/QOMX_StreamingExtensions.h#7 $
+$DateTime: 2011/03/02 12:27:27 $
+$Change: 1638323 $
+
+========================================================================== */
+
+/* =======================================================================
+** Includes and Public Data Declarations
+** ======================================================================= */
+
+/* =======================================================================
+
+ INCLUDE FILES FOR MODULE
+
+========================================================================== */
+
+#include <OMX_Types.h>
+#include <OMX_Component.h>
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif /* end of macro __cplusplus */
+
+/* =======================================================================
+
+ DATA DECLARATIONS
+
+========================================================================== */
+/* -----------------------------------------------------------------------
+** Type Declarations
+** ----------------------------------------------------------------------- */
+/**
+ * Qualcomm vendor streaming extension strings.
+ */
+#define OMX_QUALCOMM_INDEX_CONFIG_WATERMARK "OMX.Qualcomm.index.config.Watermark"
+#define OMX_QUALCOMM_INDEX_CONFIG_WATERMARKSTATUS "OMX.Qualcomm.index.config.WatermarkStatus"
+#define OMX_QUALCOMM_INDEX_CONFIG_BUFFERMARKING "OMX.Qualcomm.index.config.BufferMarking"
+#define OMX_QUALCOMM_INDEX_PARAM_STREAMING_NETWORKINTERFACE "OMX.Qualcomm.index.param.streaming.NetworkInterface"
+#define OMX_QUALCOMM_INDEX_PARAM_STREAMING_NETWORKPROFILE "OMX.Qualcomm.index.param.streaming.NetworkProfile"
+#define OMX_QUALCOMM_INDEX_PARAM_STREAMING_PROXYSERVER "OMX.Qualcomm.index.param.streaming.ProxyServer"
+#define OMX_QUALCOMM_INDEX_PARAM_STREAMING_SOURCEPORTS "OMX.Qualcomm.index.param.streaming.SourcePorts"
+#define OMX_QUALCOMM_INDEX_CONFIG_STREAMING_PROTOCOLHEADER "OMX.Qualcomm.index.param.streaming.ProtocolHeader"
+#define OMX_QUALCOMM_INDEX_CONFIG_STREAMING_PROTOCOLEVENT "OMX.Qualcomm.index.config.streaming.ProtocolEvent"
+#define OMX_QUALCOMM_INDEX_CONFIG_STREAMING_DYNAMIC_SWITCH_CAPABILITY "OMX.Qualcomm.index.config.streaming.DynamicSessionSwitchCapability"
+#define OMX_QUALCOMM_INDEX_CONFIG_STREAMING_PROTOCOLHEADERSEVENT "OMX.QCOM.index.config.streaming.ProtocolHeadersEvent"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_USERPAUSETIMEOUT "OMX.QCOM.index.config.streaming.UserPauseTimeout"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_NOTIFYERRORONOPTIONSTIMEOUT "OMX.QCOM.index.config.streaming.NotifyErrorOnOptionsTimeout"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_USEINTERLEAVEDTCP "OMX.QCOM.index.config.streaming.UseInterleavedTCP"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_DATAINACTIVITYTIMEOUT "OMX.QCOM.index.config.streaming.DataInactivityTimeout"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_RTSPOPTIONSKEEPALIVEINTERVAL "OMX.QCOM.index.config.streaming.RTSPOptionsKeepaliveInterval"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_RTCPRRINTERVAL "OMX.QCOM.index.config.streaming.RTCPRRInterval"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_RECONFIGUREPORT "OMX.QCOM.index.config.streaming.ReconfigurePort"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_DEFAULTRTSPMESSAGETIMEOUT "OMX.QCOM.index.config.streaming.DefaultRTSPMessageTimeout"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_ENABLEFIREWALLPROBES "OMX.QCOM.index.config.streaming.EnableFirewallProbes"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_RTSPOPTIONSBEFORESETUP "OMX.QCOM.index.config.streaming.RTSPOptionsBeforeSetup"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_RTSPPIPELINEDFASTSTARTUP "OMX.QCOM.index.config.streaming.RTSPPipelinedFastStartup"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_WMFASTSTARTSPEED "OMX.QCOM.index.config.streaming.WMFastStartSpeed"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_ENABLEFASTRECONNECT "OMX.QCOM.index.config.streaming.EnableFastReconnect"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_FASTRECONNECTMAXATTEMPTS "OMX.QCOM.index.config.streaming.FastReconnectMaxAttempts"
+#define OMX_QCOM_INDEX_CONFIG_STREAMING_DOWNLOADPROGRESSUNITSTYPE "OMX.QCOM.index.config.streaming.DownloadProgressUnitsType"
+#define OMX_QOMX_INDEX_CONFIG_STREAMING_DOWNLOADPROGRESS "OMX.QCOM.index.config.streaming.DownloadProgress"
+/**
+ * Enumeration of the buffering watermark types
+ */
+typedef enum QOMX_WATERMARKTYPE
+{
+ QOMX_WATERMARK_UNDERRUN, /**< buffer has reached or is operating in an underrun condition */
+ QOMX_WATERMARK_NORMAL /**< has reached or is operating in a normal (optimal) condition */
+}QOMX_WATERMARKTYPE;
+
+/**
+ * Enumeration of type of buffering level tracking
+ */
+typedef enum QOMX_WATERMARKUNITSTYPE
+{
+ QOMX_WATERMARKUNITSTYPE_Time, /**< use a media time based reference */
+ QOMX_WATERMARKUNITSTYPE_Data /**< use a data fullness based reference */
+}QOMX_WATERMARKUNITSTYPE;
+
+/**
+ * Buffering watermark levels.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eWaterMark : eWaterMark specifies the type of buffering watermark being
+ * configured
+ * QOMX_WATERMARK_UNDERRUN Indicates the condition when the
+ * buffer has reached or is operating in an underrun condition
+ * - not enough data
+ * QOMX_WATERMARK_NORMAL Indicates the condition when the buffer
+ * has reached or is operating in a normal (optimal) condition
+ * - sufficient data within the buffer.
+ *
+ * nLevel : specifies the buffering level associated with the watermark.
+ * The units associated with the watermark level is dependent
+ * on the eUnitsType being selected.
+ * QOMX_WATERMARKUNITSTYPE_Time nLevel in units of microseconds.
+ * QOMX_WATERMARKUNITSTYPE_Data nLevel in units of bytes.
+ *
+ * nUnitsType : specifies the type of buffering level tracking to be used.
+ * QOMX_WATERMARKUNITSTYPE_Time the buffer watermark level
+ * shall use a media time based reference.
+ * QOMX_WATERMARKUNITSTYPE_Data the buffer watermark level
+ * shall use a data fullness based reference.
+ * bEnable : specifies if the watermark type is being enabled or disabled
+ */
+typedef struct QOMX_BUFFERINGWATERMARKTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_WATERMARKTYPE eWaterMark;
+ OMX_U32 nLevel;
+ QOMX_WATERMARKUNITSTYPE eUnitsType;
+ OMX_BOOL bEnable;
+} QOMX_BUFFERINGWATERMARKTYPE;
+
+/**
+ * Current buffering status of the streaming source component, for a given
+ * media port
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eCurrentWaterMark : specifies the current buffer watermark level condition
+ * QOMX_WATERMARK_UNDERRUN Indicates the condition when the
+ * buffer has reached or is operating in an underrun
+ * condition - not enough data
+ * QOMX_WATERMARK_NORMAL Indicates the condition when the
+ * buffer has reached or is operating in a normal
+ * (optimal) condition - sufficient data within the buffer.
+ * eUnitsType : specifies the type of buffering level tracking to be used.
+ * QOMX_WATERMARKUNITSTYPE_Time the buffer watermark level
+ * shall use a media time based reference.
+ * QOMX_WATERMARKUNITSTYPE_Data the buffer watermark level
+ * shall use a data fullness based reference.
+ * nCurrentLevel : specifies the current buffer watermark level condition
+ * The units associated with the watermark level is dependent
+ * on the eUnitsType being selected.
+ * QOMX_WATERMARKUNITSTYPE_Time nLevel in units of microseconds.
+ * QOMX_WATERMARKUNITSTYPE_Data nLevel in units of bytes.
+ */
+typedef struct QOMX_BUFFERINGSTATUSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_WATERMARKTYPE eCurrentWaterMark;
+ QOMX_WATERMARKUNITSTYPE eUnitsType;
+ OMX_U32 nCurrentLevel;
+} QOMX_BUFFERINGSTATUSTYPE;
+
+/**
+ * marked buffer shall be emitted when the buffering level has reach an
+ * underrun condition (QOMX_WATERMARK_UNDERRUN).
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * markInfo : identifies the target component handle that shall emit
+ * the mark buffer event and associated
+ * bEnable : enables or disables the buffer marking insertion.
+ *
+ */
+typedef struct QOMX_BUFFERMARKINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_MARKTYPE markInfo;
+ OMX_BOOL bEnable;
+} QOMX_BUFFERMARKINGTYPE;
+
+/**
+ * Source ports.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nMinimumPortNumber : Minimum port number the component may use
+ * nMaximumPortNumber : Maximum port number the component may use
+ */
+typedef struct QOMX_PARAM_STREAMING_SOURCE_PORTS
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U16 nMinimumPortNumber;
+ OMX_U16 nMaximumPortNumber;
+} QOMX_PARAM_STREAMING_SOURCE_PORTS;
+
+/**
+ * Enumeration used to define to the protocol message type.
+ */
+typedef enum QOMX_STREAMING_PROTOCOLMESSAGETYPE
+{
+ QOMX_STREAMING_PROTOCOLMESSAGE_REQUEST,
+ QOMX_STREAMING_PROTOCOLMESSAGE_RESPONSE,
+ QOMX_STREAMING_PROTOCOLMESSAGE_ALL
+} QOMX_STREAMING_PROTOCOLMESSAGETYPE;
+
+/**
+ * Enumeration used to define the protocol header action type.
+ */
+typedef enum QOMX_STREAMING_PROTOCOLHEADERACTIONTYPE
+{
+ QOMX_STREAMING_PROTOCOLHEADERACTION_NONE,
+ QOMX_STREAMING_PROTOCOLHEADERACTION_ADD,
+ QOMX_STREAMING_PROTOCOLHEADERACTION_REMOVE
+} QOMX_STREAMING_PROTOCOLHEADERACTIONTYPE;
+
+/**
+ * Protocol message header.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes (including size of
+ messageHeader parameter)
+ * nVersion : OMX specification version information
+ * eMessageType : enumeration to distinguish protocol message type
+ * eActionType : enumeration indicating protocol header action type
+ * nMessageClassSize : size of the message class string (excluding any
+ * terminating characters)
+ * nHeaderNameSize : size of the header name string (excluding any
+ * terminating characters)
+ * nHeaderValueSize : size of the header value string (excluding any
+ * terminating characters)
+ * messageHeader : the NULL-terminated message header string formed by
+ * concatenating message class, header name and value
+ * strings, i.e. the first nMessageClassSize bytes of the
+ * messageHeader parameter correspond to the message class
+ * (without any terminating characters), followed by the
+ * header name of size nHeaderNameSize bytes and then the
+ * header value of size nHeaderValueSize bytes. The value
+ * of message class is interpreted by what is mentioned in
+ * eMessageType,
+ * 1) For request message
+ * (QOMX_STREAMING_PROTOCOLMESSAGE_REQUEST) it is the
+ * Method token (as specified in the RFC 2616 and RFC
+ * 2326).
+ * 2) For response message
+ * (QOMX_STREAMING_PROTOCOLMESSAGE_RESPONSE) it is
+ * either or both the Method token and a three digit
+ * Status-Code (as specified in the RFC 2616 and
+ * RFC 2326) or a class of the response Status-Codes
+ * (1xx, 2xx, 3xx, 4xx, and 5xx). When both present,
+ * the method token and status code are separated by
+ * 1 empty space.
+ * 3) For all messages
+ * (QOMX_STREAMING_PROTOCOLMESSAGE_ALL) it will be
+ * absent (nMessageClassSize will be zero).
+ */
+typedef struct QOMX_CONFIG_STREAMING_PROTOCOLHEADERTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ QOMX_STREAMING_PROTOCOLMESSAGETYPE eMessageType;
+ QOMX_STREAMING_PROTOCOLHEADERACTIONTYPE eActionType;
+ OMX_U32 nMessageClassSize;
+ OMX_U32 nHeaderNameSize;
+ OMX_U32 nHeaderValueSize;
+ OMX_U8 messageHeader[1];
+} QOMX_CONFIG_STREAMING_PROTOCOLHEADERTYPE;
+
+/**
+ * Protocol Event.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes (including size of
+ protocolEventText parameter)
+ * nVersion : OMX specification version information
+ * nProtocolEvent : 1xx, 2xx, 3xx, 4xx or 5xx codes for HTTP/RTSP protocol
+ * nReasonPhraseSize : size of the reason phrase string (excluding any
+ * terminating characters)
+ * nEntityBodySize : size of the entity body string (excluding any
+ * terminating characters)
+ * nContentUriSize : size of the url (exclusing any terminating characters)
+ * url is used a key to identify for which operation this
+ * event belongs to
+ * protocolEventText : NULL-terminated protocol event text string formed by
+ * concatenating reason phrase and entity body
+ * and uri, i.e. the first nReasonPhraseSize bytes of the
+ * protocolEventText parameter correspond to the reason
+ * phrase (without any terminating characters), followed
+ * by the entity body of size nEntityBodySize bytes,
+ * followed by nContentUriSize bytes of URI
+ */
+typedef struct QOMX_CONFIG_STREAMING_PROTOCOLEVENTTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nProtocolEvent;
+ OMX_U32 nReasonPhraseSize;
+ OMX_U32 nEntityBodySize;
+ OMX_U32 nContentUriSize;
+ OMX_U8 protocolEventText[1];
+} QOMX_CONFIG_STREAMING_PROTOCOLEVENTTYPE;
+
+/**
+ * Protocol Headers Event
+ *
+ * STRUCT MEMBERS:
+ * nSize: Size of the structure in bytes including
+ * messageHeaders.
+ * nVersion: OMX specification version information
+ * eMessageType: enumeration to distinguish protocol message
+ * type
+ * nMessageClassSize: Size of the message class string.
+ * nMessageAttributesSize: Size of the message attributes
+ * string.
+ *
+ * This structure can be populated in 2 modes:
+ * (i) Query for required sizes of message class and message
+ * attributes. In this mode, nMessageClassSize and
+ * nMessageAtributesSize both need to be set to zero.
+ * (ii) Request to populate messageHeaders. In this mode, at
+ * least one of nMessageClassSize or nMessageAttributesSize
+ * need to be non-zero. On output, messageHeaders will be
+ * populated with the message class and message attributes.
+ * nMessageClassSize and/or nMessageAtributesSize may be
+ * overwritten to reflect the actual start and end of
+ * message class and message attributes. The max sizes of
+ * message class and message attributes will not exceed the
+ * values input by the client. The strings are not null
+ * terminated.
+ */
+typedef struct QOMX_STREAMING_PROTOCOLHEADERSTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ QOMX_STREAMING_PROTOCOLMESSAGETYPE eMessageType;
+ OMX_U32 nMessageClassSize;
+ OMX_U32 nMessageAtributesSize;
+ OMX_U8 messageHeaders[1];
+} QOMX_STREAMING_PROTOCOLHEADERSTYPE;
+
+/**
+ * Enumeration of possible streaming network interfaces.
+ */
+typedef enum QOMX_STREAMING_NETWORKINTERFACETYPE
+{
+ QOMX_STREAMING_NETWORKINTERFACE_ANY_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_CDMA_SN_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_CDMA_AN_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_UMTS_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_SIO_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_CDMA_BCAST_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_WLAN_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_DUN_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_FLO_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_DVBH_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_STA_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_IPSEC_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_LO_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_MBMS_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_IWLAN_3GPP_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_IWLAN_3GPP2_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_MIP6_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_UW_FMC_IFACE,
+ QOMX_STREAMING_NETWORKINTERFACE_CMMB_IFACE
+} QOMX_STREAMING_NETWORKINTERFACETYPE;
+
+/*
+ * Network interface.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes (including size of
+ protocolErrorText parameter)
+ * nVersion : OMX specification version information
+ * eNetworkInterface : Network interface the component may use
+ */
+typedef struct QOMX_PARAM_STREAMING_NETWORKINTERFACE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ QOMX_STREAMING_NETWORKINTERFACETYPE eNetworkInterface;
+} QOMX_PARAM_STREAMING_NETWORKINTERFACE;
+
+/**
+ * Enumeration of UnitType for DownloadProgress
+ */
+typedef enum QOMX_DOWNLOADPROGRESSUNITSTYPE
+{
+ QOMX_DOWNLOADPROGRESSUNITSTYPE_TIME,
+ QOMX_DOWNLOADPROGRESSUNITSTYPE_DATA
+} QOMX_DOWNLOADPROGRESSUNITSTYPE;
+
+
+/**
+ * DownloadProgress units
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes (including size of
+ protocolEventText parameter)
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eUnitsType : Specifies the type of units type in
+ * which download prgoress should be
+ * reported
+ */
+typedef struct QOMX_CONFIG_STREAMING_DOWNLOADPROGRESSUNITS
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_DOWNLOADPROGRESSUNITSTYPE eUnitsType;
+} QOMX_CONFIG_STREAMING_DOWNLOADPROGRESSUNITS;
+
+
+/**
+ * Download Progress
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes (including size of
+ protocolEventText parameter)
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * nDataDownloaded : specifies the amount of data downloaded
+ * in time or data scale (based on
+ * eUnitsType) from the media position
+ * specified by nStartOffset below. It
+ * starts at zero and progressively
+ * increases as more data is downloaded
+ * nCurrentStartOffset: specifies is the current download start
+ * position in time or data scale (based
+ * on eUnitsType)
+ */
+typedef struct QOMX_CONFIG_STREAMING_DOWNLOADPROGRESSTYPE
+{
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nDataDownloaded;
+ OMX_U32 nCurrentStartOffset;
+} QOMX_CONFIG_STREAMING_DOWNLOADPROGRESSTYPE;
+
+#if defined( __cplusplus )
+}
+#endif /* end of macro __cplusplus */
+
+#endif /* QOMX_STREAMINGEXTENSIONS_H_ */
+
diff --git a/msmcobalt/mm-core/inc/QOMX_VideoExtensions.h b/msmcobalt/mm-core/inc/QOMX_VideoExtensions.h
new file mode 100644
index 0000000..9587fae
--- /dev/null
+++ b/msmcobalt/mm-core/inc/QOMX_VideoExtensions.h
@@ -0,0 +1,582 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2011,2015 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 __H_QOMX_VIDEOEXTENSIONS_H__
+#define __H_QOMX_VIDEOEXTENSIONS_H__
+
+/*========================================================================
+
+*//** @file QOMX_VideoExtensions.h
+
+@par FILE SERVICES:
+ Qualcomm extensions API for OpenMax IL Video.
+
+ This file contains the description of the Qualcomm OpenMax IL
+ video extention interface, through which the IL client and OpenMax
+ components can access additional video capabilities.
+
+*//*====================================================================== */
+
+
+/*========================================================================== */
+
+/*========================================================================
+
+ INCLUDE FILES FOR MODULE
+
+========================================================================== */
+#include <OMX_Core.h>
+#include <OMX_Video.h>
+
+/*========================================================================
+
+ DEFINITIONS AND DECLARATIONS
+
+========================================================================== */
+
+#if defined( __cplusplus )
+extern "C"
+{
+#endif /* end of macro __cplusplus */
+
+/* Video extension strings */
+#define OMX_QCOM_INDEX_PARAM_VIDEO_SYNTAXHDR "OMX.QCOM.index.param.video.SyntaxHdr"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_ENCODERMODE "OMX.QCOM.index.param.video.EncoderMode"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_INTRAREFRESH "OMX.QCOM.index.config.video.IntraRefresh"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_INTRAPERIOD "OMX.QCOM.index.config.video.IntraPeriod"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_TEMPORALSPATIALTRADEOFF "OMX.QCOM.index.config.video.TemporalSpatialTradeOff"
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_MBCONCEALMENTREPORTING "OMX.QCOM.index.config.video.MBConcealmentReporting"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_EXTRADATAMULTISLICEINFO "OMX.QCOM.index.param.video.ExtraDataMultiSliceInfo" /**< reference: QOMX_ENABLETYPE */
+#define OMX_QCOM_INDEX_CONFIG_VIDEO_FLOWSTATUS "OMX.QCOM.index.config.video.FlowStatus" /**< reference: QOMX_FLOWSTATUSTYPE */
+#define OMX_QCOM_INDEX_PARAM_VIDEO_PICTURETYPEDECODE "OMX.QCOM.index.param.video.PictureTypeDecode" /**< reference: QOMX_VIDEO_DECODEPICTURETYPE */
+#define OMX_QCOM_INDEX_PARAM_VIDEO_SAMPLEASPECTRATIO "OMX.QCOM.index.param.video.SampleAspectRatio" /**< reference: QOMX_VIDEO_SAMPLEASPECTRATIO */
+#define OMX_QCOM_INDEX_PARAM_VIDEO_EXTRADATALTRINFO "OMX.QCOM.index.param.video.ExtraDataLTRInfo" /**< reference: QOMX_ENABLETYPE */
+
+/* Video coding types */
+#define OMX_QCOM_INDEX_PARAM_VIDEO_DIVX "OMX.QCOM.index.param.video.DivX"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_VP "OMX.QCOM.index.param.video.VP"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_SPARK "OMX.QCOM.index.param.video.Spark"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_VC1 "OMX.QCOM.index.param.video.VC1"
+
+/**
+ * Enumeration used to define the extended video compression
+ * codings, not present in the OpenMax IL 1.1.2 specification.
+ * NOTE: This essentially refers to file extensions. If the
+ * coding is being used to specify the ENCODE type, then
+ * additional work must be done to configure the exact
+ * flavor of the compression to be used.
+ */
+typedef enum QOMX_VIDEO_CODINGTYPE
+{
+ QOMX_VIDEO_CodingDivX = 0x7F000001, /**< all versions of DivX */
+ QOMX_VIDEO_CodingVP = 0x7F000002, /**< all versions of On2 VP codec */
+ QOMX_VIDEO_CodingSpark = 0x7F000003, /**< Sorenson Spark */
+ QOMX_VIDEO_CodingVC1 = 0x7F000004, /**< VC-1 */
+ QOMX_VIDEO_MPEG1 = 0x7F000005 /**< MPEG-1 */
+} QOMX_VIDEO_CODINGTYPE;
+
+/**
+ * DivX Versions
+ */
+typedef enum QOMX_VIDEO_DIVXFORMATTYPE {
+ QOMX_VIDEO_DIVXFormatUnused = 0x01, /**< Format unused or unknown */
+ QOMX_VIDEO_DIVXFormat311 = 0x02, /**< DivX 3.11 */
+ QOMX_VIDEO_DIVXFormat4 = 0x04, /**< DivX 4 */
+ QOMX_VIDEO_DIVXFormat5 = 0x08, /**< DivX 5 */
+ QOMX_VIDEO_DIVXFormat6 = 0x10, /**< DivX 6 */
+ QOMX_VIDEO_DIVXFormatKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_DIVXFormatVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_DIVXFormatMax = 0x7FFFFFFF
+} QOMX_VIDEO_DIVXFORMATTYPE;
+
+/**
+ * DivX profile types, each profile indicates support for
+ * various performance bounds.
+ */
+typedef enum QOMX_VIDEO_DIVXPROFILETYPE {
+ QOMX_VIDEO_DivXProfileqMobile = 0x01, /**< qMobile Profile */
+ QOMX_VIDEO_DivXProfileMobile = 0x02, /**< Mobile Profile */
+ QOMX_VIDEO_DivXProfileMT = 0x04, /**< Mobile Theatre Profile */
+ QOMX_VIDEO_DivXProfileHT = 0x08, /**< Home Theatre Profile */
+ QOMX_VIDEO_DivXProfileHD = 0x10, /**< High Definition Profile */
+ QOMX_VIDEO_DIVXProfileKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_DIVXProfileVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_DIVXProfileMax = 0x7FFFFFFF
+} QOMX_VIDEO_DIVXPROFILETYPE;
+
+/**
+ * DivX Video Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Version of DivX stream / data
+ * eProfile : Profile of DivX stream / data
+ */
+typedef struct QOMX_VIDEO_PARAM_DIVXTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_DIVXFORMATTYPE eFormat;
+ QOMX_VIDEO_DIVXPROFILETYPE eProfile;
+} QOMX_VIDEO_PARAM_DIVXTYPE;
+
+/**
+ * VP Versions
+ */
+typedef enum QOMX_VIDEO_VPFORMATTYPE {
+ QOMX_VIDEO_VPFormatUnused = 0x01, /**< Format unused or unknown */
+ QOMX_VIDEO_VPFormat6 = 0x02, /**< VP6 Video Format */
+ QOMX_VIDEO_VPFormat7 = 0x04, /**< VP7 Video Format */
+ QOMX_VIDEO_VPFormat8 = 0x08, /**< VP8 Video Format */
+ QOMX_VIDEO_VPFormat9 = 0x10, /**< VP9 Video Format */
+ QOMX_VIDEO_VPFormatKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_VPFormatVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_VPFormatMax = 0x7FFFFFFF
+} QOMX_VIDEO_VPFORMATTYPE;
+
+/**
+ * VP profile types, each profile indicates support for various
+ * encoding tools.
+ */
+typedef enum QOMX_VIDEO_VPPROFILETYPE {
+ QOMX_VIDEO_VPProfileSimple = 0x01, /**< Simple Profile, applies to VP6 only */
+ QOMX_VIDEO_VPProfileAdvanced = 0x02, /**< Advanced Profile, applies to VP6 only */
+ QOMX_VIDEO_VPProfileVersion0 = 0x04, /**< Version 0, applies to VP7 and VP8 */
+ QOMX_VIDEO_VPProfileVersion1 = 0x08, /**< Version 1, applies to VP7 and VP8 */
+ QOMX_VIDEO_VPProfileVersion2 = 0x10, /**< Version 2, applies to VP8 only */
+ QOMX_VIDEO_VPProfileVersion3 = 0x20, /**< Version 3, applies to VP8 only */
+ QOMX_VIDEO_VPProfileKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_VPProfileVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_VPProfileMax = 0x7FFFFFFF
+} QOMX_VIDEO_VPPROFILETYPE;
+
+/**
+ * VP Video Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Format of VP stream / data
+ * eProfile : Profile or Version of VP stream / data
+ */
+typedef struct QOMX_VIDEO_PARAM_VPTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_VPFORMATTYPE eFormat;
+ QOMX_VIDEO_VPPROFILETYPE eProfile;
+} QOMX_VIDEO_PARAM_VPTYPE;
+
+/**
+ * Spark Versions
+ */
+typedef enum QOMX_VIDEO_SPARKFORMATTYPE {
+ QOMX_VIDEO_SparkFormatUnused = 0x01, /**< Format unused or unknown */
+ QOMX_VIDEO_SparkFormat0 = 0x02, /**< Video Format Version 0 */
+ QOMX_VIDEO_SparkFormat1 = 0x04, /**< Video Format Version 1 */
+ QOMX_VIDEO_SparkFormatKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_SparkFormatVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_SparkFormatMax = 0x7FFFFFFF
+} QOMX_VIDEO_SPARKFORMATTYPE;
+
+/**
+ * Spark Video Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eFormat : Version of Spark stream / data
+ */
+typedef struct QOMX_VIDEO_PARAM_SPARKTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_SPARKFORMATTYPE eFormat;
+} QOMX_VIDEO_PARAM_SPARKTYPE;
+
+/**
+ * VC-1 profile types, each profile indicates support for
+ * various encoding tools.
+ */
+typedef enum QOMX_VIDEO_VC1PROFILETYPE {
+ QOMX_VIDEO_VC1ProfileSimple = 0x01, /**< Simple Profile */
+ QOMX_VIDEO_VC1ProfileMain = 0x02, /**< Main Profile */
+ QOMX_VIDEO_VC1ProfileAdvanced = 0x04, /**< Advanced Profile */
+ QOMX_VIDEO_VC1ProfileKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_VC1ProfileVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_VC1ProfileMax = 0x7FFFFFFF
+} QOMX_VIDEO_VC1PROFILETYPE;
+
+/**
+ * VC-1 level types, each level indicates support for various
+ * performance bounds.
+ */
+typedef enum QOMX_VIDEO_VC1LEVELTYPE {
+ QOMX_VIDEO_VC1LevelLow = 0x01, /**< Low Level, applies to simple and main profiles*/
+ QOMX_VIDEO_VC1LevelMedium = 0x02, /**< Medium Level, applies to simple and main profiles */
+ QOMX_VIDEO_VC1LevelHigh = 0x04, /**< High Level, applies to main profile only */
+ QOMX_VIDEO_VC1Level0 = 0x08, /**< Level 0, applies to advanced profile only */
+ QOMX_VIDEO_VC1Level1 = 0x10, /**< Level 1, applies to advanced profile only */
+ QOMX_VIDEO_VC1Level2 = 0x20, /**< Level 2, applies to advanced profile only */
+ QOMX_VIDEO_VC1Level3 = 0x40, /**< Level 3, applies to advanced profile only */
+ QOMX_VIDEO_VC1Level4 = 0x80, /**< Level 4, applies to advanced profile only */
+ QOMX_VIDEO_VC1LevelKhronosExtensions = 0x6F000000,
+ QOMX_VIDEO_VC1LevelVendorStartUnused = 0x7F000000,
+ QOMX_VIDEO_VC1LevelMax = 0x7FFFFFFF
+} QOMX_VIDEO_VC1LEVELTYPE;
+
+/**
+ * VC-1 Video Params
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version information
+ * nPortIndex : Port that this structure applies to
+ * eProfile : Profile of VC-1 stream / data
+ * eLevel : Level of VC-1 stream / data
+ */
+typedef struct QOMX_VIDEO_PARAM_VC1TYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_VC1PROFILETYPE eProfile;
+ QOMX_VIDEO_VC1LEVELTYPE eLevel;
+} QOMX_VIDEO_PARAM_VC1TYPE;
+
+/**
+ * Extended MPEG-4 level types not defined in the OpenMax IL
+ * 1.1.2 specification, each level indicates support for various
+ * frame sizes, bit rates, decoder frame rates.
+ */
+typedef enum QOMX_VIDEO_MPEG4LEVELTYPE {
+ QOMX_VIDEO_MPEG4Level6 = 0x7F000001, /**< Level 6 */
+ QOMX_VIDEO_MPEG4Level7 = 0x7F000002, /**< Level 7 */
+ QOMX_VIDEO_MPEG4Level8 = 0x7F000003, /**< Level 8 */
+ QOMX_VIDEO_MPEG4Level9 = 0x7F000004, /**< Level 9 */
+ QOMX_VIDEO_MPEG4LevelMax = 0x7FFFFFFF
+} QOMX_VIDEO_MPEG4LEVELTYPE;
+
+/**
+ * This structure is used in retrieving the syntax header from a
+ * video encoder component, or setting the out of band syntax
+ * header configuration data on a video decoder component.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nBytes : When used with OMX_GetParameter for the encoder
+ * component, it is a read-write field. When
+ * QOMX_VIDEO_SYNTAXHDRTYPE is passed in
+ * OMX_GetParameter this is the size of the buffer
+ * array pointed by data field. When the
+ * OMX_GetParameter call returns this is the
+ * amount of data within the buffer array.
+ *
+ * The IL client needs to allocate the buffer
+ * array and then request for the syntax header.
+ * If the size of buffer array to allocate is
+ * unknown to the IL client, then it can call
+ * OMX_GetParamter with nBytes set to 0. In this
+ * case, when OMX_GetParameter returns, the nBytes
+ * field will be set to the size of the syntax
+ * header. IL Client can then allocate a buffer of
+ * this size and call OMX_GetParamter again.
+ *
+ * When used with OMX_SetParameter for the decoder
+ * component, it is a read-only field specifying
+ * the amount of data in the buffer array.
+ * data : The syntax header data. The format of the
+ * syntax header is specific to the video codec,
+ * and is described below.
+ *
+ * H.263 : N/A
+ * H.264 : The SPS and PPS parameter sets
+ * MPEG-4 : The VO, VOS, and VOL header
+ * WMV7 : The "Extra Data" info, in the ASF Stream
+ * Properties Object.
+ * WMV8 : The "Extra Data" info, in the ASF Stream
+ * Properties Object.
+ * WMV9 SP/MP : The STRUCT_C portion of the sequence layer
+ * meta data, defined in Table 263 of the VC-1
+ * specification.
+ * VC-1 SP/MP : The STRUCT_C portion of the sequence layer
+ * meta data, defined in Table 263 of the VC-1
+ * specification.
+ * VC-1 AP : The sequence and entry point header
+ * DivX 3 : N/A
+ * DivX 4.x : The VO, VOS, and VOL header
+ * DivX 5.x : The VO, VOS, and VOL header
+ * DivX 6.x : The VO, VOS, and VOL header
+ * VP6 : N/A
+ * Spark : N/A
+ */
+typedef struct QOMX_VIDEO_SYNTAXHDRTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nBytes;
+ OMX_U8 data[1];
+} QOMX_VIDEO_SYNTAXHDRTYPE;
+
+
+/**
+ * Enumeration used to define the extended video intra refresh types, not
+ * present in the OpenMax IL 1.1.2 specification.
+ *
+ * ENUMS:
+ * IntraRefreshRandom : Random intra refresh mode.
+ */
+typedef enum QOMX_VIDEO_INTRAREFRESHTYPE
+{
+ QOMX_VIDEO_IntraRefreshRandom = 0x7F100000
+} QOMX_VIDEO_INTRAREFRESHTYPE;
+
+
+/**
+ * This structure is used to configure the intra periodicity for encoder.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nIDRPeriod : Defines the periodicity of IDR occurrence. This specifies
+ * coding a frame as IDR after a specific number of intra
+ * frames. The periodicity of intra frame coding is specified by
+ * the nPFrames. If nIDRPeriod is set to 0, only the first
+ * frame of the encode session is an IDR frame. This field is
+ * ignored for non-AVC codecs and is used only for codecs that
+ * support IDR Period.
+ * nPFrames : Specifies the number of P frames between each I Frame.
+ * nBFrames : Specifies the number of B frames between each I Frame.
+ */
+typedef struct QOMX_VIDEO_INTRAPERIODTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nIDRPeriod;
+ OMX_U32 nPFrames;
+ OMX_U32 nBFrames;
+} QOMX_VIDEO_INTRAPERIODTYPE;
+
+
+/**
+ * Enumeration used to define the extended video extra data payload types not
+ * present in the OpenMax IL 1.1.2 specification.
+ *
+ * ENUMS:
+ * VideoMultiSliceInfo : Multi slice layout information
+ *
+ * Slice information layout:
+ * First 4 bytes = Number of Slice Entries
+ *
+ * Then individual slice entries: 8 bytes per entry.
+ * Slice1 information: offset (4 bytes), Length (4 bytes)
+ * Slice2 information: offset (4 bytes), Length (4 bytes)
+ * Slice3 information: offset (4 bytes), Length (4 bytes)
+ * ...................................
+ * ...................................
+ * SliceN information: offset (4 bytes), Length (4 bytes)
+ *
+ *
+ * VideoNumConcealedMB : Number of concealed MBs
+ *
+ * The data array consists of an unsigned 32-bit size field
+ * indicating the number of concealed macroblocks in the
+ * uncompressed frame.
+ *
+ *
+ * QOMX_ExtraDataOMXIndex : Indicates that the data payload contains an
+ * OpenMax index and associated payload.
+ *
+ * The data of the extra data payload shall contain the value of the
+ * OMX_INDEXTYPE corresponding to the requested operation as an unsigned
+ * 32 bit number occupying the first four bytes of the payload. The index
+ * will be immediately followed by the associated structure. Padding bytes
+ * are appended to ensure 32 bit address alignment if needed.
+ */
+typedef enum QOMX_VIDEO_EXTRADATATYPE
+{
+ QOMX_ExtraDataVideoMultiSliceInfo = 0x7F100000,
+ QOMX_ExtraDataVideoNumConcealedMB,
+ QOMX_ExtraDataOMXIndex,
+ QOMX_ExtraDataHDCPEncryptionInfo
+} QOMX_VIDEO_EXTRADATATYPE;
+
+
+/**
+ * Enumeration used to define the video encoder modes
+ *
+ * ENUMS:
+ * EncoderModeDefault : Default video recording mode.
+ * All encoder settings made through
+ * OMX_SetParameter/OMX_SetConfig are applied. No
+ * parameter is overridden.
+ * EncoderModeMMS : Video recording mode for MMS (Multimedia Messaging
+ * Service). This mode is similar to EncoderModeDefault
+ * except that here the Rate control mode is overridden
+ * internally and set as a variant of variable bitrate with
+ * variable frame rate. After this mode is set if the IL
+ * client tries to set OMX_VIDEO_CONTROLRATETYPE via
+ * OMX_IndexParamVideoBitrate that would be rejected. For
+ * this, client should set mode back to EncoderModeDefault
+ * first and then change OMX_VIDEO_CONTROLRATETYPE.
+ */
+typedef enum QOMX_VIDEO_ENCODERMODETYPE
+{
+ QOMX_VIDEO_EncoderModeDefault = 0x01,
+ QOMX_VIDEO_EncoderModeMMS = 0x02,
+ QOMX_VIDEO_EncoderModeMax = 0x7FFFFFFF
+} QOMX_VIDEO_ENCODERMODETYPE;
+
+/**
+ * This structure is used to set the video encoder mode.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nMode : defines the video encoder mode
+ */
+typedef struct QOMX_VIDEO_PARAM_ENCODERMODETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ QOMX_VIDEO_ENCODERMODETYPE nMode;
+} QOMX_VIDEO_PARAM_ENCODERMODETYPE;
+
+
+/**
+ * This structure is used to set the temporal (picture rate) - spatial
+ * (picture quality) trade-off factor.
+ * This setting is only valid when rate control is enabled and set to a mode
+ * with variable frame rate. For all other rate control modes this setting is
+ * ignored.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nTSFactor : temporal-spatial tradeoff factor value in the range of 0-100.
+ * A factor of 0 won't emphasizes picture rate in rate
+ * control decisions at all i.e only picture quality is emphasized. For
+ * increasing values from 1 to 99 the emphasis of picture rate in rate
+ * control decisions increases. A factor of 100 emphasizes only picture rate
+ * in rate control decisions.
+ */
+typedef struct QOMX_VIDEO_TEMPORALSPATIALTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nTSFactor;
+} QOMX_VIDEO_TEMPORALSPATIALTYPE;
+
+/**
+ * This structure is used to enable or disable the MB concealmenet reporting
+ * for the uncompressed frames emitted from the port.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * bEnableMBConcealmentReporting : Flag indicating whether MB concealment
+ * reporting is enabled or disabled.
+ * OMX_TRUE: Enables MB concealment reporting
+ * OMX_FALSE: Disables MB concealment reporting
+ */
+typedef struct QOMX_VIDEO_MBCONCEALMENTREPORTINGTYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_BOOL bEnableMBConcealmentReporting;
+} QOMX_VIDEO_MBCONCEALMENTREPORTINGTYPE;
+
+/**
+ * Specifies the extended picture types. These values should be
+ * OR'd along with the types defined in OMX_VIDEO_PICTURETYPE to
+ * signal all pictures types which are allowed.
+ *
+ * ENUMS:
+ * H.264 Specific Picture Types: IDR
+ */
+typedef enum QOMX_VIDEO_PICTURETYPE {
+ QOMX_VIDEO_PictureTypeIDR = OMX_VIDEO_PictureTypeVendorStartUnused + 0x1000
+} QOMX_VIDEO_PICTURETYPE;
+
+/**
+ * This structure is used to configure the processing of
+ * specific picture types.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nPictureTypes : Specifies the picture type(s)
+ * that shall be processed. The value consists
+ * of the desired picture types, defined by the
+ * OMX_VIDEO_PICTURETYPE and
+ * QOMX_VIDEO_PICTURETYPE enumerations, OR'd to
+ * signal all the pictures types which are
+ * allowed.
+ */
+typedef struct QOMX_VIDEO_DECODEPICTURETYPE {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nPictureTypes;
+} QOMX_VIDEO_DECODEPICTURETYPE;
+
+/**
+ * This structure describes the sample aspect ratio information.
+ *
+ * STRUCT MEMBERS:
+ * nSize : Size of the structure in bytes
+ * nVersion : OMX specification version info
+ * nPortIndex : Port that this structure applies to
+ * nWidth : Specifies the horizontal aspect size of
+ * the sample
+ * nHeight : Specifies the vertical aspect size of the
+ * sample
+ */
+typedef struct QOMX_VIDEO_SAMPLEASPECTRATIO {
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U16 nWidth;
+ OMX_U16 nHeight;
+} QOMX_VIDEO_SAMPLEASPECTRATIO;
+
+#if defined( __cplusplus )
+}
+#endif /* end of macro __cplusplus */
+
+#endif /* end of macro __H_QOMX_VIDEOEXTENSIONS_H__ */
diff --git a/msmcobalt/mm-core/inc/drmplay_version.h b/msmcobalt/mm-core/inc/drmplay_version.h
new file mode 100644
index 0000000..230b633
--- /dev/null
+++ b/msmcobalt/mm-core/inc/drmplay_version.h
@@ -0,0 +1,34 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 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 DRMPLAY_VERSION_H
+#define DRMPLAY_VERSION_H
+
+#define DRMPLAY_API_VERSION ".101"
+
+#endif /* DRMPLAY_VERSION_H */
diff --git a/msmcobalt/mm-core/inc/qc_omx_common.h b/msmcobalt/mm-core/inc/qc_omx_common.h
new file mode 100644
index 0000000..0459185
--- /dev/null
+++ b/msmcobalt/mm-core/inc/qc_omx_common.h
@@ -0,0 +1,65 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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 qc_omx_common.h
+ This module contains the definitions of the OpenMAX core.
+
+*//*========================================================================*/
+
+#ifndef QC_OMX_COMMON_H
+#define QC_OMX_COMMON_H
+
+
+#include <stdio.h> // Standard IO
+#include "OMX_Core.h" // OMX API
+#include "OMX_QCOMExtns.h" // OMX API
+
+#define OMX_CORE_MAX_CMP 1 // MAX Components supported
+#define OMX_CORE_MAX_CMP_ROLES 1 // MAX Roles per component
+#define OMX_SPEC_VERSION 0x00000101 // OMX Version
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void * (*create_qc_omx_component)(void);
+
+#ifdef _ANDROID_
+#define LOG_TAG "QC_CORE"
+#endif
+#include "qc_omx_msg.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/msmcobalt/mm-core/inc/qc_omx_component.h b/msmcobalt/mm-core/inc/qc_omx_component.h
new file mode 100644
index 0000000..9b5ebf7
--- /dev/null
+++ b/msmcobalt/mm-core/inc/qc_omx_component.h
@@ -0,0 +1,183 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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 m p o n e n t I n t e r f a c e
+
+*//** @file qc_omx_component.h
+ This module contains the abstract interface for the OpenMAX components.
+
+*//*========================================================================*/
+
+#ifndef QC_OMX_COMPONENT_H
+#define QC_OMX_COMPONENT_H
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+
+class qc_omx_component
+{
+
+public:
+ /* single member to hold the vtable */
+ OMX_COMPONENTTYPE m_cmp;
+
+public:
+
+ // this is critical, otherwise, sub class destructor will not be called
+ virtual ~qc_omx_component(){}
+
+ // Initialize the component after creation
+ virtual OMX_ERRORTYPE component_init(OMX_IN OMX_STRING componentName)=0;
+
+ /*******************************************************************/
+ /* Standard OpenMAX Methods */
+ /*******************************************************************/
+
+ // Query the component for its information
+ virtual
+ OMX_ERRORTYPE get_component_version(OMX_HANDLETYPE cmp_handle,
+ OMX_STRING cmp_name,
+ OMX_VERSIONTYPE* cmp_version,
+ OMX_VERSIONTYPE* spec_version,
+ OMX_UUIDTYPE* cmp_UUID)=0;
+
+ // Invoke a command on the component
+ virtual
+ OMX_ERRORTYPE send_command(OMX_HANDLETYPE cmp_handle,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param1,
+ OMX_PTR cmd_data)=0;
+
+ // Get a Parameter setting from the component
+ virtual
+ OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE param_index,
+ OMX_PTR param_data)=0;
+
+ // Send a parameter structure to the component
+ virtual
+ OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE param_index,
+ OMX_PTR param_data)=0;
+
+ // Get a configuration structure from the component
+ virtual
+ OMX_ERRORTYPE get_config(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE config_index,
+ OMX_PTR config_data)=0;
+
+ // Set a component configuration value
+ virtual
+ OMX_ERRORTYPE set_config(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE config_index,
+ OMX_PTR config_data)=0;
+
+ // Translate the vendor specific extension string to
+ // standardized index type
+ virtual
+ OMX_ERRORTYPE get_extension_index(OMX_HANDLETYPE cmp_handle,
+ OMX_STRING paramName,
+ OMX_INDEXTYPE* indexType)=0;
+
+ // Get Current state information
+ virtual
+ OMX_ERRORTYPE get_state(OMX_HANDLETYPE cmp_handle,
+ OMX_STATETYPE* state)=0;
+
+ // Component Tunnel Request
+ virtual
+ OMX_ERRORTYPE component_tunnel_request(OMX_HANDLETYPE cmp_handle,
+ OMX_U32 port,
+ OMX_HANDLETYPE peer_component,
+ OMX_U32 peer_port,
+ OMX_TUNNELSETUPTYPE* tunnel_setup)=0;
+
+ // Use a buffer already allocated by the IL client
+ // or a buffer already supplied by a tunneled component
+ virtual
+ OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE** buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR app_data,
+ OMX_U32 bytes,
+ OMX_U8* buffer)=0;
+
+
+ // Request that the component allocate new buffer and associated header
+ virtual
+ OMX_ERRORTYPE allocate_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE** buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR app_data,
+ OMX_U32 bytes)=0;
+
+ // Release the buffer and associated header from the component
+ virtual
+ OMX_ERRORTYPE free_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_U32 port,
+ OMX_BUFFERHEADERTYPE* buffer)=0;
+
+ // Send a filled buffer to an input port of a component
+ virtual
+ OMX_ERRORTYPE empty_this_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE* buffer)=0;
+
+ // Send an empty buffer to an output port of a component
+ virtual
+ OMX_ERRORTYPE fill_this_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE* buffer)=0;
+
+ // Set callbacks
+ virtual
+ OMX_ERRORTYPE set_callbacks( OMX_HANDLETYPE cmp_handle,
+ OMX_CALLBACKTYPE* callbacks,
+ OMX_PTR app_data)=0;
+
+ // Component De-Initialize
+ virtual
+ OMX_ERRORTYPE component_deinit( OMX_HANDLETYPE cmp_handle)=0;
+
+ // Use the Image already allocated via EGL
+ virtual
+ OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE** buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR app_data,
+ void* egl_image)=0;
+
+ // Component Role enum
+ virtual
+ OMX_ERRORTYPE component_role_enum( OMX_HANDLETYPE cmp_handle,
+ OMX_U8* role,
+ OMX_U32 index)=0;
+
+};
+#endif /* QC_OMX_COMPONENT_H */
diff --git a/msmcobalt/mm-core/inc/qc_omx_msg.h b/msmcobalt/mm-core/inc/qc_omx_msg.h
new file mode 100644
index 0000000..deb0ab7
--- /dev/null
+++ b/msmcobalt/mm-core/inc/qc_omx_msg.h
@@ -0,0 +1,86 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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 qc_omx_msg.h
+ This module contains the definitions of the OpenMAX core.
+
+*//*========================================================================*/
+
+#ifndef _QC_OMX_MSG_H_
+#define _QC_OMX_MSG_H_
+
+#ifdef _ENABLE_QC_MSG_LOG_
+ #ifdef _ANDROID_
+ #include <utils/Log.h>
+
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+
+ #ifndef LOGE
+ #define LOGE ALOGE
+ #endif
+
+ #ifndef LOGW
+ #define LOGW ALOGW
+ #endif
+
+ #ifndef LOGD
+ #define LOGD ALOGD
+ #endif
+
+ #ifndef LOGV
+ #define LOGV ALOGV
+ #endif
+
+ #ifndef LOGI
+ #define LOGI ALOGI
+ #endif
+
+ #ifdef __cplusplus
+ }
+ #endif
+
+ #define DEBUG_PRINT_ERROR LOGE
+ #define DEBUG_PRINT LOGI
+ #define DEBUG_DETAIL LOGV
+ #else
+ #define DEBUG_PRINT_ERROR printf
+ #define DEBUG_PRINT printf
+ #define DEBUG_DETAIL printf
+ #endif // _ANDROID_
+#else
+ #define DEBUG_PRINT_ERROR
+ #define DEBUG_PRINT
+ #define DEBUG_DETAIL
+#endif // _ENABLE_QC_MSG_LOG_
+
+#endif // _QC_OMX_MSG_H_
diff --git a/msmcobalt/mm-core/src/7627A/qc_registry_table.c b/msmcobalt/mm-core/src/7627A/qc_registry_table.c
new file mode 100755
index 0000000..aa65c1a
--- /dev/null
+++ b/msmcobalt/mm-core/src/7627A/qc_registry_table.c
@@ -0,0 +1,812 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2011-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.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxH264Dec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmvDec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.real",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxrv9Dec.so",
+ {
+ "video_decoder.real"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVidEnc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.spark",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.spark"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxOn2Dec.so",
+ {
+ "video_decoder.vp"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVp8Dec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVidEnc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVidEnc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxMp3Dec.so",
+ #else
+ "libmm-adec-omxmp3.so.1",
+ #endif
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAacDec.so",
+ #else
+ "libmm-adec-omxaac.so.1",
+ #endif
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxMp3Dec.so",
+ #else
+ "libmm-adec-omxmp3.so.1",
+ #endif
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAacDec.so",
+ #else
+ "libmm-adec-omxaac.so.1",
+ #endif
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrDec.so",
+ #else
+ "libmm-adec-omxamr.so.1",
+ #endif
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrDec.so",
+ #else
+ "libmm-adec-omxamr.so.1",
+ #endif
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAacEnc.so",
+ #else
+ "libmm-aenc-omxaac.so.1",
+ #endif
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13Hw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelpHwDec.so",
+ #else
+ "libmm-adec-omxQcelp13.so.1",
+ #endif
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.Qcelp13Hw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelpHwDec.so",
+ #else
+ "libmm-adec-omxQcelp13.so.1",
+ #endif
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrchw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcHwDec.so",
+ #else
+ "libmm-adec-omxevrc.so.1",
+ #endif
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcHwDec.so",
+ #else
+ "libmm-adec-omxevrc.so.1",
+ #endif
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.amr",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrEnc.so",
+ #else
+ "libmm-aenc-omxamr.so.1",
+ #endif
+ {
+ "audio_encoder.amr"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwbp"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwbp"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelp13Enc.so",
+ #else
+ "libmm-aenc-omxqcelp13.so.1",
+ #endif
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelp13Enc.so",
+ #else
+ "libmm-aenc-omxqcelp13.so.1",
+ #endif
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcEnc.so",
+ #else
+ "libmm-aenc-omxevrc.so.1",
+ #endif
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcEnc.so",
+ #else
+ "libmm-aenc-omxevrc.so.1",
+ #endif
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ac3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAc3HwDec.so",
+ {
+ "audio_decoder.ac3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.eac3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAc3HwDec.so",
+ {
+ "audio_decoder.eac3"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/7627A/qc_registry_table_android.c b/msmcobalt/mm-core/src/7627A/qc_registry_table_android.c
new file mode 100755
index 0000000..af55f50
--- /dev/null
+++ b/msmcobalt/mm-core/src/7627A/qc_registry_table_android.c
@@ -0,0 +1,711 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2011-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.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxH264Dec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ //Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ //Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmvDec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.real",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxrv9Dec.so",
+ {
+ "video_decoder.real"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.spark",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMpeg4Dec.so",
+ {
+ "video_decoder.spark"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxOn2Dec.so",
+ {
+ "video_decoder.vp"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVp8Dec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVidEnc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVidEnc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVidEnc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMp3Dec.so",
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13Hw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelpHwDec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrchw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcHwDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwbp"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcEnc.so",
+ #else
+ "libmm-aenc-omxevrc.so.1",
+ #endif
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelp13Enc.so",
+ #else
+ "libmm-aenc-omxqcelp13.so.1",
+ #endif
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ac3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAc3HwDec.so",
+ {
+ "audio_decoder.ac3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.eac3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAc3HwDec.so",
+ {
+ "audio_decoder.eac3"
+ }
+ },
+#ifndef _ANDROID_
+ {
+ "OMX.qcom.audio.decoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrDec.so",
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMp3Dec.so",
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrDec.so",
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.Qcelp13Hw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelpHwDec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcHwDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.amr",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amr"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ }
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwbp"
+ }
+ }
+#endif
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/7630/qc_registry_table.c b/msmcobalt/mm-core/src/7630/qc_registry_table.c
new file mode 100644
index 0000000..eb53d90
--- /dev/null
+++ b/msmcobalt/mm-core/src/7630/qc_registry_table.c
@@ -0,0 +1,746 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009,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.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxMp3Dec.so",
+ #else
+ "libmm-adec-omxmp3.so.1",
+ #endif
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAacDec.so",
+ #else
+ "libmm-adec-omxaac.so.1",
+ #endif
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxMp3Dec.so",
+ #else
+ "libmm-adec-omxmp3.so.1",
+ #endif
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAacDec.so",
+ #else
+ "libmm-adec-omxaac.so.1",
+ #endif
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrDec.so",
+ #else
+ "libmm-adec-omxamr.so.1",
+ #endif
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrDec.so",
+ #else
+ "libmm-adec-omxamr.so.1",
+ #endif
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAacEnc.so",
+ #else
+ "libmm-aenc-omxaac.so.1",
+ #endif
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAacEnc.so",
+ #else
+ "libmm-aenc-omxaac.so.1",
+ #endif
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13Hw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelpHwDec.so",
+ #else
+ "libmm-adec-omxQcelp13.so.1",
+ #endif
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+#ifdef _ANDROID_
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+#endif
+ {
+ "OMX.qcom.audio.decoder.tunneled.Qcelp13Hw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelpHwDec.so",
+ #else
+ "libmm-adec-omxQcelp13.so.1",
+ #endif
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcDec.so",
+ #else
+ "libmm-adec-omxevrc.so.1",
+ #endif
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcDec.so",
+ #else
+ "libmm-adec-omxevrc.so.1",
+ #endif
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.amr",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrEnc.so",
+ #else
+ "libmm-aenc-omxamr.so.1",
+ #endif
+ {
+ "audio_encoder.amr"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxWmaDec.so",
+ #else
+ "libmm-adec-omxwma.so.1",
+ #endif
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwbp"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAmrwbDec.so",
+ #else
+ "libmm-adec-omxamrwb.so.1",
+ #endif
+ {
+ "audio_decoder.amrwbp"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelp13Enc.so",
+ #else
+ "libmm-aenc-omxqcelp13.so.1",
+ #endif
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelp13Enc.so",
+ #else
+ "libmm-aenc-omxqcelp13.so.1",
+ #endif
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcEnc.so",
+ #else
+ "libmm-aenc-omxevrc.so.1",
+ #endif
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcEnc.so",
+ #else
+ "libmm-aenc-omxevrc.so.1",
+ #endif
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.adpcm",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAdpcmDec.so",
+ #else
+ "libmm-adec-omxadpcm.so.1",
+ #endif
+ {
+ "audio_decoder.adpcm"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.adpcm",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxAdpcmDec.so",
+ #else
+ "libmm-adec-omxadpcm.so.1",
+ #endif
+ {
+ "audio_decoder.adpcm"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/7630/qc_registry_table_android.c b/msmcobalt/mm-core/src/7630/qc_registry_table_android.c
new file mode 100644
index 0000000..f7314d2
--- /dev/null
+++ b/msmcobalt/mm-core/src/7630/qc_registry_table_android.c
@@ -0,0 +1,552 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009,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.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+#include "drmplay_version.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwbp"
+ }
+ },
+ {
+ "drm.play" DRMPLAY_API_VERSION,
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libDrmPlay.so",
+ {
+ "drm.play" DRMPLAY_API_VERSION
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxEvrcEnc.so",
+ #else
+ "libmm-aenc-omxevrc.so.1",
+ #endif
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "libOmxQcelp13Enc.so",
+ #else
+ "libmm-aenc-omxqcelp13.so.1",
+ #endif
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+#ifndef _ANDROID_
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrDec.so",
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMp3Dec.so",
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrDec.so",
+ {
+ "audio_decoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.amr",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amr"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ }
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.amrwbp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbDec.so",
+ {
+ "audio_decoder.amrwbp"
+ }
+ }
+#endif
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8084/qc_registry_table.c b/msmcobalt/mm-core/src/8084/qc_registry_table.c
new file mode 100644
index 0000000..ce5fc56
--- /dev/null
+++ b/msmcobalt/mm-core/src/8084/qc_registry_table.c
@@ -0,0 +1,463 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2012-2016, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8084/qc_registry_table_android.c b/msmcobalt/mm-core/src/8084/qc_registry_table_android.c
new file mode 100644
index 0000000..278b36f
--- /dev/null
+++ b/msmcobalt/mm-core/src/8084/qc_registry_table_android.c
@@ -0,0 +1,574 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2012 - 2016, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+{
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play.generic",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.role.generic"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8092/qc_registry_table.c b/msmcobalt/mm-core/src/8092/qc_registry_table.c
new file mode 100644
index 0000000..bfbaf10
--- /dev/null
+++ b/msmcobalt/mm-core/src/8092/qc_registry_table.c
@@ -0,0 +1,479 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2012-2014, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mvc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mvc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8092/qc_registry_table_android.c b/msmcobalt/mm-core/src/8092/qc_registry_table_android.c
new file mode 100644
index 0000000..f1d2649
--- /dev/null
+++ b/msmcobalt/mm-core/src/8092/qc_registry_table_android.c
@@ -0,0 +1,574 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2012 - 2014, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mvc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mvc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+{
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play.generic",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.role.generic"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8226/qc_registry_table.c b/msmcobalt/mm-core/src/8226/qc_registry_table.c
new file mode 100644
index 0000000..5655cc2
--- /dev/null
+++ b/msmcobalt/mm-core/src/8226/qc_registry_table.c
@@ -0,0 +1,411 @@
+/*--------------------------------------------------------------------------
+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.
+
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevchybrid",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevcswvdec",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevcswvdec"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8226/qc_registry_table_android.c b/msmcobalt/mm-core/src/8226/qc_registry_table_android.c
new file mode 100644
index 0000000..6b7029e
--- /dev/null
+++ b/msmcobalt/mm-core/src/8226/qc_registry_table_android.c
@@ -0,0 +1,476 @@
+/*--------------------------------------------------------------------------
+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.
+
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevchybrid",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevcswvdec",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevcswvdec"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+{
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.101"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8610/qc_registry_table.c b/msmcobalt/mm-core/src/8610/qc_registry_table.c
new file mode 100644
index 0000000..cf5e038
--- /dev/null
+++ b/msmcobalt/mm-core/src/8610/qc_registry_table.c
@@ -0,0 +1,425 @@
+/*--------------------------------------------------------------------------
+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.
+
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8610/qc_registry_table_android.c b/msmcobalt/mm-core/src/8610/qc_registry_table_android.c
new file mode 100644
index 0000000..0e222f1
--- /dev/null
+++ b/msmcobalt/mm-core/src/8610/qc_registry_table_android.c
@@ -0,0 +1,437 @@
+/*--------------------------------------------------------------------------
+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.
+
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.ittiam.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.ittiam.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "drm.play",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libDrmPlay.so",
+ {
+ "drm.play"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8660/qc_registry_table.c b/msmcobalt/mm-core/src/8660/qc_registry_table.c
new file mode 100755
index 0000000..287b8aa
--- /dev/null
+++ b/msmcobalt/mm-core/src/8660/qc_registry_table.c
@@ -0,0 +1,671 @@
+/*--------------------------------------------------------------------------
+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 "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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMp3Dec.so",
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.mp3",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMp3Dec.so",
+ {
+ "audio_decoder.mp3"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.tunneled.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.adpcm",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAdpcmDec.so",
+ {
+ "audio_decoder.adpcm"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.tunneled.adpcm",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAdpcmDec.so",
+ {
+ "audio_decoder.adpcm"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+},
+ {
+ "OMX.qcom.audio.encoder.tunneled.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8660/qc_registry_table_android.c b/msmcobalt/mm-core/src/8660/qc_registry_table_android.c
new file mode 100755
index 0000000..b9d551d
--- /dev/null
+++ b/msmcobalt/mm-core/src/8660/qc_registry_table_android.c
@@ -0,0 +1,468 @@
+/*--------------------------------------------------------------------------
+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 "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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+#ifdef ENABLE_DRMPLAY
+#include "drmplay_version.h"
+#endif
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+#ifdef ENABLE_DRMPLAY
+ {
+ "drm.play" DRMPLAY_API_VERSION,
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libDrmPlay.so",
+ {
+ "drm.play" DRMPLAY_API_VERSION
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+#endif
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8909/registry_table.c b/msmcobalt/mm-core/src/8909/registry_table.c
new file mode 100644
index 0000000..4c9924f
--- /dev/null
+++ b/msmcobalt/mm-core/src/8909/registry_table.c
@@ -0,0 +1,255 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8909/registry_table_android.c b/msmcobalt/mm-core/src/8909/registry_table_android.c
new file mode 100644
index 0000000..226518a
--- /dev/null
+++ b/msmcobalt/mm-core/src/8909/registry_table_android.c
@@ -0,0 +1,320 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.ittiam.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxIttiamVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencMpeg4.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencMpeg4.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.101"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8916/registry_table.c b/msmcobalt/mm-core/src/8916/registry_table.c
new file mode 100644
index 0000000..006c776
--- /dev/null
+++ b/msmcobalt/mm-core/src/8916/registry_table.c
@@ -0,0 +1,411 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevchybrid",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevcswvdec",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevcswvdec"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8916/registry_table_android.c b/msmcobalt/mm-core/src/8916/registry_table_android.c
new file mode 100644
index 0000000..9e467d7
--- /dev/null
+++ b/msmcobalt/mm-core/src/8916/registry_table_android.c
@@ -0,0 +1,489 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevcswvdec",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevcswvdec"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+{
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.101"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8937/registry_table.c b/msmcobalt/mm-core/src/8937/registry_table.c
new file mode 100755
index 0000000..ce928db
--- /dev/null
+++ b/msmcobalt/mm-core/src/8937/registry_table.c
@@ -0,0 +1,466 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014-16, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.mpeg4sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.h263sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.divxsw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.divx4sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencMpeg4.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencMpeg4.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.alac.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDecSw.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.ape.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDecSw.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8937/registry_table_android.c b/msmcobalt/mm-core/src/8937/registry_table_android.c
new file mode 100755
index 0000000..6ecb499
--- /dev/null
+++ b/msmcobalt/mm-core/src/8937/registry_table_android.c
@@ -0,0 +1,514 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014-16, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.mpeg4sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.h263sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.divxsw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qti.video.decoder.divx4sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencMpeg4.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencMpeg4.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.alac.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDecSw.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.ape.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDecSw.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qti.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8952/registry_table.c b/msmcobalt/mm-core/src/8952/registry_table.c
new file mode 100644
index 0000000..1154138
--- /dev/null
+++ b/msmcobalt/mm-core/src/8952/registry_table.c
@@ -0,0 +1,544 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2015, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qti.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8952/registry_table_android.c b/msmcobalt/mm-core/src/8952/registry_table_android.c
new file mode 100644
index 0000000..4f882e5
--- /dev/null
+++ b/msmcobalt/mm-core/src/8952/registry_table_android.c
@@ -0,0 +1,609 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2015, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+{
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qti.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.101"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8960/qc_registry_table.c b/msmcobalt/mm-core/src/8960/qc_registry_table.c
new file mode 100755
index 0000000..5f7afe9
--- /dev/null
+++ b/msmcobalt/mm-core/src/8960/qc_registry_table.c
@@ -0,0 +1,272 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 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 "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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8960/qc_registry_table_android.c b/msmcobalt/mm-core/src/8960/qc_registry_table_android.c
new file mode 100644
index 0000000..7a79fe9
--- /dev/null
+++ b/msmcobalt/mm-core/src/8960/qc_registry_table_android.c
@@ -0,0 +1,479 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 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 "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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.101"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8974/qc_registry_table.c b/msmcobalt/mm-core/src/8974/qc_registry_table.c
new file mode 100644
index 0000000..90f63dc
--- /dev/null
+++ b/msmcobalt/mm-core/src/8974/qc_registry_table.c
@@ -0,0 +1,425 @@
+/*--------------------------------------------------------------------------
+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.
+
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevchybrid",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevcswvdec",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevcswvdec"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+{
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/8974/qc_registry_table_android.c b/msmcobalt/mm-core/src/8974/qc_registry_table_android.c
new file mode 100644
index 0000000..23c3b54
--- /dev/null
+++ b/msmcobalt/mm-core/src/8974/qc_registry_table_android.c
@@ -0,0 +1,501 @@
+/*--------------------------------------------------------------------------
+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.
+--------------------------------------------------------------------------*/
+/*============================================================================
+ 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevchybrid",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevcswvdec",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdecHevc.so",
+ {
+ "video_decoder.hevcswvdec"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play.generic",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.role.generic"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/common/omx_core_cmp.cpp b/msmcobalt/mm-core/src/common/omx_core_cmp.cpp
new file mode 100755
index 0000000..300abe4
--- /dev/null
+++ b/msmcobalt/mm-core/src/common/omx_core_cmp.cpp
@@ -0,0 +1,407 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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
+
+ This module contains the implementation of the OpenMAX core Macros which
+ operate directly on the component.
+
+*//*========================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+#include "qc_omx_common.h"
+#include "omx_core_cmp.h"
+#include "qc_omx_component.h"
+#include <string.h>
+
+
+void * qc_omx_create_component_wrapper(OMX_PTR obj_ptr)
+{
+ qc_omx_component *pThis = (qc_omx_component *)obj_ptr;
+ OMX_COMPONENTTYPE* component = &(pThis->m_cmp);
+ memset(&pThis->m_cmp,0,sizeof(OMX_COMPONENTTYPE));
+
+ component->nSize = sizeof(OMX_COMPONENTTYPE);
+ component->nVersion.nVersion = OMX_SPEC_VERSION;
+ component->pApplicationPrivate = 0;
+ component->pComponentPrivate = obj_ptr;
+
+ component->AllocateBuffer = &qc_omx_component_allocate_buffer;
+ component->FreeBuffer = &qc_omx_component_free_buffer;
+ component->GetParameter = &qc_omx_component_get_parameter;
+ component->SetParameter = &qc_omx_component_set_parameter;
+ component->SendCommand = &qc_omx_component_send_command;
+ component->FillThisBuffer = &qc_omx_component_fill_this_buffer;
+ component->EmptyThisBuffer = &qc_omx_component_empty_this_buffer;
+ component->GetState = &qc_omx_component_get_state;
+ component->GetComponentVersion = &qc_omx_component_get_version;
+ component->GetConfig = &qc_omx_component_get_config;
+ component->SetConfig = &qc_omx_component_set_config;
+ component->GetExtensionIndex = &qc_omx_component_get_extension_index;
+ component->ComponentTunnelRequest = &qc_omx_component_tunnel_request;
+ component->UseBuffer = &qc_omx_component_use_buffer;
+ component->SetCallbacks = &qc_omx_component_set_callbacks;
+ component->UseEGLImage = &qc_omx_component_use_EGL_image;
+ component->ComponentRoleEnum = &qc_omx_component_role_enum;
+ component->ComponentDeInit = &qc_omx_component_deinit;
+ return (void *)component;
+}
+
+
+
+/************************************************************************/
+/* COMPONENT INTERFACE */
+/************************************************************************/
+
+OMX_ERRORTYPE
+qc_omx_component_init(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_STRING componentName)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_init %p\n", hComp);
+
+ if(pThis)
+ {
+ // call the init fuction
+ eRet = pThis->component_init(componentName);
+
+ if(eRet != OMX_ErrorNone)
+ {
+ // in case of error, please destruct the component created
+ delete pThis;
+ }
+ }
+ return eRet;
+}
+
+
+OMX_ERRORTYPE
+qc_omx_component_get_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)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_get_version %p, %s , %p\n", hComp, componentName, componentVersion);
+ if(pThis)
+ {
+ eRet = pThis->get_component_version(hComp,componentName,componentVersion,specVersion,componentUUID);
+ }
+ return eRet;
+}
+
+OMX_ERRORTYPE
+qc_omx_component_send_command(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_COMMANDTYPE cmd,
+ OMX_IN OMX_U32 param1,
+ OMX_IN OMX_PTR cmdData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_send_command %p, %d , %d\n", hComp,(unsigned)cmd,(unsigned)param1);
+
+ if(pThis)
+ {
+ eRet = pThis->send_command(hComp,cmd,param1,cmdData);
+ }
+ return eRet;
+}
+
+OMX_ERRORTYPE
+qc_omx_component_get_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_INOUT OMX_PTR paramData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_get_parameter %p, %p , %d\n", hComp, paramData, paramIndex);
+
+ if(pThis)
+ {
+ eRet = pThis->get_parameter(hComp,paramIndex,paramData);
+ }
+ return eRet;
+}
+
+OMX_ERRORTYPE
+qc_omx_component_set_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_IN OMX_PTR paramData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_set_parameter %p, %p , %d\n", hComp, paramData, paramIndex);
+
+ if(pThis)
+ {
+ eRet = pThis->set_parameter(hComp,paramIndex,paramData);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_get_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_INOUT OMX_PTR configData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_get_config %p\n", hComp);
+
+ if(pThis)
+ {
+ eRet = pThis->get_config(hComp,
+ configIndex,
+ configData);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_set_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_IN OMX_PTR configData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_set_config %p\n", hComp);
+
+ if(pThis)
+ {
+ eRet = pThis->set_config(hComp,
+ configIndex,
+ configData);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_STRING paramName,
+ OMX_OUT OMX_INDEXTYPE* indexType)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ if(pThis)
+ {
+ eRet = pThis->get_extension_index(hComp,paramName,indexType);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_get_state(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STATETYPE* state)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_get_state %p\n", hComp);
+
+ if(pThis)
+ {
+ eRet = pThis->get_state(hComp,state);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_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)
+{
+ (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup;
+ DEBUG_PRINT("Error: qc_omx_component_tunnel_request Not Implemented\n");
+ return OMX_ErrorNotImplemented;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_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_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_use_buffer %p\n", hComp);
+
+ if(pThis)
+ {
+ eRet = pThis->use_buffer(hComp,
+ bufferHdr,
+ port,
+ appData,
+ bytes,
+ buffer);
+ }
+ return eRet;
+}
+
+
+// qc_omx_component_allocate_buffer -- API Call
+ OMX_ERRORTYPE
+qc_omx_component_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_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_allocate_buffer %p, %p , %d\n",hComp, bufferHdr,(unsigned)port);
+
+ if(pThis)
+ {
+ eRet = pThis->allocate_buffer(hComp,bufferHdr,port,appData,bytes);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_free_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_free_buffer[%d] %p, %p\n", (unsigned)port, hComp, buffer);
+
+ if(pThis)
+ {
+ eRet = pThis->free_buffer(hComp,port,buffer);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_empty_this_buffer %p, %p\n",hComp, buffer);
+
+ if(pThis)
+ {
+ eRet = pThis->empty_this_buffer(hComp,buffer);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_fill_this_buffer %p, %p\n", hComp, buffer);
+ if(pThis)
+ {
+ eRet = pThis->fill_this_buffer(hComp,buffer);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_CALLBACKTYPE* callbacks,
+ OMX_IN OMX_PTR appData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_set_callbacks %p, %p , %p\n", hComp, callbacks, appData);
+
+ if(pThis)
+ {
+ eRet = pThis->set_callbacks(hComp,callbacks,appData);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_deinit %p\n", hComp);
+
+ if(pThis)
+ {
+ // call the deinit fuction first
+ OMX_STATETYPE state;
+ pThis->get_state(hComp,&state);
+ DEBUG_PRINT("Calling FreeHandle in state %d \n", state);
+ eRet = pThis->component_deinit(hComp);
+ // destroy the component.
+ delete pThis;
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_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_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_use_EGL_image %p, %p , %d\n", hComp, bufferHdr,(unsigned)port);
+ if(pThis)
+ {
+ eRet = pThis->use_EGL_image(hComp,bufferHdr,port,appData,eglImage);
+ }
+ return eRet;
+}
+
+ OMX_ERRORTYPE
+qc_omx_component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_U8* role,
+ OMX_IN OMX_U32 index)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorBadParameter;
+ qc_omx_component *pThis = (hComp)? (qc_omx_component *)(((OMX_COMPONENTTYPE *)hComp)->pComponentPrivate):NULL;
+ DEBUG_PRINT("OMXCORE: qc_omx_component_role_enum %p, %p , %d\n", hComp, role,(unsigned)index);
+
+ if(pThis)
+ {
+ eRet = pThis->component_role_enum(hComp,role,index);
+ }
+ return eRet;
+}
diff --git a/msmcobalt/mm-core/src/common/omx_core_cmp.h b/msmcobalt/mm-core/src/common/omx_core_cmp.h
new file mode 100755
index 0000000..b3c9df5
--- /dev/null
+++ b/msmcobalt/mm-core/src/common/omx_core_cmp.h
@@ -0,0 +1,160 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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
+
+ OpenMAX Core Macros interface.
+
+============================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+#ifndef OMX_CORE_CMP_H
+#define OMX_CORE_CMP_H
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void * qc_omx_create_component_wrapper(OMX_PTR obj_ptr);
+
+
+OMX_ERRORTYPE
+qc_omx_component_init(OMX_IN OMX_HANDLETYPE hComp, OMX_IN OMX_STRING componentName);
+
+
+OMX_ERRORTYPE
+qc_omx_component_get_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);
+
+OMX_ERRORTYPE
+qc_omx_component_send_command(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_COMMANDTYPE cmd,
+ OMX_IN OMX_U32 param1,
+ OMX_IN OMX_PTR cmdData);
+
+OMX_ERRORTYPE
+qc_omx_component_get_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_INOUT OMX_PTR paramData);
+
+OMX_ERRORTYPE
+qc_omx_component_set_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_IN OMX_PTR paramData);
+
+OMX_ERRORTYPE
+qc_omx_component_get_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_INOUT OMX_PTR configData);
+
+OMX_ERRORTYPE
+qc_omx_component_set_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_IN OMX_PTR configData);
+
+OMX_ERRORTYPE
+qc_omx_component_get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_STRING paramName,
+ OMX_OUT OMX_INDEXTYPE* indexType);
+
+OMX_ERRORTYPE
+qc_omx_component_get_state(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STATETYPE* state);
+
+OMX_ERRORTYPE
+qc_omx_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);
+
+OMX_ERRORTYPE
+qc_omx_component_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);
+
+
+// qc_omx_component_allocate_buffer -- API Call
+OMX_ERRORTYPE
+qc_omx_component_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
+qc_omx_component_free_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer);
+
+OMX_ERRORTYPE
+qc_omx_component_empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer);
+
+OMX_ERRORTYPE
+qc_omx_component_fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer);
+
+OMX_ERRORTYPE
+qc_omx_component_set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_CALLBACKTYPE* callbacks,
+ OMX_IN OMX_PTR appData);
+
+OMX_ERRORTYPE
+qc_omx_component_deinit(OMX_IN OMX_HANDLETYPE hComp);
+
+OMX_ERRORTYPE
+qc_omx_component_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_ERRORTYPE
+qc_omx_component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_U8* role,
+ OMX_IN OMX_U32 index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/msmcobalt/mm-core/src/common/qc_omx_core.c b/msmcobalt/mm-core/src/common/qc_omx_core.c
new file mode 100644
index 0000000..b3f9c5e
--- /dev/null
+++ b/msmcobalt/mm-core/src/common/qc_omx_core.c
@@ -0,0 +1,932 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 2015, 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
+
+ This module contains the implementation of the OpenMAX core.
+
+*//*========================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+#include <dlfcn.h> // dynamic library
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <pthread.h>
+
+#include "qc_omx_core.h"
+#include "omx_core_cmp.h"
+#include <cutils/properties.h>
+
+extern omx_core_cb_type core[];
+extern const unsigned int SIZE_OF_CORE;
+static pthread_mutex_t lock_core = PTHREAD_MUTEX_INITIALIZER;
+static int number_of_adec_nt_session;
+
+#define MAX_AUDIO_NT_SESSION 2
+
+/* ======================================================================
+FUNCTION
+ omx_core_load_cmp_library
+
+DESCRIPTION
+ Loads up the libary name mentioned in the argument
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ Constructor for creating component instances.
+========================================================================== */
+static create_qc_omx_component
+omx_core_load_cmp_library(char *libname, void **handle_ptr)
+{
+ create_qc_omx_component fn_ptr = NULL;
+ if(handle_ptr)
+ {
+ DEBUG_PRINT("Dynamically Loading the library : %s\n",libname);
+ *handle_ptr = dlopen(libname,RTLD_NOW);
+ if(*handle_ptr)
+ {
+ fn_ptr = dlsym(*handle_ptr, "get_omx_component_factory_fn");
+
+ if(fn_ptr == NULL)
+ {
+ DEBUG_PRINT("Error: Library %s incompatible as QCOM OMX component loader - %s\n",
+ libname, dlerror());
+ *handle_ptr = NULL;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT("Error: Couldn't load %s: %s\n",libname,dlerror());
+ }
+ }
+ return fn_ptr;
+}
+
+/* ======================================================================
+FUNCTION
+ OMX_Init
+
+DESCRIPTION
+ This is the first function called by the application.
+ There is nothing to do here since components shall be loaded
+ whenever the get handle method is called.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY
+OMX_Init()
+{
+ DEBUG_PRINT("OMXCORE API - OMX_Init \n");
+ /* Nothing to do here ; shared objects shall be loaded at the get handle method */
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ get_cmp_index
+
+DESCRIPTION
+ Obtains the index associated with the name.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ Error None.
+========================================================================== */
+static int get_cmp_index(char *cmp_name)
+{
+ int rc = -1,i=0;
+ DEBUG_PRINT("before get_cmp_index **********%d\n", rc);
+
+ for(i=0; i< (int)SIZE_OF_CORE; i++)
+ {
+ DEBUG_PRINT("get_cmp_index: cmp_name = %s , core[i].name = %s ,count = %d \n",cmp_name,core[i].name,i);
+
+ if(!strcmp(cmp_name, core[i].name))
+ {
+ rc = i;
+ break;
+ }
+ }
+ DEBUG_PRINT("returning index %d\n", rc);
+ return rc;
+}
+
+/* ======================================================================
+FUNCTION
+ clear_cmp_handle
+
+DESCRIPTION
+ Clears the component handle from the component table.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+static void clear_cmp_handle(OMX_HANDLETYPE inst)
+{
+ unsigned i = 0,j=0;
+
+ if(NULL == inst)
+ return;
+
+ for(i=0; i< SIZE_OF_CORE; i++)
+ {
+ for(j=0; j< OMX_COMP_MAX_INST; j++)
+ {
+ if(inst == core[i].inst[j])
+ {
+ core[i].inst[j] = NULL;
+ return;
+ }
+ }
+ }
+ return;
+}
+/* ======================================================================
+FUNCTION
+ is_cmp_handle_exists
+
+DESCRIPTION
+ Check if the component handle already exists or not.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ index pointer if the handle exists
+ negative value otherwise
+========================================================================== */
+static int is_cmp_handle_exists(OMX_HANDLETYPE inst)
+{
+ unsigned i=0,j=0;
+ int rc = -1;
+
+ if(NULL == inst)
+ return rc;
+
+ pthread_mutex_lock(&lock_core);
+ for(i=0; i< SIZE_OF_CORE; i++)
+ {
+ for(j=0; j< OMX_COMP_MAX_INST; j++)
+ {
+ if(inst == core[i].inst[j])
+ {
+ rc = i;
+ goto finish;
+ }
+ }
+ }
+finish:
+ pthread_mutex_unlock(&lock_core);
+ return rc;
+}
+
+/* ======================================================================
+FUNCTION
+ get_comp_handle_index
+
+DESCRIPTION
+ Gets the index to store the next handle for specified component name.
+
+PARAMETERS
+ cmp_name : Component Name
+
+RETURN VALUE
+ Index of next handle to be stored
+========================================================================== */
+static int get_comp_handle_index(char *cmp_name)
+{
+ unsigned i=0,j=0;
+ int rc = -1;
+ for(i=0; i< SIZE_OF_CORE; i++)
+ {
+ if(!strcmp(cmp_name, core[i].name))
+ {
+ for(j=0; j< OMX_COMP_MAX_INST; j++)
+ {
+ if(NULL == core[i].inst[j])
+ {
+ rc = j;
+ DEBUG_PRINT("free handle slot exists %d\n", rc);
+ return rc;
+ }
+ }
+ break;
+ }
+ }
+ return rc;
+}
+
+/* ======================================================================
+FUNCTION
+ check_lib_unload
+
+DESCRIPTION
+ Check if any component instance is using the library
+
+PARAMETERS
+ index: Component Index in core array.
+
+RETURN VALUE
+ 1: Library Unused and can be unloaded.
+ 0: Library used and shouldnt be unloaded.
+========================================================================== */
+static int check_lib_unload(int index)
+{
+ unsigned i=0;
+ int rc = 1;
+
+ for(i=0; i< OMX_COMP_MAX_INST; i++)
+ {
+ if(core[index].inst[i])
+ {
+ rc = 0;
+ DEBUG_PRINT("Library Used \n");
+ break;
+ }
+ }
+ return rc;
+}
+/* ======================================================================
+FUNCTION
+ is_cmp_already_exists
+
+DESCRIPTION
+ Check if the component already exists or not. Used in the
+ management of component handles.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ Error None.
+========================================================================== */
+static int is_cmp_already_exists(char *cmp_name)
+{
+ unsigned i =0,j=0;
+ int rc = -1;
+ for(i=0; i< SIZE_OF_CORE; i++)
+ {
+ if(!strcmp(cmp_name, core[i].name))
+ {
+ for(j=0; j< OMX_COMP_MAX_INST; j++)
+ {
+ if(core[i].inst[j])
+ {
+ rc = i;
+ DEBUG_PRINT("Component exists %d\n", rc);
+ return rc;
+ }
+ }
+ break;
+ }
+ }
+ return rc;
+}
+
+/* ======================================================================
+FUNCTION
+ get_cmp_handle
+
+DESCRIPTION
+ Get component handle.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ Error None.
+========================================================================== */
+void* get_cmp_handle(char *cmp_name)
+{
+ unsigned i =0,j=0;
+
+ DEBUG_PRINT("get_cmp_handle \n");
+ for(i=0; i< SIZE_OF_CORE; i++)
+ {
+ if(!strcmp(cmp_name, core[i].name))
+ {
+ for(j=0; j< OMX_COMP_MAX_INST; j++)
+ {
+ if(core[i].inst[j])
+ {
+ DEBUG_PRINT("get_cmp_handle match\n");
+ return core[i].inst[j];
+ }
+ }
+ }
+ }
+ DEBUG_PRINT("get_cmp_handle returning NULL \n");
+ return NULL;
+}
+
+/* ======================================================================
+FUNCTION
+ OMX_DeInit
+
+DESCRIPTION
+ DeInitialize all the the relevant OMX components.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ Error None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY
+OMX_Deinit()
+{
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ OMX_GetHandle
+
+DESCRIPTION
+ Constructs requested component. Relevant library is loaded if needed.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ Error None if everything goes fine.
+========================================================================== */
+
+ OMX_API OMX_ERRORTYPE OMX_APIENTRY
+OMX_GetHandle(OMX_OUT OMX_HANDLETYPE* handle,
+ OMX_IN OMX_STRING componentName,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_CALLBACKTYPE* callBacks)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ int cmp_index = -1;
+ int hnd_index = -1;
+ int vpp_cmp_index = -1;
+
+ DEBUG_PRINT("OMXCORE API : GetHandle %p %s %p\n", handle,
+ componentName,
+ appData);
+ pthread_mutex_lock(&lock_core);
+ if(handle)
+ {
+ struct stat sd;
+ *handle = NULL;
+ char optComponentName[OMX_MAX_STRINGNAME_SIZE];
+ strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);
+
+ if(strstr(componentName, "avc") && strstr(componentName, "decoder"))
+ {
+ void *libhandle = dlopen("libOmxVideoDSMode.so", RTLD_NOW);
+ if(libhandle)
+ {
+ int (*fn_ptr)() = dlsym(libhandle, "isDSModeActive");
+
+ if(fn_ptr == NULL)
+ {
+ DEBUG_PRINT_ERROR("Error: isDSModeActive Not Found %s\n",
+ dlerror());
+ }
+ else
+ {
+ int isActive = fn_ptr();
+ char *pSubString = strstr(componentName, ".dsmode");
+ if(pSubString)
+ {
+ optComponentName[pSubString - componentName] = 0;
+ }
+ else if(isActive)
+ {
+ strlcat(optComponentName, ".dsmode", OMX_MAX_STRINGNAME_SIZE);
+ }
+ cmp_index = get_cmp_index(optComponentName);
+ }
+ dlclose(libhandle);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Failed to load dsmode library");
+ }
+ }
+
+ if(cmp_index < 0)
+ {
+ cmp_index = get_cmp_index(componentName);
+ strlcpy(optComponentName, componentName, OMX_MAX_STRINGNAME_SIZE);
+ }
+ if(cmp_index >= 0)
+ {
+ char value[PROPERTY_VALUE_MAX];
+ DEBUG_PRINT("getting fn pointer\n");
+
+ // Load VPP omx component for decoder if vpp
+ // property is enabled
+ if ((property_get("media.vpp.enable", value, NULL))
+ && (!strcmp("1", value) || !strcmp("true", value))) {
+ DEBUG_PRINT("VPP property is enabled");
+ if (!strcmp(core[cmp_index].so_lib_name, "libOmxVdec.so")) {
+ vpp_cmp_index = get_cmp_index("OMX.qti.vdec.vpp");
+ if (vpp_cmp_index < 0) {
+ DEBUG_PRINT_ERROR("Unable to find VPP OMX lib in registry ");
+ } else {
+ DEBUG_PRINT("Loading vpp for vdec");
+ cmp_index = vpp_cmp_index;
+ }
+ }
+ }
+
+ // dynamically load the so
+ core[cmp_index].fn_ptr =
+ omx_core_load_cmp_library(core[cmp_index].so_lib_name,
+ &core[cmp_index].so_lib_handle);
+
+
+ if(core[cmp_index].fn_ptr)
+ {
+ //Do not allow more than MAX limit for DSP audio decoders
+ if((!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxG711Dec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) &&
+ (number_of_adec_nt_session+1 > MAX_AUDIO_NT_SESSION)) {
+ DEBUG_PRINT_ERROR("Rejecting new session..Reached max limit for DSP audio decoder session");
+ pthread_mutex_unlock(&lock_core);
+ return OMX_ErrorInsufficientResources;
+ }
+ // Construct the component requested
+ // Function returns the opaque handle
+ void* pThis = (*(core[cmp_index].fn_ptr))();
+ if(pThis)
+ {
+ void *hComp = NULL;
+ hComp = qc_omx_create_component_wrapper((OMX_PTR)pThis);
+ if((eRet = qc_omx_component_init(hComp, optComponentName)) !=
+ OMX_ErrorNone)
+ {
+ DEBUG_PRINT("Component not created succesfully\n");
+ pthread_mutex_unlock(&lock_core);
+ return eRet;
+
+ }
+ qc_omx_component_set_callbacks(hComp,callBacks,appData);
+
+ if (vpp_cmp_index >= 0)
+ {
+ hnd_index = get_comp_handle_index("OMX.qti.vdec.vpp");
+ }
+ else
+ {
+ hnd_index = get_comp_handle_index(optComponentName);
+ }
+
+ if(hnd_index >= 0)
+ {
+ core[cmp_index].inst[hnd_index]= *handle = (OMX_HANDLETYPE) hComp;
+ }
+ else
+ {
+ DEBUG_PRINT("OMX_GetHandle:NO free slot available to store Component Handle\n");
+ pthread_mutex_unlock(&lock_core);
+ return OMX_ErrorInsufficientResources;
+ }
+ DEBUG_PRINT("Component %p Successfully created\n",*handle);
+ if(!strcmp(core[cmp_index].so_lib_name,"libOmxWmaDec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxAacDec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxG711Dec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxAlacDec.so") ||
+ !strcmp(core[cmp_index].so_lib_name,"libOmxApeDec.so")) {
+
+ number_of_adec_nt_session++;
+ DEBUG_PRINT("OMX_GetHandle: number_of_adec_nt_session : %d\n",
+ number_of_adec_nt_session);
+ }
+ }
+ else
+ {
+ eRet = OMX_ErrorInsufficientResources;
+ DEBUG_PRINT("Component Creation failed\n");
+ }
+ }
+ else
+ {
+ eRet = OMX_ErrorNotImplemented;
+ DEBUG_PRINT("library couldnt return create instance fn\n");
+ }
+
+ }
+ else
+ {
+ eRet = OMX_ErrorNotImplemented;
+ DEBUG_PRINT("ERROR: Already another instance active ;rejecting \n");
+ }
+ }
+ else
+ {
+ eRet = OMX_ErrorBadParameter;
+ DEBUG_PRINT("\n OMX_GetHandle: NULL handle \n");
+ }
+ pthread_mutex_unlock(&lock_core);
+ return eRet;
+}
+/* ======================================================================
+FUNCTION
+ OMX_FreeHandle
+
+DESCRIPTION
+ Destructs the component handles.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ Error None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY
+OMX_FreeHandle(OMX_IN OMX_HANDLETYPE hComp)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ int err = 0, i = 0;
+ DEBUG_PRINT("OMXCORE API : FreeHandle %p\n", hComp);
+
+ // 0. Check that we have an active instance
+ if((i=is_cmp_handle_exists(hComp)) >=0)
+ {
+ // 1. Delete the component
+ if ((eRet = qc_omx_component_deinit(hComp)) == OMX_ErrorNone)
+ {
+ pthread_mutex_lock(&lock_core);
+ clear_cmp_handle(hComp);
+ /* Unload component library */
+ if( (i < (int)SIZE_OF_CORE) && core[i].so_lib_handle)
+ {
+ if(check_lib_unload(i))
+ {
+ DEBUG_PRINT_ERROR(" Unloading the dynamic library for %s\n",
+ core[i].name);
+ err = dlclose(core[i].so_lib_handle);
+ if(err)
+ {
+ DEBUG_PRINT_ERROR("Error %d in dlclose of lib %s\n",
+ err,core[i].name);
+ }
+ core[i].so_lib_handle = NULL;
+ }
+ if(!strcmp(core[i].so_lib_name,"libOmxWmaDec.so") ||
+ !strcmp(core[i].so_lib_name,"libOmxAacDec.so") ||
+ !strcmp(core[i].so_lib_name,"libOmxAlacDec.so") ||
+ !strcmp(core[i].so_lib_name,"libOmxApeDec.so")) {
+ if(number_of_adec_nt_session>0)
+ number_of_adec_nt_session--;
+ DEBUG_PRINT_ERROR("OMX_FreeHandle: reduced number_of_adec_nt_session %d\n",
+ number_of_adec_nt_session);
+ }
+ }
+ pthread_mutex_unlock(&lock_core);
+ }
+ else
+ {
+ DEBUG_PRINT(" OMX_FreeHandle failed on %p\n", hComp);
+ return eRet;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("OMXCORE Warning: Free Handle called with no active instances\n");
+ }
+ return OMX_ErrorNone;
+}
+/* ======================================================================
+FUNCTION
+ OMX_SetupTunnel
+
+DESCRIPTION
+ Not Implemented.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY
+OMX_SetupTunnel(OMX_IN OMX_HANDLETYPE outputComponent,
+ OMX_IN OMX_U32 outputPort,
+ OMX_IN OMX_HANDLETYPE inputComponent,
+ OMX_IN OMX_U32 inputPort)
+{
+ (void) outputComponent, (void) outputPort, (void) inputComponent, (void) inputPort;
+ /* Not supported right now */
+ DEBUG_PRINT("OMXCORE API: OMX_SetupTunnel Not implemented \n");
+ return OMX_ErrorNotImplemented;
+}
+/* ======================================================================
+FUNCTION
+ OMX_GetContentPipe
+
+DESCRIPTION
+ Not Implemented.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE
+OMX_GetContentPipe(OMX_OUT OMX_HANDLETYPE* pipe,
+ OMX_IN OMX_STRING uri)
+{
+ (void) pipe, (void) uri;
+ /* Not supported right now */
+ DEBUG_PRINT("OMXCORE API: OMX_GetContentPipe Not implemented \n");
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+FUNCTION
+ OMX_GetComponentNameEnum
+
+DESCRIPTION
+ Returns the component name associated with the index.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE OMX_APIENTRY
+OMX_ComponentNameEnum(OMX_OUT OMX_STRING componentName,
+ OMX_IN OMX_U32 nameLen,
+ OMX_IN OMX_U32 index)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ DEBUG_PRINT("OMXCORE API - OMX_ComponentNameEnum %p %d %d\n", componentName
+ ,(unsigned)nameLen
+ ,(unsigned)index);
+ if(index < SIZE_OF_CORE)
+ {
+ #ifdef _ANDROID_
+ strlcpy(componentName, core[index].name,nameLen);
+ #else
+ strncpy(componentName, core[index].name,nameLen);
+ #endif
+ }
+ else
+ {
+ eRet = OMX_ErrorNoMore;
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ OMX_GetComponentsOfRole
+
+DESCRIPTION
+ Returns the component name which can fulfill the roles passed in the
+ argument.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE
+OMX_GetComponentsOfRole(OMX_IN OMX_STRING role,
+ OMX_INOUT OMX_U32* numComps,
+ OMX_INOUT OMX_U8** compNames)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned i,j,namecount=0;
+
+ printf(" Inside OMX_GetComponentsOfRole \n");
+
+ /*If CompNames is NULL then return*/
+ if (compNames == NULL)
+ {
+ if (numComps == NULL)
+ {
+ eRet = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ *numComps = 0;
+ for (i=0; i<SIZE_OF_CORE;i++)
+ {
+ for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
+ {
+ if(!strcmp(role,core[i].roles[j]))
+ {
+ (*numComps)++;
+ }
+ }
+ }
+ }
+ return eRet;
+ }
+
+ if(numComps)
+ {
+ namecount = *numComps;
+
+ if (namecount == 0)
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ *numComps = 0;
+
+ for (i=0; i<SIZE_OF_CORE;i++)
+ {
+ for(j=0; j<OMX_CORE_MAX_CMP_ROLES && core[i].roles[j] ; j++)
+ {
+ if(!strcmp(role,core[i].roles[j]))
+ {
+ #ifdef _ANDROID_
+ strlcpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
+ #else
+ strncpy((char *)compNames[*numComps],core[i].name, OMX_MAX_STRINGNAME_SIZE);
+ #endif
+ (*numComps)++;
+ break;
+ }
+ }
+ if (*numComps == namecount)
+ {
+ break;
+ }
+ }
+ }
+ else
+ {
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ printf(" Leaving OMX_GetComponentsOfRole \n");
+ return eRet;
+}
+/* ======================================================================
+FUNCTION
+ OMX_GetRolesOfComponent
+
+DESCRIPTION
+ Returns the primary role of the components supported.
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+OMX_API OMX_ERRORTYPE
+OMX_GetRolesOfComponent(OMX_IN OMX_STRING compName,
+ OMX_INOUT OMX_U32* numRoles,
+ OMX_OUT OMX_U8** roles)
+{
+ /* Not supported right now */
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned i,j,numofroles = 0;;
+ DEBUG_PRINT("GetRolesOfComponent %s\n",compName);
+
+ if (roles == NULL)
+ {
+ if (numRoles == NULL)
+ {
+ eRet = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ *numRoles = 0;
+ for(i=0; i< SIZE_OF_CORE; i++)
+ {
+ if(!strcmp(compName,core[i].name))
+ {
+ for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
+ {
+ (*numRoles)++;
+ }
+ break;
+ }
+ }
+
+ }
+ return eRet;
+ }
+
+ if(numRoles)
+ {
+ if (*numRoles == 0)
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ numofroles = *numRoles;
+ *numRoles = 0;
+ for(i=0; i< SIZE_OF_CORE; i++)
+ {
+ if(!strcmp(compName,core[i].name))
+ {
+ for(j=0; (j<OMX_CORE_MAX_CMP_ROLES) && core[i].roles[j];j++)
+ {
+ if(roles && roles[*numRoles])
+ {
+ #ifdef _ANDROID_
+ strlcpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
+ #else
+ strncpy((char *)roles[*numRoles],core[i].roles[j],OMX_MAX_STRINGNAME_SIZE);
+ #endif
+ }
+ (*numRoles)++;
+ if (numofroles == *numRoles)
+ {
+ break;
+ }
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT("ERROR: Both Roles and numRoles Invalid\n");
+ eRet = OMX_ErrorBadParameter;
+ }
+ return eRet;
+}
+
+OMX_API OMX_BOOL
+OMXConfigParser(
+ OMX_PTR aInputParameters,
+ OMX_PTR aOutputParameters)
+{
+ OMX_BOOL Status = OMX_TRUE;
+ VideoOMXConfigParserOutputs *aOmxOutputParameters;
+ OMXConfigParserInputs *aOmxInputParameters;
+ aOmxOutputParameters = (VideoOMXConfigParserOutputs *)aOutputParameters;
+ aOmxInputParameters = (OMXConfigParserInputs *)aInputParameters;
+
+ aOmxOutputParameters->width = 176; //setting width to QCIF
+ aOmxOutputParameters->height = 144; //setting height to QCIF
+
+ //TODO
+ //Qcom component do not use the level/profile from IL client .They are parsing the first buffer
+ //sent in ETB so for now setting the defalut values . Going farward we can call
+ //QC parser here.
+ if (0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.avc"))
+ {
+ aOmxOutputParameters->profile = 66; //minimum supported h264 profile - setting to baseline profile
+ aOmxOutputParameters->level = 0; // minimum supported h264 level
+ }
+ else if ((0 == strcmp(aOmxInputParameters->cComponentRole, (OMX_STRING)"video_decoder.mpeg4")) || (0 == strcmp(aOmxInputParameters ->cComponentRole, (OMX_STRING)"video_decoder.h263")))
+ {
+ aOmxOutputParameters->profile = 8; //minimum supported h263/mpeg4 profile
+ aOmxOutputParameters->level = 0; // minimum supported h263/mpeg4 level
+ }
+
+ return Status;
+}
diff --git a/msmcobalt/mm-core/src/common/qc_omx_core.h b/msmcobalt/mm-core/src/common/qc_omx_core.h
new file mode 100644
index 0000000..95a1776
--- /dev/null
+++ b/msmcobalt/mm-core/src/common/qc_omx_core.h
@@ -0,0 +1,72 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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
+
+ This module contains the definitions of the OpenMAX core.
+
+*//*========================================================================*/
+
+#ifndef QC_OMX_CORE_H
+#define QC_OMX_CORE_H
+
+#include "qc_omx_common.h" // OMX API
+#include <string.h>
+
+#define OMX_COMP_MAX_INST 16
+
+typedef struct _omx_core_cb_type
+{
+ char* name;// Component name
+ create_qc_omx_component fn_ptr;// create instance fn ptr
+ void* inst[OMX_COMP_MAX_INST];// Instance handle
+ void* so_lib_handle;// So Library handle
+ char* so_lib_name;// so directory
+ char* roles[OMX_CORE_MAX_CMP_ROLES];// roles played
+}omx_core_cb_type;
+
+typedef struct
+{
+ OMX_U32 width;
+ OMX_U32 height;
+ OMX_U32 profile;
+ OMX_U32 level;
+} VideoOMXConfigParserOutputs;
+
+
+typedef struct
+{
+ OMX_U8* inPtr; //pointer to codec configuration header
+ OMX_U32 inBytes; //length of codec configuration header
+ OMX_STRING cComponentRole; //OMX component codec type
+ OMX_STRING cComponentName; //OMX component name
+} OMXConfigParserInputs;
+
+#endif
+
diff --git a/msmcobalt/mm-core/src/default/qc_registry_table.c b/msmcobalt/mm-core/src/default/qc_registry_table.c
new file mode 100644
index 0000000..ed0ab56
--- /dev/null
+++ b/msmcobalt/mm-core/src/default/qc_registry_table.c
@@ -0,0 +1,62 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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
+
+ This module contains a dummy registry table for the QCOM's OpenMAX core
+ with placeholders for actual values
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.xxx.yyy.zzz",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ #ifdef _ANDROID_
+ "abc.so",
+ #else
+ "efg.so.1",
+ #endif
+ {
+ "ijk.lmn"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/default/qc_registry_table_android.c b/msmcobalt/mm-core/src/default/qc_registry_table_android.c
new file mode 100644
index 0000000..5eb170c
--- /dev/null
+++ b/msmcobalt/mm-core/src/default/qc_registry_table_android.c
@@ -0,0 +1,59 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2009, 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
+
+ This module contains a dummy registry table for the QCOM's OpenMAX core
+ with placeholders for actual values
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.xxx.yyy.zzz",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "abc.so",
+ {
+ "efg.ijk"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8953/registry_table.c b/msmcobalt/mm-core/src/msm8953/registry_table.c
new file mode 100755
index 0000000..48831f3
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8953/registry_table.c
@@ -0,0 +1,679 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2015-2016, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qti.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.g711mlaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Dec.so",
+ {
+ "audio_decoder.g711"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.g711alaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Dec.so",
+ {
+ "audio_decoder.g711"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.alac.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDecSw.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.ape.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDecSw.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrwb"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.g711mlaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Enc.so",
+ {
+ "audio_encoder.g711"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.g711alaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Enc.so",
+ {
+ "audio_encoder.g711"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qti.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8953/registry_table_android.c b/msmcobalt/mm-core/src/msm8953/registry_table_android.c
new file mode 100755
index 0000000..0d8c8ca
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8953/registry_table_android.c
@@ -0,0 +1,770 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2015-2016, 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
+
+ This module contains the registry table for the QTI's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+{
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qti.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.g711mlaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Dec.so",
+ {
+ "audio_decoder.g711"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.g711alaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Dec.so",
+ {
+ "audio_decoder.g711"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.alac.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDecSw.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.ape.sw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDecSw.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+{
+ "OMX.qcom.audio.encoder.amrwb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrwb"
+ }
+ },
+{
+ "OMX.qcom.audio.encoder.g711mlaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Enc.so",
+ {
+ "audio_encoder.g711"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.g711alaw",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxG711Enc.so",
+ {
+ "audio_encoder.g711"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.101"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp4"
+ }
+ },
+ {
+ "OMX.qti.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8992/registry_table.c b/msmcobalt/mm-core/src/msm8992/registry_table.c
new file mode 100644
index 0000000..27cb90f
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8992/registry_table.c
@@ -0,0 +1,479 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014 - 2016, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qti.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8992/registry_table_android.c b/msmcobalt/mm-core/src/msm8992/registry_table_android.c
new file mode 100644
index 0000000..425e3f9
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8992/registry_table_android.c
@@ -0,0 +1,574 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014 - 2016, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+{
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qti.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxSwVencHevc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play.generic",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.role.generic"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8994/registry_table.c b/msmcobalt/mm-core/src/msm8994/registry_table.c
new file mode 100644
index 0000000..eb1d824
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8994/registry_table.c
@@ -0,0 +1,463 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014 - 2016, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8994/registry_table_android.c b/msmcobalt/mm-core/src/msm8994/registry_table_android.c
new file mode 100644
index 0000000..9bcdbc2
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8994/registry_table_android.c
@@ -0,0 +1,638 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014 - 2016, 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
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play.generic",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.role.generic"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8996/registry_table.c b/msmcobalt/mm-core/src/msm8996/registry_table.c
new file mode 100644
index 0000000..fbfe2c8
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8996/registry_table.c
@@ -0,0 +1,573 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014-2016, 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
+
+ This module contains the registry table for the OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.alac.sw",
+ NULL, // Create instance function
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDecSw.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.ape.sw",
+ NULL, // Create instance function
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDecSw.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qti.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msm8996/registry_table_android.c b/msmcobalt/mm-core/src/msm8996/registry_table_android.c
new file mode 100644
index 0000000..f574ad4
--- /dev/null
+++ b/msmcobalt/mm-core/src/msm8996/registry_table_android.c
@@ -0,0 +1,797 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014-2016, 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
+
+ This module contains the registry table for the OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.alac.sw",
+ NULL, // Create instance function
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDecSw.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.ape.sw",
+ NULL, // Create instance function
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDecSw.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play.generic",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.role.generic"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qti.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msmcobalt/registry_table.c b/msmcobalt/mm-core/src/msmcobalt/registry_table.c
new file mode 100644
index 0000000..627d1e7
--- /dev/null
+++ b/msmcobalt/mm-core/src/msmcobalt/registry_table.c
@@ -0,0 +1,559 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2016, 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
+
+ This module contains the registry table for the OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8",
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.dsd",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxDsdDec.so",
+ {
+ "audio_decoder.dsd"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qti.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-core/src/msmcobalt/registry_table_android.c b/msmcobalt/mm-core/src/msmcobalt/registry_table_android.c
new file mode 100644
index 0000000..fbd9829
--- /dev/null
+++ b/msmcobalt/mm-core/src/msmcobalt/registry_table_android.c
@@ -0,0 +1,813 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2016, 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
+
+ This module contains the registry table for the OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+ {
+ "OMX.qcom.video.decoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.avc.secure.dsmode",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVideoDSMode.so",
+ {
+ "video_decoder.avc"
+ }
+ },
+
+ {
+ "OMX.qcom.video.decoder.divx4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.divx311",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.divx"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg4.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.mpeg2.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.mpeg2"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vc1.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.wmv.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vc1"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.decoder.vp9.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVdec.so",
+ {
+ "video_decoder.vp9"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.mpeg4",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.mpeg4"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.h263",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.h263"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.avc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.avc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.vp8",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.vp8"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.video.encoder.hevc.secure",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVenc.so",
+ {
+ "video_encoder.hevc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.Qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Dec.so",
+ {
+ "audio_decoder.Qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcDec.so",
+ {
+ "audio_decoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wma10Pro",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.wmaLossLess",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxWmaDec.so",
+ {
+ "audio_decoder.wma"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.amrwbplus",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrwbplusDec.so",
+ {
+ "audio_decoder.awbplus"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.alac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDec.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.alac.sw",
+ NULL, // Create instance function
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAlacDecSw.so",
+ {
+ "audio_decoder.alac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.ape",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDec.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.ape.sw",
+ NULL, // Create instance function
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxApeDecSw.so",
+ {
+ "audio_decoder.ape"
+ }
+ },
+ {
+ "OMX.qti.audio.decoder.dsd",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxDsdDec.so",
+ {
+ "audio_decoder.dsd"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacEnc.so",
+ {
+ "audio_encoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.qcelp13",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxQcelp13Enc.so",
+ {
+ "audio_encoder.qcelp13"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.evrc",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxEvrcEnc.so",
+ {
+ "audio_encoder.evrc"
+ }
+ },
+ {
+ "OMX.qcom.audio.encoder.amrnb",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAmrEnc.so",
+ {
+ "audio_encoder.amrnb"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.aac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "OMX.qcom.audio.decoder.multiaac",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxAacDec.so",
+ {
+ "audio_decoder.aac"
+ }
+ },
+ {
+ "AIV.play.generic",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libAivPlay.so",
+ {
+ "AIV.play.role.generic"
+ }
+ },
+ {
+ "OMX.qcom.file.muxer",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxMux.so",
+ {
+ "container_muxer.mp2"
+ }
+ },
+ {
+ "OMX.qti.vdec.vpp",
+ NULL, // Create instance function
+ // Unique instance handle
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ },
+ NULL, // Shared object library handle
+ "libOmxVpp.so",
+ {
+ "video_decoder.vpp"
+ }
+ }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/msmcobalt/mm-video-v4l2/Android.mk b/msmcobalt/mm-video-v4l2/Android.mk
new file mode 100644
index 0000000..6361f9b
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/msmcobalt/mm-video-v4l2/vidc/Android.mk b/msmcobalt/mm-video-v4l2/vidc/Android.mk
new file mode 100644
index 0000000..5c069fe
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/Android.mk
@@ -0,0 +1,2 @@
+LOCAL_PATH := $(call my-dir)
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/msmcobalt/mm-video-v4l2/vidc/common/Android.mk b/msmcobalt/mm-video-v4l2/vidc/common/Android.mk
new file mode 100644
index 0000000..22d838f
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/common/Android.mk
@@ -0,0 +1,51 @@
+ROOT_DIR := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PATH:= $(ROOT_DIR)
+
+# ---------------------------------------------------------------------------------
+# Common definitons
+# ---------------------------------------------------------------------------------
+
+libmm-vidc-def := -g -O3 -Dlrintf=_ffix_r
+libmm-vidc-def += -D__align=__alignx
+libmm-vidc-def += -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\)
+libmm-vidc-def += -DT_ARM
+libmm-vidc-def += -Dinline=__inline
+libmm-vidc-def += -D_ANDROID_
+libmm-vidc-def += -Werror
+libmm-vidc-def += -D_ANDROID_ICS_
+
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxVidcCommon)
+# ---------------------------------------------------------------------------------
+
+libmm-vidc-inc := $(LOCAL_PATH)/inc
+libmm-vidc-inc += $(QCOM_MEDIA_ROOT)/mm-core/inc
+libmm-vidc-inc += $(TARGET_OUT_HEADERS)/qcom/display
+libmm-vidc-inc += $(QCOM_MEDIA_ROOT)/libc2dcolorconvert
+libmm-vidc-inc += $(TOP)/frameworks/av/include/media/stagefright
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+libmm-vidc-inc += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+endif
+
+LOCAL_MODULE := libOmxVidcCommon
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libmm-vidc-def)
+LOCAL_C_INCLUDES := $(libmm-vidc-inc)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := liblog libutils libcutils libdl
+
+LOCAL_SRC_FILES := src/extra_data_handler.cpp
+LOCAL_SRC_FILES += src/vidc_color_converter.cpp
+
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
+
+include $(BUILD_STATIC_LIBRARY)
+
+# ---------------------------------------------------------------------------------
+# END
+# ---------------------------------------------------------------------------------
diff --git a/msmcobalt/mm-video-v4l2/vidc/common/inc/extra_data_handler.h b/msmcobalt/mm-video-v4l2/vidc/common/inc/extra_data_handler.h
new file mode 100644
index 0000000..dd1af29
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/common/inc/extra_data_handler.h
@@ -0,0 +1,84 @@
+/*--------------------------------------------------------------------------
+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 <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include "OMX_QCOMExtns.h"
+#include<linux/msm_vidc_dec.h>
+#include<linux/msm_vidc_enc.h>
+
+#ifdef _ANDROID_
+extern "C" {
+#include<utils/Log.h>
+}
+#endif // _ANDROID_
+
+#include "vidc_debug.h"
+#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(void);
+ 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_OTHER_EXTRADATATYPE *pExtra);
+};
+
+#endif
diff --git a/msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_color_converter.h b/msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_color_converter.h
new file mode 100644
index 0000000..5361c11
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_color_converter.h
@@ -0,0 +1,55 @@
+/*--------------------------------------------------------------------------
+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 <dlfcn.h>
+#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);
+ bool get_output_filled_length(unsigned int &filled_length);
+ int get_src_format();
+ void close();
+ private:
+ C2DColorConverterBase *c2dcc;
+ void *mLibHandle;
+ ColorConvertFormat src_format;
+ createC2DColorConverter_t *mConvertOpen;
+ destroyC2DColorConverter_t *mConvertClose;
+};
diff --git a/msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_debug.h b/msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_debug.h
new file mode 100644
index 0000000..3d5bbb5
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/common/inc/vidc_debug.h
@@ -0,0 +1,113 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013 - 2016, 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 __VIDC_DEBUG_H__
+#define __VIDC_DEBUG_H__
+
+#ifdef _ANDROID_
+#include <cstdio>
+#include <pthread.h>
+#include <sys/mman.h>
+
+enum {
+ PRIO_ERROR=0x1,
+ PRIO_INFO=0x1,
+ PRIO_HIGH=0x2,
+ PRIO_LOW=0x4
+};
+
+extern int debug_level;
+
+#undef DEBUG_PRINT_ERROR
+#define DEBUG_PRINT_ERROR(fmt, args...) ({ \
+ if (debug_level & PRIO_ERROR) \
+ ALOGE(fmt,##args); \
+ })
+#undef DEBUG_PRINT_INFO
+#define DEBUG_PRINT_INFO(fmt, args...) ({ \
+ if (debug_level & PRIO_INFO) \
+ ALOGI(fmt,##args); \
+ })
+#undef DEBUG_PRINT_LOW
+#define DEBUG_PRINT_LOW(fmt, args...) ({ \
+ if (debug_level & PRIO_LOW) \
+ ALOGD(fmt,##args); \
+ })
+#undef DEBUG_PRINT_HIGH
+#define DEBUG_PRINT_HIGH(fmt, args...) ({ \
+ if (debug_level & PRIO_HIGH) \
+ ALOGD(fmt,##args); \
+ })
+#else
+#define DEBUG_PRINT_ERROR printf
+#define DEBUG_PRINT_INFO printf
+#define DEBUG_PRINT_LOW printf
+#define DEBUG_PRINT_HIGH printf
+#endif
+
+#define VALIDATE_OMX_PARAM_DATA(ptr, paramType) \
+ { \
+ if (ptr == NULL) { return OMX_ErrorBadParameter; } \
+ paramType *p = reinterpret_cast<paramType *>(ptr); \
+ if (p->nSize < sizeof(paramType)) { \
+ ALOGE("Insufficient object size(%u) v/s expected(%zu) for type %s",\
+ (unsigned int)p->nSize, sizeof(paramType), #paramType); \
+ return OMX_ErrorBadParameter; \
+ } \
+ } \
+
+class auto_lock {
+ public:
+ auto_lock(pthread_mutex_t &lock)
+ : mLock(lock) {
+ pthread_mutex_lock(&mLock);
+ }
+ ~auto_lock() {
+ pthread_mutex_unlock(&mLock);
+ }
+ private:
+ pthread_mutex_t &mLock;
+};
+
+class AutoUnmap {
+ void *vaddr;
+ int size;
+
+ public:
+ AutoUnmap(void *vaddr, int size) {
+ this->vaddr = vaddr;
+ this->size = size;
+ }
+
+ ~AutoUnmap() {
+ if (vaddr)
+ munmap(vaddr, size);
+ }
+};
+
+#endif
diff --git a/msmcobalt/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp b/msmcobalt/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp
new file mode 100644
index 0000000..187eb77
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp
@@ -0,0 +1,551 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 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"
+
+int debug_level = PRIO_ERROR;
+
+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("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
+ (unsigned int)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("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
+ (unsigned int)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("In %s() bit_ptr/byte_ptr :%u/%u/%x", __func__, (unsigned int)bit_ptr,
+ (unsigned int)byte_ptr, rbsp_buf[byte_ptr]);
+
+ DEBUG_PRINT_LOW("In %s() bin/num_bits : %x/%u", __func__, (unsigned)bins, (unsigned int)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("In %s() symbol : %u", __func__, (unsigned int)symbol);
+ return symbol;
+}
+
+OMX_U32 extra_data_handler::parse_frame_pack(void)
+{
+ 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("ERROR: In %s() Start code not found", __func__);
+ return -1;
+ }
+
+ forbidden_zero_bit = (buf[i] & 0x80) >>7;
+
+ if (forbidden_zero_bit) {
+ DEBUG_PRINT_ERROR("ERROR: In %s() Non-zero forbidden bit", __func__);
+ return -1;
+ }
+
+ nal_ref_idc = (buf[i] & 0x60) >>5;
+ DEBUG_PRINT_LOW("In %s() nal_ref_idc ; %u", __func__, (unsigned int)nal_ref_idc);
+
+ nal_unit_type = (buf[i++] & 0x1F);
+
+ while (i<len) {
+ if (!(buf[i] + buf[i+1]) && (buf[i+2] == H264_EMULATION_BYTE) &&
+ (i+2 < len)) {
+ rbsp_buf[j++] = buf[i++];
+ rbsp_buf[j++] = buf[i++];
+ i++;
+ } else
+ rbsp_buf[j++] = buf[i++];
+ }
+
+ return nal_unit_type;
+}
+OMX_S32 extra_data_handler::parse_sei(OMX_U8 *buffer, OMX_U32 buffer_length)
+{
+ OMX_U32 nal_unit_type, payload_type = 0, payload_size = 0;
+ OMX_U32 marker = 0, pad = 0xFF;
+
+ nal_unit_type = parse_rbsp(buffer, buffer_length);
+
+ if (nal_unit_type != NAL_TYPE_SEI) {
+ DEBUG_PRINT_ERROR("ERROR: In %s() - Non SEI NAL ", __func__);
+ return -1;
+ } else {
+
+ while (rbsp_buf[byte_ptr] == 0xFF)
+ payload_type += rbsp_buf[byte_ptr++];
+
+ payload_type += rbsp_buf[byte_ptr++];
+
+ DEBUG_PRINT_LOW("In %s() payload_type : %u", __func__, (unsigned int)payload_type);
+
+ while (rbsp_buf[byte_ptr] == 0xFF)
+ payload_size += rbsp_buf[byte_ptr++];
+
+ payload_size += rbsp_buf[byte_ptr++];
+
+ DEBUG_PRINT_LOW("In %s() payload_size : %u", __func__, (unsigned int)payload_size);
+
+ switch (payload_type) {
+ case SEI_PAYLOAD_FRAME_PACKING_ARRANGEMENT:
+ DEBUG_PRINT_LOW("In %s() Frame Packing SEI ", __func__);
+ parse_frame_pack();
+ break;
+ default:
+ DEBUG_PRINT_LOW("INFO: In %s() Not Supported SEI NAL ", __func__);
+ break;
+ }
+ }
+
+ if (bit_ptr != 8) {
+ marker = d_u(1);
+
+ if (marker) {
+ if (bit_ptr != 8) {
+ pad = d_u(bit_ptr);
+
+ if (pad) {
+ DEBUG_PRINT_ERROR("ERROR: In %s() padding Bits Error in SEI",
+ __func__);
+ return -1;
+ }
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: In %s() Marker Bit Error in SEI",
+ __func__);
+ return -1;
+ }
+ }
+
+ DEBUG_PRINT_LOW("In %s() payload_size : %u/%u", __func__,
+ (unsigned int)payload_size, (unsigned int)byte_ptr);
+ return 1;
+}
+
+OMX_S32 extra_data_handler::parse_ltrinfo(OMX_OTHER_EXTRADATATYPE *pExtra)
+{
+ OMX_U32 *pLTR;
+ pExtra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoLTRInfo;
+ pLTR = (OMX_U32* )pExtra + 5;
+ DEBUG_PRINT_HIGH("ExtraData LTR ID %u", (unsigned int)*pLTR);
+ 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 *)(void *)pExtra->data;
+ OMX_U32 num_slices = *data;
+ DEBUG_PRINT_LOW("number of slices = %u", (unsigned int)num_slices);
+
+ if ((4 + num_slices * 8) != (OMX_U32)pExtra->nDataSize) {
+ DEBUG_PRINT_ERROR("unknown error in slice info extradata");
+ return -1;
+ }
+
+ for (unsigned 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[%u] "
+ "for slice[%u]", (unsigned)(*(OMX_U32 *)(pBuffer + slice_offset)),
+ (unsigned int)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 = %u/%u",
+ i, (unsigned int)slice_offset, (unsigned int)slice_size);
+ }
+
+ if (pBufHdr->nFilledLen != total_size) {
+ DEBUG_PRINT_ERROR("frame_size[%u] is not equal to "
+ "total slices size[%u]", (unsigned int)pBufHdr->nFilledLen, (unsigned int)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__, (unsigned)buf_hdr->nFlags);
+
+ if (buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
+
+ OMX_OTHER_EXTRADATATYPE *extra_data = (OMX_OTHER_EXTRADATATYPE *)
+ ((unsigned long)(buf_hdr->pBuffer + buf_hdr->nOffset +
+ buf_hdr->nFilledLen + 3)&(~3));
+
+ while (extra_data &&
+ ((unsigned long)extra_data > (unsigned long)buf_hdr->pBuffer) &&
+ ((unsigned long)extra_data < (unsigned long)buf_hdr->pBuffer + buf_hdr->nAllocLen)) {
+
+ DEBUG_PRINT_LOW("extradata(%p): nSize = 0x%x, eType = 0x%x,"
+ " nDataSize = 0x%x", extra_data, (unsigned int)extra_data->nSize,
+ extra_data->eType, (unsigned int)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 %u found, "
+ "parsing it", (unsigned int)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 %u bytes",
+ (unsigned int)extra_data->nSize);
+ } else if (extra_data->eType == VEN_EXTRADATA_SLICEINFO) {
+ DEBUG_PRINT_LOW("Extradata SliceInfo of size %u found, "
+ "parsing it", (unsigned int)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(extra_data);
+ }
+
+#endif
+ else {
+ DEBUG_PRINT_ERROR("Unknown extradata(%p) found, nSize = 0x%x, "
+ "eType = 0x%x, nDataSize = 0x%x", extra_data,
+ (unsigned int)extra_data->nSize, extra_data->eType, (unsigned int)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("%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("%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("%s bin : %x/%u", __func__, (unsigned)symbol, (unsigned int)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("%sstream byte/rem_bits %x/%u", __func__,
+ (unsigned)rbsp_buf[byte_ptr], (unsigned int)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("%s 2 stream byte/rem_bits %x/%u", __func__,
+ (unsigned)rbsp_buf[byte_ptr], (unsigned int)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("%s bin : %x", __func__, (unsigned)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("%s rbsp length %u", __func__, (unsigned int)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 *) (buf_hdr->pBuffer +
+ buf_hdr->nOffset + buf_hdr->nFilledLen);
+ OMX_U32 msg_size;
+
+ if (buf_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ DEBUG_PRINT_LOW("%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/msmcobalt/mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp b/msmcobalt/mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp
new file mode 100644
index 0000000..413b27b
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/common/src/vidc_color_converter.cpp
@@ -0,0 +1,189 @@
+/*--------------------------------------------------------------------------
+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.
+--------------------------------------------------------------------------*/
+#define LOG_TAG "OMX_C2D"
+
+#include <utils/Log.h>
+#include <gralloc_priv.h>
+#include "vidc_color_converter.h"
+#include "vidc_debug.h"
+
+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("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("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("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("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_HIGH("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("Status of getbuffer is %d", cret);
+ ret = (cret)?false:true;
+ buf_size = bufferreq.size;
+ }
+
+ return ret;
+}
+
+bool omx_c2d_conv::get_output_filled_length(unsigned int &filled_length)
+{
+ bool ret = false;
+ C2DBuffReq req;
+ filled_length = 0;
+
+ if (c2dcc) {
+ int cret = c2dcc->getBuffReq(C2D_OUTPUT, &req);
+ DEBUG_PRINT_LOW("Status of getBuffReq is %d", cret);
+ if (!cret && (req.bpp.denominator > 0)) {
+ filled_length = (req.stride * req.sliceHeight * req.bpp.numerator);
+ filled_length /= req.bpp.denominator;
+ ret = true;
+ }
+ }
+
+ return ret;
+}
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/Android.mk b/msmcobalt/mm-video-v4l2/vidc/vdec/Android.mk
new file mode 100644
index 0000000..287bba7
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/Android.mk
@@ -0,0 +1,161 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# ---------------------------------------------------------------------------------
+# Common definitons
+# ---------------------------------------------------------------------------------
+
+libmm-vdec-def := -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\)
+libmm-vdec-def += -D__align=__alignx
+libmm-vdec-def += -Dinline=__inline
+libmm-vdec-def += -g -O3
+libmm-vdec-def += -DIMAGE_APPS_PROC
+libmm-vdec-def += -D_ANDROID_
+libmm-vdec-def += -DCDECL
+libmm-vdec-def += -DT_ARM
+libmm-vdec-def += -DNO_ARM_CLZ
+libmm-vdec-def += -UENABLE_DEBUG_LOW
+libmm-vdec-def += -UENABLE_DEBUG_HIGH
+libmm-vdec-def += -DENABLE_DEBUG_ERROR
+libmm-vdec-def += -UINPUT_BUFFER_LOG
+libmm-vdec-def += -UOUTPUT_BUFFER_LOG
+libmm-vdec-def += -Wno-parentheses
+libmm-vdec-def += -D_ANDROID_ICS_
+libmm-vdec-def += -D_MSM8974_
+libmm-vdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT
+libmm-vdec-def += -DMAX_RES_1080P
+libmm-vdec-def += -DMAX_RES_1080P_EBI
+
+TARGETS_THAT_USE_HEVC_ADSP_HEAP := msm8226 msm8974
+TARGETS_THAT_HAVE_VENUS_HEVC := apq8084 msm8994 msm8996
+TARGETS_THAT_SUPPORT_UBWC := msm8996 msm8953 msmcobalt
+TARGETS_THAT_NEED_SW_VDEC := msm8937
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_USE_HEVC_ADSP_HEAP)),true)
+libmm-vdec-def += -D_HEVC_USE_ADSP_HEAP_
+endif
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_HAVE_VENUS_HEVC)),true)
+libmm-vdec-def += -DVENUS_HEVC
+endif
+
+ifeq ($(TARGET_BOARD_PLATFORM),msm8610)
+libmm-vdec-def += -DSMOOTH_STREAMING_DISABLED
+libmm-vdec-def += -DH264_PROFILE_LEVEL_CHECK
+endif
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_SUPPORT_UBWC)),true)
+libmm-vdec-def += -D_UBWC_
+endif
+
+ifeq ($(TARGET_USES_ION),true)
+libmm-vdec-def += -DUSE_ION
+endif
+
+ifneq (1,$(filter 1,$(shell echo "$$(( $(PLATFORM_SDK_VERSION) >= 18 ))" )))
+libmm-vdec-def += -DANDROID_JELLYBEAN_MR1=1
+endif
+
+ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)),true)
+libmm-vdec-def += -DMASTER_SIDE_CP
+endif
+
+include $(CLEAR_VARS)
+
+# Common Includes
+libmm-vdec-inc := $(LOCAL_PATH)/inc
+libmm-vdec-inc += $(QCOM_MEDIA_ROOT)/mm-video-v4l2/vidc/common/inc
+libmm-vdec-inc += $(QCOM_MEDIA_ROOT)/mm-core/inc
+libmm-vdec-inc += $(TARGET_OUT_HEADERS)/qcom/display
+libmm-vdec-inc += $(TARGET_OUT_HEADERS)/adreno
+libmm-vdec-inc += $(TOP)/frameworks/native/include/media/openmax
+libmm-vdec-inc += $(TOP)/frameworks/native/include/media/hardware
+libmm-vdec-inc += $(QCOM_MEDIA_ROOT)/libc2dcolorconvert
+libmm-vdec-inc += $(TOP)/frameworks/av/include/media/stagefright
+libmm-vdec-inc += $(TARGET_OUT_HEADERS)/mm-video/SwVdec
+libmm-vdec-inc += $(TARGET_OUT_HEADERS)/mm-video/swvdec
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+libmm-vdec-inc += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+endif
+
+ifeq ($(PLATFORM_SDK_VERSION), 18) #JB_MR2
+libmm-vdec-def += -DANDROID_JELLYBEAN_MR2=1
+libmm-vdec-inc += $(QCOM_MEDIA_ROOT)/libstagefrighthw
+endif
+
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+# Common Dependencies
+libmm-vdec-add-dep := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
+
+ifeq ($(call is-platform-sdk-version-at-least, 19),true)
+# This feature is enabled for Android KK+
+libmm-vdec-def += -DADAPTIVE_PLAYBACK_SUPPORTED
+endif
+
+ifeq ($(call is-platform-sdk-version-at-least, 22),true)
+# This feature is enabled for Android LMR1
+libmm-vdec-def += -DFLEXYUV_SUPPORTED
+endif
+
+ifeq ($(TARGET_USES_MEDIA_EXTENSIONS),true)
+libmm-vdec-def += -DALLOCATE_OUTPUT_NATIVEHANDLE
+endif
+
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxVdec)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libOmxVdec
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libmm-vdec-def) -Werror
+LOCAL_C_INCLUDES += $(libmm-vdec-inc)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-vdec-add-dep)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils libdl
+
+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/hevc_utils.cpp
+LOCAL_STATIC_LIBRARIES := libOmxVidcCommon
+LOCAL_SRC_FILES += src/omx_vdec_v4l2.cpp
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxSwVdec)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+ifneq "$(wildcard $(QCPATH) )" ""
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_NEED_SW_VDEC)),true)
+
+LOCAL_MODULE := libOmxSwVdec
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libmm-vdec-def)
+LOCAL_C_INCLUDES += $(libmm-vdec-inc)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-vdec-add-dep)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := liblog libcutils
+LOCAL_SHARED_LIBRARIES += libswvdec
+
+LOCAL_SRC_FILES := src/omx_swvdec.cpp
+LOCAL_SRC_FILES += src/omx_swvdec_utils.cpp
+
+include $(BUILD_SHARED_LIBRARY)
+endif
+endif
+
+# ---------------------------------------------------------------------------------
+# END
+# ---------------------------------------------------------------------------------
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/inc/Map.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/Map.h
new file mode 100644
index 0000000..a222eb2
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/Map.h
@@ -0,0 +1,244 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, 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 _MAP_H_
+#define _MAP_H_
+
+#include <stdio.h>
+
+template <typename T,typename T2>
+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<T,T2> *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 <typename T,typename T2>
+T2 Map<T,T2>::find(T d1)
+{
+ tmp = head;
+
+ while (tmp) {
+ if (tmp->data == d1) {
+ return tmp->data2;
+ }
+
+ tmp = tmp->next;
+ }
+
+ return 0;
+}
+
+ template <typename T,typename T2>
+T Map<T,T2>::find_ele(T d1)
+{
+ tmp = head;
+
+ while (tmp) {
+ if (tmp->data == d1) {
+ return tmp->data;
+ }
+
+ tmp = tmp->next;
+ }
+
+ return 0;
+}
+
+ template <typename T,typename T2>
+T2 Map<T,T2>::begin()
+{
+ tmp = head;
+
+ if (tmp) {
+ return (tmp->data2);
+ }
+
+ return 0;
+}
+
+ template <typename T,typename T2>
+void Map<T,T2>::show()
+{
+ tmp = head;
+
+ while (tmp) {
+ printf("%d-->%d\n",tmp->data,tmp->data2);
+ tmp = tmp->next;
+ }
+}
+
+ template <typename T,typename T2>
+int Map<T,T2>::size()
+{
+ int count =0;
+ tmp = head;
+
+ while (tmp) {
+ tmp = tmp->next;
+ count++;
+ }
+
+ return count;
+}
+
+ template <typename T,typename T2>
+void Map<T,T2>::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 <typename T,typename T2>
+bool Map<T,T2>::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 <typename T,typename T2>
+bool Map<T,T2>::eraseall()
+{
+ node *tempnode;
+ tmp = head;
+
+ while (head) {
+ tempnode = head;
+ tempnode->next = NULL;
+ head = head->next;
+ delete tempnode;
+ }
+
+ tail = head = NULL;
+ return true;
+}
+
+
+ template <typename T,typename T2>
+bool Map<T,T2>::isempty()
+{
+ if (!size_of_list) return true;
+ else return false;
+}
+
+#endif // _MAP_H_
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h
new file mode 100644
index 0000000..cc42fc1
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/decoder_driver_test.h
@@ -0,0 +1,69 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011,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 <stdio.h>
+#include <stdlib.h>
+#include "message_queue.h"
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <inttypes.h>
+#include <linux/msm_vidc_dec.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+
+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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/frameparser.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/frameparser.h
new file mode 100644
index 0000000..916390a
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/frameparser.h
@@ -0,0 +1,103 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2015, 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 <stdlib.h>
+
+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_VP9 = 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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h
new file mode 100644
index 0000000..ad05a9e
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/h264_utils.h
@@ -0,0 +1,480 @@
+/*--------------------------------------------------------------------------
+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 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 <stdio.h>
+#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 SIZE_NAL_FIELD_MAX 4
+#define BASELINE_PROFILE 66
+#define MAIN_PROFILE 77
+#define HIGH_PROFILE 100
+
+#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<uint8> nalu;
+ uint32 nalu;
+ uint32 crop_left;
+ uint32 crop_right;
+ uint32 crop_top;
+ uint32 crop_bot;
+};
+//typedef map<uint32, H264ParamNalu> H264ParamNaluSet;
+typedef Map<uint32, H264ParamNalu *> 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 NODE_STRUCT>
+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_NODE> panscan_used;
+ omx_dl_list<PANSCAN_NODE> 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);
+ OMX_U32 get_profile();
+#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 profile;
+ 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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/hevc_utils.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/hevc_utils.h
new file mode 100644
index 0000000..797d1d2
--- /dev/null
+++ b/msmcobalt/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 <stdio.h>
+#include <utils/Log.h>
+#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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/message_queue.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/message_queue.h
new file mode 100644
index 0000000..7cae154
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/message_queue.h
@@ -0,0 +1,76 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, 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 QUEUE_H
+#define QUEUE_H
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Message Queue structure */
+struct video_msgq {
+ /* Command to be executed */
+ unsigned int cmd;
+
+ unsigned int status;
+
+ /* Client-specific data */
+ void *clientdata;
+};
+
+
+/* Thread & Message Queue information */
+struct video_queue_context {
+ /* Message Queue related members */
+ pthread_mutex_t mutex;
+ sem_t sem_message;
+ int commandq_size;
+ int dataq_size;
+ struct video_msgq *ptr_dataq;
+ struct video_msgq *ptr_cmdq;
+ int write_dataq ;
+ int read_dataq;
+ int write_comq ;
+ int read_comq ;
+
+};
+
+int check_if_queue_empty ( unsigned int queuetocheck,void* queuecontext );
+
+struct video_msgq * queue_get_cmd ( void* queuecontext );
+
+int queue_post_cmdq ( void *queuecontext,
+ struct video_msgq *post_msg
+ );
+
+int queue_post_dataq ( void *queuecontext,
+ struct video_msgq *post_msg
+ );
+
+#endif /* QUEUE_H */
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/inc/mp4_utils.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/mp4_utils.h
new file mode 100644
index 0000000..93c04e7
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/mp4_utils.h
@@ -0,0 +1,169 @@
+/*--------------------------------------------------------------------------
+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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec.h
new file mode 100644
index 0000000..aaaeae7
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec.h
@@ -0,0 +1,459 @@
+/**
+ * @copyright
+ *
+ * Copyright (c) 2015-2016, 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.
+ *
+ * @file
+ *
+ * omx_swvdec.h
+ *
+ * @brief
+ *
+ * OMX software video decoder component header.
+ */
+
+#ifndef _OMX_SWVDEC_H_
+#define _OMX_SWVDEC_H_
+
+//#undef NDEBUG // uncomment to enable assertions
+
+#include <pthread.h>
+#include <semaphore.h>
+
+#include <linux/msm_ion.h>
+#include <linux/msm_vidc_dec.h>
+
+#include "qc_omx_component.h"
+
+#include "omx_swvdec_utils.h"
+
+#include "swvdec_types.h"
+
+using namespace android;
+
+/// OMX SwVdec version date
+#define OMX_SWVDEC_VERSION_DATE "2016-05-05T16:09:40+0530"
+
+#define OMX_SPEC_VERSION 0x00000101 ///< OMX specification version
+
+#define OMX_SWVDEC_NUM_INSTANCES 1 ///< number of OMX SwVdec instances
+
+#define OMX_SWVDEC_IP_BUFFER_COUNT_MIN 5 ///< OMX SwVdec minimum ip buffer count
+
+#define OMX_SWVDEC_MAX_FRAMES_PER_ETB 2 ///< maximum number of frames per ETB
+
+/// frame dimensions structure
+typedef struct {
+ unsigned int width; ///< frame width
+ unsigned int height; ///< frame height
+} FRAME_DIMENSIONS;
+
+/// frame attributes structure
+typedef struct {
+ unsigned int stride; ///< frame stride
+ unsigned int scanlines; ///< frame scanlines
+ unsigned int size; ///< frame size
+} FRAME_ATTRIBUTES;
+
+/// asynchronous thread structure
+typedef struct {
+ sem_t sem_thread_created; ///< thread created semaphore
+ sem_t sem_event; ///< event semaphore
+ pthread_t handle; ///< thread handle
+ bool created; ///< thread created?
+ bool exit; ///< thread exit variable
+} ASYNC_THREAD;
+
+/// @cond
+
+struct vdec_ion {
+ int ion_fd_device;
+ struct ion_fd_data ion_fd_data;
+ struct ion_allocation_data ion_alloc_data;
+};
+
+typedef struct {
+ OMX_BUFFERHEADERTYPE buffer_header;
+ struct vdec_ion ion_info;
+ struct vdec_bufferpayload buffer_payload;
+ SWVDEC_BUFFER buffer_swvdec;
+ bool buffer_populated;
+ unsigned int split_count;
+} OMX_SWVDEC_BUFFER_INFO;
+
+/// @endcond
+
+/// port structure
+typedef struct {
+ OMX_PARAM_PORTDEFINITIONTYPE def; ///< definition
+ OMX_BOOL enabled; ///< enabled?
+ OMX_BOOL populated; ///< populated?
+ OMX_BOOL unpopulated; ///< unpopulated?
+ OMX_BOOL flush_inprogress; ///< flush inprogress?
+ unsigned int num_pending_buffers; ///< # of pending buffers
+} OMX_SWVDEC_PORT;
+
+/// meta_buffer information structure
+typedef struct {
+ int fd; ///< file descriptor
+ int ref_count; ///< reference count
+} OMX_SWVDEC_META_BUFFER_INFO;
+
+#define DEFAULT_FRAME_WIDTH 1920 ///< default frame width
+#define DEFAULT_FRAME_HEIGHT 1080 ///< default frame height
+
+#define MAX(x, y) (((x) > (y)) ? (x) : (y)) ///< maximum
+#define MIN(x, y) (((x) < (y)) ? (x) : (y)) ///< minimum
+#define ALIGN(x, y) (((x) + ((y) - 1)) & (~((y) - 1)))
+ ///< align 'x' to next highest multiple of 'y'
+
+/// macro to print 'command type' string
+#define OMX_COMMANDTYPE_STRING(x) \
+ ((x == OMX_CommandStateSet) ? "OMX_CommandStateSet" : \
+ ((x == OMX_CommandFlush) ? "OMX_CommandFlush" : \
+ ((x == OMX_CommandPortDisable) ? "OMX_CommandPortDisable" : \
+ ((x == OMX_CommandPortEnable) ? "OMX_CommandPortEnable" : \
+ "unknown"))))
+
+/// macro to print 'state type' string
+#define OMX_STATETYPE_STRING(x) \
+ ((x == OMX_StateInvalid) ? "OMX_StateInvalid" : \
+ ((x == OMX_StateLoaded) ? "OMX_StateLoaded" : \
+ ((x == OMX_StateIdle) ? "OMX_StateIdle" : \
+ ((x == OMX_StateExecuting) ? "OMX_StateExecuting" : \
+ ((x == OMX_StatePause) ? "OMX_StatePause" : \
+ ((x == OMX_StateWaitForResources) ? "OMX_StateWaitForResources" : \
+ "unknown"))))))
+
+enum {
+ OMX_CORE_PORT_INDEX_IP = 0, ///< input port index
+ OMX_CORE_PORT_INDEX_OP = 1 ///< output port index
+};
+
+extern "C" {
+ OMX_API void *get_omx_component_factory_fn(void);
+};
+
+/// OMX SwVdec component class; derived from QC OMX component base class
+class omx_swvdec : public qc_omx_component
+{
+public:
+
+ omx_swvdec();
+
+ virtual ~omx_swvdec();
+
+ // derived class versions of base class pure virtual functions
+
+ OMX_ERRORTYPE component_init(OMX_STRING cmp_name);
+ OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE cmp_handle);
+ OMX_ERRORTYPE get_component_version(OMX_HANDLETYPE cmp_handle,
+ OMX_STRING cmp_name,
+ OMX_VERSIONTYPE *p_cmp_version,
+ OMX_VERSIONTYPE *p_spec_version,
+ OMX_UUIDTYPE *p_cmp_UUID);
+ OMX_ERRORTYPE send_command(OMX_HANDLETYPE cmp_handle,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param,
+ OMX_PTR p_cmd_data);
+ OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE param_index,
+ OMX_PTR p_param_data);
+ OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE param_index,
+ OMX_PTR p_param_data);
+ OMX_ERRORTYPE get_config(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE config_index,
+ OMX_PTR p_config_data);
+ OMX_ERRORTYPE set_config(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE config_index,
+ OMX_PTR p_config_data);
+ OMX_ERRORTYPE get_extension_index(OMX_HANDLETYPE cmp_handle,
+ OMX_STRING param_name,
+ OMX_INDEXTYPE *p_index_type);
+ OMX_ERRORTYPE get_state(OMX_HANDLETYPE cmp_handle,
+ OMX_STATETYPE *p_state);
+ OMX_ERRORTYPE component_tunnel_request(OMX_HANDLETYPE cmp_handle,
+ OMX_U32 port,
+ OMX_HANDLETYPE peer_component,
+ OMX_U32 peer_port,
+ OMX_TUNNELSETUPTYPE *p_tunnel_setup);
+ OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR p_app_data,
+ OMX_U32 bytes,
+ OMX_U8 *p_buffer);
+ OMX_ERRORTYPE allocate_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR p_app_data,
+ OMX_U32 bytes);
+ OMX_ERRORTYPE free_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_U32 port,
+ OMX_BUFFERHEADERTYPE *p_buffer);
+ OMX_ERRORTYPE empty_this_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr);
+ OMX_ERRORTYPE fill_this_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr);
+ OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE cmp_handle,
+ OMX_CALLBACKTYPE *p_callbacks,
+ OMX_PTR p_app_data);
+ OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR p_app_data,
+ void *egl_image);
+ OMX_ERRORTYPE component_role_enum(OMX_HANDLETYPE cmp_handle,
+ OMX_U8 *p_role,
+ OMX_U32 index);
+
+ // SwVdec callback functions
+
+ static SWVDEC_STATUS swvdec_empty_buffer_done_callback(
+ SWVDEC_HANDLE swvdec_handle,
+ SWVDEC_BUFFER *p_buffer_ip,
+ void *p_client_handle);
+ static SWVDEC_STATUS swvdec_fill_buffer_done_callback(
+ SWVDEC_HANDLE swvdec_handle,
+ SWVDEC_BUFFER *p_buffer_op,
+ void *p_client_handle);
+ static SWVDEC_STATUS swvdec_event_handler_callback(
+ SWVDEC_HANDLE swvdec_handle,
+ SWVDEC_EVENT event,
+ void *p_data,
+ void *p_client_handle);
+
+private:
+
+ OMX_STATETYPE m_state; ///< component state
+
+ unsigned int m_status_flags; ///< status flags
+
+ char m_cmp_name[OMX_MAX_STRINGNAME_SIZE]; ///< component name
+ char m_role_name[OMX_MAX_STRINGNAME_SIZE]; ///< component role name
+
+ SWVDEC_CODEC m_swvdec_codec; ///< SwVdec codec type
+ SWVDEC_HANDLE m_swvdec_handle; ///< SwVdec handle
+ bool m_swvdec_created; ///< SwVdec created?
+
+ OMX_VIDEO_CODINGTYPE m_omx_video_codingtype; ///< OMX video coding type
+ OMX_COLOR_FORMATTYPE m_omx_color_formattype; ///< OMX color format type
+
+ FRAME_DIMENSIONS m_frame_dimensions; ///< frame dimensions
+ FRAME_ATTRIBUTES m_frame_attributes; ///< frame attributes
+
+ FRAME_DIMENSIONS m_frame_dimensions_max;
+ ///< max frame dimensions for adaptive playback
+
+ ASYNC_THREAD m_async_thread; ///< asynchronous thread
+
+ omx_swvdec_queue m_queue_command; ///< command queue
+ omx_swvdec_queue m_queue_port_ip; ///< input port queue for ETBs & EBDs
+ omx_swvdec_queue m_queue_port_op; ///< output port queue for FTBs & FBDs
+
+ OMX_SWVDEC_PORT m_port_ip; ///< input port
+ OMX_SWVDEC_PORT m_port_op; ///< output port
+
+ OMX_CALLBACKTYPE m_callback; ///< IL client callback structure
+ OMX_PTR m_app_data; ///< IL client app data pointer
+
+ OMX_PRIORITYMGMTTYPE m_prio_mgmt; ///< priority management
+
+ bool m_sync_frame_decoding_mode; ///< sync frame decoding mode enabled?
+ bool m_android_native_buffers; ///< android native buffers enabled?
+
+ bool m_meta_buffer_mode_disabled; ///< meta buffer mode disabled?
+ bool m_meta_buffer_mode; ///< meta buffer mode enabled?
+ bool m_adaptive_playback_mode; ///< adaptive playback mode enabled?
+ bool m_arbitrary_bytes_mode; ///< arbitrary bytes mode enabled?
+
+ bool m_port_reconfig_inprogress; ///< port reconfiguration in progress?
+
+ bool m_dimensions_update_inprogress; ///< dimensions update in progress?
+
+ sem_t m_sem_cmd; ///< semaphore for command processing
+
+ OMX_SWVDEC_BUFFER_INFO *m_buffer_array_ip; ///< input buffer info array
+ OMX_SWVDEC_BUFFER_INFO *m_buffer_array_op; ///< output buffer info array
+
+ OMX_SWVDEC_META_BUFFER_INFO *m_meta_buffer_array; ///< metabuffer info array
+ pthread_mutex_t m_meta_buffer_array_mutex;
+ ///< mutex for metabuffer info array
+
+ std::priority_queue <OMX_TICKS,
+ std::vector<OMX_TICKS>,
+ std::greater<OMX_TICKS> > m_queue_timestamp;
+ ///< timestamp priority queue
+
+ omx_swvdec_diag m_diag; ///< diagnostics class variable
+
+ OMX_ERRORTYPE set_frame_dimensions(unsigned int width,
+ unsigned int height);
+ OMX_ERRORTYPE set_frame_attributes(OMX_COLOR_FORMATTYPE color_format);
+ OMX_ERRORTYPE set_adaptive_playback(unsigned int max_width,
+ unsigned int max_height);
+
+ OMX_ERRORTYPE get_video_port_format(
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format);
+ OMX_ERRORTYPE set_video_port_format(
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format);
+
+ OMX_ERRORTYPE get_port_definition(OMX_PARAM_PORTDEFINITIONTYPE *p_port_def);
+ OMX_ERRORTYPE set_port_definition(OMX_PARAM_PORTDEFINITIONTYPE *p_port_def);
+
+ OMX_ERRORTYPE get_supported_profilelevel(
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *p_profilelevel);
+
+ OMX_ERRORTYPE describe_color_format(DescribeColorFormatParams *p_params);
+
+ OMX_ERRORTYPE set_port_definition_qcom(
+ OMX_QCOM_PARAM_PORTDEFINITIONTYPE *p_port_def);
+
+ // functions to set SwVdec properties with OMX component properties
+
+ OMX_ERRORTYPE set_frame_dimensions_swvdec();
+ OMX_ERRORTYPE set_frame_attributes_swvdec();
+ OMX_ERRORTYPE set_adaptive_playback_swvdec();
+
+ // functions to get SwVdec properties and set OMX component properties
+
+ OMX_ERRORTYPE get_frame_dimensions_swvdec();
+ OMX_ERRORTYPE get_frame_attributes_swvdec();
+ OMX_ERRORTYPE get_buffer_requirements_swvdec(unsigned int port_index);
+
+ // buffer allocation & de-allocation functions
+ OMX_ERRORTYPE buffer_allocate_ip(OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_PTR p_app_data,
+ OMX_U32 size);
+ OMX_ERRORTYPE buffer_allocate_op(OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_PTR p_app_data,
+ OMX_U32 size);
+ OMX_ERRORTYPE buffer_allocate_ip_info_array();
+ OMX_ERRORTYPE buffer_allocate_op_info_array();
+ OMX_ERRORTYPE buffer_use_op(OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_PTR p_app_data,
+ OMX_U32 size,
+ OMX_U8 *p_buffer);
+ OMX_ERRORTYPE buffer_deallocate_ip(OMX_BUFFERHEADERTYPE *p_buffer_hdr);
+ OMX_ERRORTYPE buffer_deallocate_op(OMX_BUFFERHEADERTYPE *p_buffer_hdr);
+ void buffer_deallocate_ip_info_array();
+ void buffer_deallocate_op_info_array();
+
+ OMX_ERRORTYPE meta_buffer_array_allocate();
+ void meta_buffer_array_deallocate();
+ void meta_buffer_ref_add(unsigned int index, int fd);
+ void meta_buffer_ref_remove(unsigned int index);
+
+ OMX_BOOL port_ip_populated();
+ OMX_BOOL port_op_populated();
+
+ OMX_ERRORTYPE flush(unsigned int port_index);
+
+ int ion_memory_alloc_map(struct ion_allocation_data *p_alloc_data,
+ struct ion_fd_data *p_fd_data,
+ OMX_U32 size,
+ OMX_U32 alignment);
+ void ion_memory_free(struct vdec_ion *p_ion_buf_info);
+ void ion_flush_op(unsigned int index);
+
+ // component callback functions
+
+ void swvdec_empty_buffer_done(SWVDEC_BUFFER *p_buffer_ip);
+ void swvdec_fill_buffer_done(SWVDEC_BUFFER *p_buffer_op);
+ void swvdec_event_handler(SWVDEC_EVENT event, void *p_data);
+
+ OMX_ERRORTYPE retval_swvdec2omx(SWVDEC_STATUS retval_swvdec);
+
+ // status bits for pending events
+ enum {
+ PENDING_STATE_LOADED_TO_IDLE, ///< loaded to idle state
+ PENDING_STATE_EXECUTING_TO_IDLE, ///< executing to idle state
+ PENDING_STATE_IDLE_TO_LOADED, ///< idle to loaded state
+ PENDING_PORT_ENABLE_IP, ///< enablement of ip port
+ PENDING_PORT_ENABLE_OP, ///< enablement of op port
+ PENDING_PORT_DISABLE_IP, ///< disablement of ip port
+ PENDING_PORT_DISABLE_OP, ///< disablement of op port
+ PENDING_PORT_FLUSH_IP, ///< flush of ip port
+ PENDING_PORT_FLUSH_OP ///< flush of op port
+ };
+
+ // events raised internally
+ enum {
+ OMX_SWVDEC_EVENT_CMD, ///< command event
+ OMX_SWVDEC_EVENT_CMD_ACK, ///< command acknowledgement
+ OMX_SWVDEC_EVENT_ERROR, ///< error event
+ OMX_SWVDEC_EVENT_ETB, ///< ETB event
+ OMX_SWVDEC_EVENT_EBD, ///< EBD event
+ OMX_SWVDEC_EVENT_FTB, ///< FTB event
+ OMX_SWVDEC_EVENT_FBD, ///< FBD event
+ OMX_SWVDEC_EVENT_EOS, ///< EOS event
+ OMX_SWVDEC_EVENT_FLUSH_PORT_IP, ///< flush ip port event
+ OMX_SWVDEC_EVENT_FLUSH_PORT_OP, ///< flush op port event
+ OMX_SWVDEC_EVENT_PORT_RECONFIG, ///< port reconfig event
+ OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED ///< dimensions updated event
+ };
+
+ OMX_ERRORTYPE async_thread_create();
+ void async_thread_destroy();
+
+ static void async_thread(void *p_cmp);
+
+ void async_post_event(unsigned long event_id,
+ unsigned long event_param1,
+ unsigned long event_param2);
+
+ static void async_process_event(void *p_cmp);
+
+ OMX_ERRORTYPE async_process_event_cmd(OMX_COMMANDTYPE cmd, OMX_U32 param);
+ OMX_ERRORTYPE async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,
+ OMX_U32 param);
+ OMX_ERRORTYPE async_process_event_error(OMX_ERRORTYPE error_code);
+ OMX_ERRORTYPE async_process_event_cmd_state_set(bool *p_cmd_ack,
+ OMX_STATETYPE state_new);
+ OMX_ERRORTYPE async_process_event_cmd_flush(unsigned int port_index);
+ OMX_ERRORTYPE async_process_event_cmd_port_disable(
+ bool *p_cmd_ack,
+ unsigned int port_index);
+ OMX_ERRORTYPE async_process_event_cmd_port_enable(bool *p_cmd_ack,
+ unsigned int port_index);
+ OMX_ERRORTYPE async_process_event_etb(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index);
+ OMX_ERRORTYPE async_process_event_ftb(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index);
+ OMX_ERRORTYPE async_process_event_ebd(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index);
+ OMX_ERRORTYPE async_process_event_fbd(OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index);
+ OMX_ERRORTYPE async_process_event_eos();
+ OMX_ERRORTYPE async_process_event_flush_port_ip();
+ OMX_ERRORTYPE async_process_event_flush_port_op();
+ OMX_ERRORTYPE async_process_event_port_reconfig();
+ OMX_ERRORTYPE async_process_event_dimensions_updated();
+};
+
+#endif // #ifndef _OMX_SWVDEC_H_
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec_utils.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec_utils.h
new file mode 100644
index 0000000..cfd3676
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_swvdec_utils.h
@@ -0,0 +1,145 @@
+/**
+ * @copyright
+ *
+ * Copyright (c) 2015-2016, 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.
+ *
+ * @file
+ *
+ * omx_swvdec_utils.h
+ *
+ * @brief
+ *
+ * OMX software video decoder utility functions header.
+ */
+
+#ifndef _OMX_SWVDEC_UTILS_H_
+#define _OMX_SWVDEC_UTILS_H_
+
+#include <queue>
+#include <pthread.h>
+
+#include <cutils/log.h>
+
+extern unsigned int g_omx_swvdec_logmask;
+ ///< global OMX SwVdec logmask variable extern declaration
+
+void omx_swvdec_log_init();
+
+#define OMX_SWVDEC_LOGMASK_LOW 4 ///< 100: logmask for low priority logs
+#define OMX_SWVDEC_LOGMASK_HIGH 2 ///< 010: logmask for high priority logs
+#define OMX_SWVDEC_LOGMASK_ERROR 1 ///< 001: logmask for error priority logs
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "OMX_SWVDEC" ///< OMX SwVdec log tag
+
+/// low priority log message
+#define OMX_SWVDEC_LOG_LOW(string, ...) \
+ do { \
+ if (g_omx_swvdec_logmask & OMX_SWVDEC_LOGMASK_LOW) \
+ ALOGD("--- %s(): " string, __FUNCTION__, ##__VA_ARGS__); \
+ } while (0)
+
+/// high priority log message
+#define OMX_SWVDEC_LOG_HIGH(string, ...) \
+ do { \
+ if (g_omx_swvdec_logmask & OMX_SWVDEC_LOGMASK_HIGH) \
+ ALOGI("--- %s(): " string, __FUNCTION__, ##__VA_ARGS__); \
+ } while (0)
+
+/// error priority log message
+#define OMX_SWVDEC_LOG_ERROR(string, ...) \
+ do { \
+ if (g_omx_swvdec_logmask & OMX_SWVDEC_LOGMASK_ERROR) \
+ ALOGE("!!! %s(): " string, __FUNCTION__, ##__VA_ARGS__); \
+ } while (0)
+
+/// high priority log message for OMX SwVdec API calls
+#define OMX_SWVDEC_LOG_API(string, ...) \
+ do { \
+ if (g_omx_swvdec_logmask & OMX_SWVDEC_LOGMASK_HIGH) \
+ ALOGI(">>> %s(): " string, __FUNCTION__, ##__VA_ARGS__); \
+ } while (0)
+
+/// high priority log message for OMX SwVdec callbacks
+#define OMX_SWVDEC_LOG_CALLBACK(string, ...) \
+ do { \
+ if (g_omx_swvdec_logmask & OMX_SWVDEC_LOGMASK_HIGH) \
+ ALOGI("<<< %s(): " string, __FUNCTION__, ##__VA_ARGS__); \
+ } while (0)
+
+/// OMX SwVdec event information structure
+typedef struct {
+ unsigned long event_id; ///< event ID
+ unsigned long event_param1; ///< event parameter 1
+ unsigned long event_param2; ///< event parameter 2
+} OMX_SWVDEC_EVENT_INFO;
+
+/// OMX SwVdec queue class
+class omx_swvdec_queue
+{
+public:
+ omx_swvdec_queue();
+ ~omx_swvdec_queue();
+
+ void push(OMX_SWVDEC_EVENT_INFO *p_event_info);
+ bool pop(OMX_SWVDEC_EVENT_INFO *p_event_info);
+
+private:
+ std::queue<OMX_SWVDEC_EVENT_INFO> m_queue; ///< queue
+ pthread_mutex_t m_mutex; ///< mutex
+};
+
+#define DIAG_FILE_PATH "/data/misc/media" ///< file path
+
+/// OMX SwVdec diagnostics class
+class omx_swvdec_diag
+{
+public:
+ omx_swvdec_diag();
+ ~omx_swvdec_diag();
+
+ void dump_ip(unsigned char *p_buffer, unsigned int filled_length);
+ void dump_op(unsigned char *p_buffer,
+ unsigned int width,
+ unsigned int height,
+ unsigned int stride,
+ unsigned int scanlines);
+
+private:
+ unsigned int m_dump_ip; ///< dump input bitstream
+ unsigned int m_dump_op; ///< dump output YUV
+
+ char *m_filename_ip; ///< input filename string
+ char *m_filename_op; ///< output filename string
+
+ FILE *m_file_ip; ///< input file handle
+ FILE *m_file_op; ///< output file handle
+};
+
+#endif // #ifndef _OMX_SWVDEC_UTILS_H_
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
new file mode 100644
index 0000000..2f44cd8
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -0,0 +1,1280 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010 - 2016, 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <cstddef>
+#include <cutils/atomic.h>
+#include <qdMetaData.h>
+
+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 <linux/msm_ion.h>
+//#include <binder/MemoryHeapIon.h>
+//#else
+#endif
+#include <binder/MemoryHeapBase.h>
+#include <ui/ANativeObjectBase.h>
+extern "C" {
+#include <utils/Log.h>
+}
+#include <linux/videodev2.h>
+#include <poll.h>
+#include "hevc_utils.h"
+#define TIMEOUT 5000
+#endif // _ANDROID_
+
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+#include <media/hardware/HardwareAPI.h>
+#endif
+
+#include <unistd.h>
+
+#if defined (_ANDROID_ICS_)
+#include <gralloc_priv.h>
+#endif
+
+#include <pthread.h>
+#ifndef PC_DEBUG
+#include <semaphore.h>
+#endif
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "OMX_Skype_VideoExtensions.h"
+#include "OMX_VideoExt.h"
+#include "OMX_IndexExt.h"
+#include "qc_omx_component.h"
+#include <linux/msm_vidc_dec.h>
+#include <media/msm_vidc.h>
+#include "frameparser.h"
+#ifdef MAX_RES_1080P
+#include "mp4_utils.h"
+#endif
+#include "extra_data_handler.h"
+#include "ts_parser.h"
+#include "vidc_color_converter.h"
+#include "vidc_debug.h"
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#else
+#define PROPERTY_VALUE_MAX 92
+#endif
+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,ion_user_handle_t handle,int mapfd);
+ virtual ~VideoHeap() {}
+ private:
+ int m_ion_device_fd;
+ ion_user_handle_t 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_INDEX 64
+#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_INDEX - 1)/BITS_PER_INDEX)
+#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_INDEX)
+#define BITMASK_FLAG(mIndex) ((uint64_t)1 << ((mIndex) % BITS_PER_INDEX))
+#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 OMX_CORE_FWVGA_HEIGHT 480
+#define OMX_CORE_FWVGA_WIDTH 864
+
+#define DESC_BUFFER_SIZE (8192 * 16)
+
+#ifdef _ANDROID_
+#define MAX_NUM_INPUT_OUTPUT_BUFFERS 64
+#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 OMX_FRAMEDIMENSION_EXTRADATA 0x00200000
+#define OMX_FRAMEPACK_EXTRADATA 0x00400000
+#define OMX_QP_EXTRADATA 0x00800000
+#define OMX_BITSINFO_EXTRADATA 0x01000000
+#define OMX_VQZIPSEI_EXTRADATA 0x02000000
+#define OMX_OUTPUTCROP_EXTRADATA 0x04000000
+
+#define OMX_VUI_DISPLAY_INFO_EXTRADATA 0x08000000
+#define OMX_MPEG2_SEQDISP_INFO_EXTRADATA 0x10000000
+#define OMX_VPX_COLORSPACE_INFO_EXTRADATA 0x20000000
+#define OMX_VC1_SEQDISP_INFO_EXTRADATA 0x40000000
+#define OMX_DISPLAY_INFO_EXTRADATA 0x80000000
+#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 OMX_FRAMEDIMENSION_EXTRADATA_SIZE (sizeof(OMX_OTHER_EXTRADATATYPE) +\
+ sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION) + 3)&(~3)
+#define OMX_FRAMEPACK_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
+ sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT) + 3)&(~3))
+#define OMX_QP_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
+ sizeof(OMX_QCOM_EXTRADATA_QP) + 3)&(~3))
+#define OMX_BITSINFO_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
+ sizeof(OMX_QCOM_EXTRADATA_BITS_INFO) + 3)&(~3))
+#define OMX_VQZIPSEI_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
+ sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + 3)&(~3))
+#define OMX_USERDATA_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
+ + 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
+};
+enum vidc_perf_level {
+ VIDC_SVS = 0,
+ VIDC_NOMINAL = 1,
+ VIDC_TURBO = 2
+};
+#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 {
+ unsigned long 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_framesize frame_size;
+ 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
+};
+
+struct video_decoder_capability {
+ unsigned int min_width;
+ unsigned int max_width;
+ unsigned int min_height;
+ unsigned int max_height;
+};
+
+struct debug_cap {
+ bool in_buffer_log;
+ bool out_buffer_log;
+ bool out_meta_buffer_log;
+ char infile_name[PROPERTY_VALUE_MAX + 36];
+ char outfile_name[PROPERTY_VALUE_MAX + 36];
+ char out_ymetafile_name[PROPERTY_VALUE_MAX + 36];
+ char out_uvmetafile_name[PROPERTY_VALUE_MAX + 36];
+ char log_loc[PROPERTY_VALUE_MAX];
+ FILE *infile;
+ FILE *outfile;
+ FILE *out_ymeta_file;
+ FILE *out_uvmeta_file;
+};
+
+struct dynamic_buf_list {
+ long fd;
+ long dup_fd;
+ OMX_U32 offset;
+ OMX_U32 ref_count;
+ void *buffaddr;
+ long mapped_size;
+};
+
+struct extradata_info {
+ OMX_BOOL output_crop_updated;
+ OMX_CONFIG_RECTTYPE output_crop_rect;
+ OMX_U32 output_width;
+ OMX_U32 output_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;
+ int m_poll_efd;
+#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();
+ void buf_ref_add(int nPortIndex);
+ void buf_ref_remove();
+ OMX_BUFFERHEADERTYPE* get_omx_output_buffer_header(int index);
+ OMX_ERRORTYPE set_dpb(bool is_split_mode, int dpb_color_format);
+ OMX_ERRORTYPE decide_dpb_buffer_mode(bool force_split_mode);
+ void request_perf_level(enum vidc_perf_level perf_level);
+ int dpb_bit_depth;
+ bool async_thread_force_stop;
+ volatile bool message_thread_stop;
+ struct extradata_info m_extradata_info;
+ int m_progressive;
+
+ 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,
+ OMX_COMPONENT_FLUSH_DEFERRED = 0xF
+ };
+
+ // 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,
+ OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD = 0x18,
+ OMX_COMPONENT_CLOSE_MSG = 0x19
+ };
+
+ 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 long param1;
+ unsigned long param2;
+ unsigned long id;
+ };
+
+ struct omx_cmd_queue {
+ omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE];
+ unsigned long m_read;
+ unsigned long m_write;
+ unsigned long m_size;
+
+ omx_cmd_queue();
+ ~omx_cmd_queue();
+ bool insert_entry(unsigned long p1, unsigned long p2, unsigned long id);
+ bool pop_entry(unsigned long *p1,unsigned long *p2, unsigned long *id);
+ // get msgtype of the first ele from the queue
+ unsigned get_q_msg_type();
+
+ };
+ struct v4l2_capability cap;
+#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);
+ OMX_ERRORTYPE get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType);
+
+ 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 convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
+ OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space,
+ ColorAspects *aspects);
+ void handle_color_space_info(void *data, unsigned int buf_index);
+ void set_colorspace_in_handle(ColorSpace_t color, unsigned int buf_index);
+ void print_debug_color_aspects(ColorAspects *aspects, const char *prefix);
+ 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,
+ OMX_TICKS time_stamp,
+ 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_frame_dimension_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 append_concealmb_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ OMX_OTHER_EXTRADATATYPE *p_concealmb, OMX_U8 *conceal_mb_data);
+ void append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload);
+ void append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_frame_qp_payload *qp_payload);
+ void append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_frame_bits_info_payload *bits_payload);
+ void append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_vqzip_sei_payload *vqzip_payload);
+ 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 long p1,
+ unsigned long p2,
+ unsigned long 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 && m_state != OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR("ERROR: Sending OMX_ErrorHardware 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 && m_state != OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR(
+ "ERROR: Sending OMX_ErrorUnsupportedSetting to Client");
+ m_error_propogated = true;
+ m_cb.EventHandler(&m_cmp, m_app_data,
+ OMX_EventError, OMX_ErrorUnsupportedSetting, 0, NULL);
+ }
+ }
+ inline void omx_report_hw_overload () {
+ if (m_cb.EventHandler && !m_error_propogated && m_state != OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR(
+ "ERROR: Sending OMX_ErrorInsufficientResources to Client");
+ m_error_propogated = true;
+ m_cb.EventHandler(&m_cmp, m_app_data,
+ OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
+ }
+ }
+
+#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;
+ pthread_mutex_t buf_lock;
+ //sem to handle the minimum procesing of commands
+ sem_t m_cmd_lock;
+ sem_t m_safe_flush;
+ 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
+ uint64_t m_out_bm_count;
+ // bitmask array size for input side
+ uint64_t m_inp_bm_count;
+ //Input port Populated
+ OMX_BOOL m_inp_bPopulated;
+ //Output port Populated
+ OMX_BOOL m_out_bPopulated;
+ // encapsulate the waiting states.
+ uint64_t m_flags;
+
+#ifdef _ANDROID_
+ // Heap pointer to frame buffers
+ struct vidc_heap {
+ sp<MemoryHeapBase> 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;
+ h264_stream_parser *h264_parser;
+ MP4_Utils mp4_headerparser;
+ HEVC_Utils m_hevc_utils;
+
+ 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;
+ OMX_S64 prev_ts_actual;
+ bool rst_prev_ts;
+ OMX_U32 frm_int;
+
+ struct vdec_allocatorproperty op_buf_rcnfg;
+ bool in_reconfig;
+ OMX_NATIVE_WINDOWTYPE m_display_id;
+ 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_reject_avc_1080p_mp;
+ bool m_enable_android_native_buffers;
+ bool m_use_android_native_buffers;
+ bool m_debug_extradata;
+ bool m_debug_concealedmb;
+ bool m_disable_dynamic_buf_mode;
+ OMX_U32 m_conceal_color;
+#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;
+ OMX_PARAM_PORTDEFINITIONTYPE m_port_def;
+ OMX_QCOM_FRAME_PACK_ARRANGEMENT m_frame_pack_arrangement;
+ omx_time_stamp_reorder time_stamp_dts;
+ desc_buffer_hdr *m_desc_buffer_ptr;
+ bool secure_mode;
+ bool allocate_native_handle;
+ bool external_meta_buffer;
+ bool external_meta_buffer_iommu;
+ OMX_QCOM_EXTRADATA_FRAMEINFO *m_extradata;
+ OMX_OTHER_EXTRADATATYPE *m_other_extradata;
+ bool codec_config_flag;
+#ifdef _MSM8974_
+ int capture_capability;
+ int output_capability;
+ bool streaming[MAX_PORT];
+ OMX_FRAMESIZETYPE framesize;
+ OMX_CONFIG_RECTTYPE rectangle;
+ OMX_U32 prev_n_filled_len;
+ bool is_down_scalar_enabled;
+ bool m_force_down_scalar;
+#endif
+ struct custom_buffersize {
+ OMX_U32 input_buffersize;
+ } m_custom_buffersize;
+ bool m_power_hinted;
+ bool is_q6_platform;
+ 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;
+ OMX_U32 m_profile;
+
+ //variables to handle dynamic buffer mode
+ bool dynamic_buf_mode;
+ struct dynamic_buf_list *out_dynamic_list;
+ OMX_U32 m_reconfig_width;
+ OMX_U32 m_reconfig_height;
+ bool m_smoothstreaming_mode;
+
+ bool m_input_pass_buffer_fd;
+ DescribeColorAspectsParams m_client_color_space;
+ DescribeColorAspectsParams m_internal_color_space;
+
+ OMX_U32 operating_frame_rate;
+ bool high_fps;
+
+ OMX_U32 m_smoothstreaming_width;
+ OMX_U32 m_smoothstreaming_height;
+ OMX_ERRORTYPE enable_smoothstreaming();
+ OMX_ERRORTYPE enable_adaptive_playback(unsigned long width, unsigned long height);
+ bool is_thulium_v1;
+ bool m_disable_ubwc_mode;
+ bool m_disable_split_mode;
+ OMX_U32 m_downscalar_width;
+ OMX_U32 m_downscalar_height;
+ int decide_downscalar();
+ int enable_downscalar();
+ int disable_downscalar();
+
+ unsigned int m_fill_output_msg;
+ bool client_set_fps;
+ unsigned int stereo_output_mode;
+ 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_ERRORTYPE set_buffer_req(OMX_U32 buffer_size, OMX_U32 actual_count);
+ 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);
+ bool is_color_conversion_enabled() {return enabled;}
+ private:
+#define MAX_COUNT MAX_NUM_INPUT_OUTPUT_BUFFERS
+ 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_U32 m_c2d_width;
+ OMX_U32 m_c2d_height;
+ 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<MemoryHeapBase> video_heap_ptr;
+ };
+ struct vidc_heap m_heap_ptr[MAX_COUNT];
+
+ OMX_ERRORTYPE cache_ops(unsigned int index, unsigned int cmd);
+ inline OMX_ERRORTYPE cache_clean_buffer(unsigned int index) {
+ return cache_ops(index, ION_IOC_CLEAN_CACHES);
+ }
+ OMX_ERRORTYPE cache_clean_invalidate_buffer(unsigned int index) {
+ return cache_ops(index, ION_IOC_CLEAN_INV_CACHES);
+ }
+ };
+#if defined (_MSM8960_) || defined (_MSM8974_)
+ allocate_color_convert_buf client_buffers;
+#endif
+ struct video_decoder_capability m_decoder_capability;
+ struct debug_cap m_debug;
+ int log_input_buffers(const char *, int);
+ int log_output_buffers(OMX_BUFFERHEADERTYPE *);
+#ifdef _MSM8974_
+ void send_codec_config();
+#endif
+ OMX_TICKS m_last_rendered_TS;
+ volatile int32_t m_queued_codec_config_count;
+ OMX_U32 current_perf_level;
+ bool secure_scaling_to_non_secure_opb;
+ bool m_force_compressed_for_dpb;
+ bool m_is_display_session;
+ class perf_lock {
+ private:
+ pthread_mutex_t mlock;
+
+ public:
+ perf_lock() {
+ pthread_mutex_init(&mlock, NULL);
+ }
+
+ ~perf_lock() {
+ pthread_mutex_destroy(&mlock);
+ }
+
+ void lock() {
+ pthread_mutex_lock(&mlock);
+ }
+
+ void unlock() {
+ pthread_mutex_unlock(&mlock);
+ }
+ };
+
+ class perf_control {
+ // 2 cores will be requested if framerate is beyond 45 fps
+ static const int MIN_FRAME_DURATION_FOR_PERF_REQUEST_US = (1e6 / 45);
+ typedef int (*perf_lock_acquire_t)(int, int, int*, int);
+ typedef int (*perf_lock_release_t)(int);
+
+ private:
+ void *m_perf_lib;
+ int m_perf_handle;
+ perf_lock_acquire_t m_perf_lock_acquire;
+ perf_lock_release_t m_perf_lock_release;
+ bool load_lib();
+ struct mpctl_stats {
+ int vid_inst_count;
+ bool vid_acquired;
+ int vid_disp_handle;
+ };
+ static struct mpctl_stats mpctl_obj;
+ static perf_lock m_perf_lock;
+
+ public:
+ perf_control();
+ ~perf_control();
+ void request_cores(int frame_duration_us);
+ void send_hint_to_mpctl(bool state);
+ };
+ perf_control m_perf_control;
+
+ static OMX_COLOR_FORMATTYPE getPreferredColorFormatNonSurfaceMode(OMX_U32 index) {
+ //On Android, we default to standard YUV formats for non-surface use-cases
+ //where apps prefer known color formats.
+ OMX_COLOR_FORMATTYPE formatsNonSurfaceMode[] = {
+ [0] = OMX_COLOR_FormatYUV420SemiPlanar,
+ [1] = OMX_COLOR_FormatYUV420Planar,
+ [2] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ [3] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
+ [4] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed,
+ };
+ return (index < sizeof(formatsNonSurfaceMode) / sizeof(OMX_COLOR_FORMATTYPE)) ?
+ formatsNonSurfaceMode[index] : OMX_COLOR_FormatMax;
+ }
+
+ OMX_COLOR_FORMATTYPE getPreferredColorFormatDefaultMode(OMX_U32 index) {
+ //for surface mode (normal playback), advertise native/accelerated formats first
+ OMX_COLOR_FORMATTYPE format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+
+ if (!m_disable_ubwc_mode) {
+ OMX_COLOR_FORMATTYPE formatsDefault[] = {
+ [0] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed,
+ [1] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ [2] = OMX_COLOR_FormatYUV420Planar,
+ [3] = OMX_COLOR_FormatYUV420SemiPlanar,
+ [4] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
+ };
+ format = (index < sizeof(formatsDefault) / sizeof(OMX_COLOR_FORMATTYPE)) ?
+ formatsDefault[index] : OMX_COLOR_FormatMax;
+ } else {
+ OMX_COLOR_FORMATTYPE formatsDefault[] = {
+ [0] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ [1] = OMX_COLOR_FormatYUV420Planar,
+ [2] = OMX_COLOR_FormatYUV420SemiPlanar,
+ [3] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
+ };
+ format = (index < sizeof(formatsDefault) / sizeof(OMX_COLOR_FORMATTYPE)) ?
+ formatsDefault[index] : OMX_COLOR_FormatMax;
+ }
+ return format;
+ }
+
+ static OMX_ERRORTYPE describeColorFormat(OMX_PTR params);
+ void prefetchNewBuffers();
+
+ class client_extradata_info {
+ private:
+ int fd;
+ OMX_U32 total_size;
+ OMX_U32 size;
+ void *vaddr;
+ public:
+ client_extradata_info() {
+ fd = -1;
+ size = 0;
+ total_size = 0;
+ vaddr = NULL;
+ }
+
+ void reset() {
+ if (vaddr) {
+ munmap(vaddr, total_size);
+ vaddr = NULL;
+ }
+ if (fd != -1) {
+ close(fd);
+ fd = -1;
+ }
+ }
+
+ ~client_extradata_info() {
+ reset();
+ }
+
+ bool set_extradata_info(int fd, OMX_U32 total_size, OMX_U32 size) {
+ reset();
+ this->fd = fd;
+ this->size = size;
+ this->total_size = total_size;
+ vaddr = (OMX_U8*)mmap(0, total_size,
+ PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (vaddr == MAP_FAILED) {
+ vaddr = NULL;
+ reset();
+ return false;
+ }
+ return true;
+ }
+
+ OMX_U8 *getBase() const {
+ return (OMX_U8 *)vaddr;
+ }
+
+ OMX_U32 getSize() const {
+ return size;
+ }
+ };
+ client_extradata_info m_client_extradata_info;
+};
+
+#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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h
new file mode 100644
index 0000000..24b6afa
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc.h
@@ -0,0 +1,934 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013-2016, 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <cstddef>
+
+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 <linux/msm_ion.h>
+#endif
+#include <binder/MemoryHeapBase.h>
+#include <ui/ANativeObjectBase.h>
+extern "C" {
+#include <utils/Log.h>
+}
+#include <linux/videodev2.h>
+#include <poll.h>
+#include "hevc_utils.h"
+#define TIMEOUT 5000
+
+#endif // _ANDROID_
+
+
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+#include <media/hardware/HardwareAPI.h>
+#endif
+
+#include <unistd.h>
+
+#if defined (_ANDROID_ICS_)
+#include <gralloc_priv.h>
+#endif
+
+#include <pthread.h>
+#ifndef PC_DEBUG
+#include <semaphore.h>
+#endif
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "qc_omx_component.h"
+#include <linux/msm_vidc_dec.h>
+#include <media/msm_vidc.h>
+#include "frameparser.h"
+#ifdef MAX_RES_1080P
+#include "mp4_utils.h"
+#endif
+#include <linux/android_pmem.h>
+#include "extra_data_handler.h"
+#include "ts_parser.h"
+#include "vidc_color_converter.h"
+#include "vidc_debug.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,ion_user_handle_t handle,int mapfd);
+ virtual ~VideoHeap() {}
+ private:
+ int m_ion_device_fd;
+ ion_user_handle_t 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 OMX_CORE_FWVGA_HEIGHT 480
+#define OMX_CORE_FWVGA_WIDTH 864
+
+#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
+};
+
+// 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);
+ }
+ }
+#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<MemoryHeapBase> 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;
+ 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<MemoryHeapBase> 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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h
new file mode 100644
index 0000000..118e64b
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/omx_vdec_hevc_swvdec.h
@@ -0,0 +1,1104 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013-2016, 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <cstddef>
+
+#include "SwVdecTypes.h"
+#include "SwVdecAPI.h"
+
+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 <linux/msm_ion.h>
+#endif
+#include <binder/MemoryHeapBase.h>
+#include <ui/ANativeObjectBase.h>
+extern "C"{
+#include <utils/Log.h>
+}
+#include <linux/videodev2.h>
+#include <poll.h>
+#include "hevc_utils.h"
+#define TIMEOUT 5000
+
+#else //_ANDROID_
+#define DEBUG_PRINT_LOW(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
+#define DEBUG_PRINT_HIGH(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
+#define DEBUG_PRINT_ERROR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
+#endif // _ANDROID_
+
+
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+#include <media/hardware/HardwareAPI.h>
+#endif
+
+#include <unistd.h>
+
+#if defined (_ANDROID_ICS_)
+#include <gralloc_priv.h>
+#endif
+
+#include <pthread.h>
+#ifndef PC_DEBUG
+#include <semaphore.h>
+#endif
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "OMX_Video.h"
+#include "qc_omx_component.h"
+#include <linux/msm_vidc_dec.h>
+#include <media/msm_vidc.h>
+#include "frameparser.h"
+#ifdef MAX_RES_1080P
+#include "mp4_utils.h"
+#endif
+#include <linux/android_pmem.h>
+#include "extra_data_handler.h"
+#include "ts_parser.h"
+#include "vidc_color_converter.h"
+#include "vidc_debug.h"
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#else
+#define PROPERTY_VALUE_MAX 92
+#endif
+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,ion_user_handle_t handle,int mapfd);
+ virtual ~VideoHeap() {}
+ private:
+ int m_ion_device_fd;
+ ion_user_handle_t 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 OMX_CORE_FWVGA_HEIGHT 480
+#define OMX_CORE_FWVGA_WIDTH 864
+
+#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
+};
+
+enum interm_buffer_state
+{
+ WITH_COMPONENT = 0,
+ WITH_SWVDEC,
+ WITH_DSP
+};
+
+#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;
+
+ struct vdec_allocatorproperty interm_op_buf;
+ struct vdec_bufferpayload *ptr_interm_outputbuffer;
+ struct vdec_output_frameinfo *ptr_interm_respbuffer;
+
+#ifdef USE_ION
+ struct vdec_ion *ip_buf_ion_info;
+ struct vdec_ion *op_buf_ion_info;
+ struct vdec_ion *interm_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
+};
+
+struct video_decoder_capability {
+ unsigned int min_width;
+ unsigned int max_width;
+ unsigned int min_height;
+ unsigned int max_height;
+};
+
+struct debug_cap {
+ bool in_buffer_log;
+ bool out_buffer_log;
+ bool im_buffer_log;
+ char infile_name[PROPERTY_VALUE_MAX + 36];
+ char outfile_name[PROPERTY_VALUE_MAX + 36];
+ char imbfile_name[PROPERTY_VALUE_MAX + 36];
+ char log_loc[PROPERTY_VALUE_MAX];
+ FILE *infile;
+ FILE *outfile;
+ FILE *imbfile;
+};
+
+struct dynamic_buf_list {
+ OMX_U32 fd;
+ OMX_U32 dup_fd;
+ OMX_U32 offset;
+ OMX_U32 ref_count;
+};
+
+// 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();
+
+ void buf_ref_add(int index, OMX_U32 fd, OMX_U32 offset);
+ void buf_ref_remove(OMX_U32 fd, OMX_U32 offset);
+
+ static SWVDEC_STATUS swvdec_input_buffer_done_cb(SWVDEC_HANDLE pSwDec, SWVDEC_IPBUFFER *pIpBuffer, void *pClientHandle);
+ static SWVDEC_STATUS swvdec_fill_buffer_done_cb(SWVDEC_HANDLE pSwDec, SWVDEC_OPBUFFER *pOpBuffer, void *pClientHandle);
+ static SWVDEC_STATUS swvdec_handle_event_cb (SWVDEC_HANDLE pSwDec, SWVDEC_EVENTHANDLER* pEventHandler, void *pClientHandle);
+ void swvdec_input_buffer_done(SWVDEC_IPBUFFER *pIpBuffer);
+ void swvdec_fill_buffer_done(SWVDEC_OPBUFFER *pOpBuffer);
+ void swvdec_handle_event(SWVDEC_EVENTHANDLER *pEvent);
+
+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,
+
+ // SWVDEC events
+ OMX_COMPONENT_GENERATE_ETB_SWVDEC = 0x17,
+ OMX_COMPONENT_GENERATE_EBD_SWVDEC = 0x18,
+ OMX_COMPONENT_GENERATE_FTB_DSP = 0x19,
+ OMX_COMPONENT_GENERATE_FBD_DSP = 0x1A,
+ OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH_DSP = 0x1C,
+ OMX_COMPONENT_GENERATE_STOP_DONE_SWVDEC = 0x1D,
+ OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING = 0x1E,
+ };
+
+ 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 long param1;
+ unsigned long 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 long p1, unsigned long p2, unsigned long id);
+ bool pop_entry(unsigned long*p1,unsigned long*p2, unsigned long*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();
+ bool execute_input_flush_swvdec();
+ bool execute_output_flush_dsp();
+
+ 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_hevc (OMX_HANDLETYPE hComp);
+
+ OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ OMX_ERRORTYPE empty_this_buffer_proxy_swvdec(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer);
+
+ OMX_ERRORTYPE empty_buffer_done_swvdec(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer);
+
+ OMX_ERRORTYPE fill_all_buffers_proxy_dsp(OMX_HANDLETYPE hComp);
+
+ OMX_ERRORTYPE fill_this_buffer_proxy_dsp(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd);
+
+ OMX_ERRORTYPE fill_buffer_done_dsp(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer);
+
+
+ OMX_ERRORTYPE fill_this_buffer_proxy_swvdec(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd);
+
+ // OMX_ERRORTYPE allocate_intermediate_buffer(OMX_HANDLETYPE, OMX_PTR, OMX_U32);
+ OMX_ERRORTYPE allocate_interm_buffer(OMX_IN OMX_U32 bytes);
+
+ OMX_ERRORTYPE free_interm_buffers();
+
+ bool release_done();
+
+ bool release_output_done();
+ bool release_input_done();
+ bool release_interm_done();
+
+ OMX_ERRORTYPE get_buffer_req(vdec_allocatorproperty *buffer_prop);
+ OMX_ERRORTYPE get_buffer_req_swvdec();
+ OMX_ERRORTYPE set_buffer_req(vdec_allocatorproperty *buffer_prop);
+ OMX_ERRORTYPE set_buffer_req_swvdec(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, int heap_id = 0);
+ 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 long p1,
+ unsigned long p2,
+ unsigned long 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)
+ {
+ DEBUG_PRINT_ERROR("\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("ERROR: Sending OMX_ErrorUnsupportedSetting to Client");
+ m_error_propogated = true;
+ m_cb.EventHandler(&m_cmp,m_app_data,
+ OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL);
+ }
+ }
+#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;
+
+ omx_cmd_queue m_ftb_q_dsp; // ftb for dsp
+ omx_cmd_queue m_etb_q_swvdec; // etbs for swvdec
+
+ // 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<MemoryHeapBase> 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;
+
+ // for soft ARM codec
+ SWVDEC_INITPARAMS sSwVdecParameter;
+ SWVDEC_HANDLE m_pSwVdec;
+ SWVDEC_CALLBACK m_callBackInfo;
+ SWVDEC_IPBUFFER *m_pSwVdecIpBuffer;
+ SWVDEC_OPBUFFER *m_pSwVdecOpBuffer;
+ OMX_U32 m_nInputBuffer;
+ OMX_U32 m_nOutputBuffer;
+
+ interm_buffer_state m_interm_buf_state[32];
+ OMX_BUFFERHEADERTYPE* m_interm_mem_ptr;
+ bool m_interm_flush_dsp_progress;
+ bool m_interm_flush_swvdec_progress;
+ OMX_BOOL m_interm_bPopulated;
+ OMX_BOOL m_interm_bEnabled;
+ int m_swvdec_mode;
+ OMX_BOOL m_fill_internal_bufers;
+
+ // 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;
+ bool m_disable_dynamic_buf_mode;
+#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;
+ 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;
+
+ bool dynamic_buf_mode;
+ struct dynamic_buf_list *out_dynamic_list;
+
+ bool m_smoothstreaming_mode;
+ OMX_U32 m_smoothstreaming_width;
+ OMX_U32 m_smoothstreaming_height;
+ OMX_ERRORTYPE enable_smoothstreaming();
+
+ 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<MemoryHeapBase> 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;
+ struct video_decoder_capability m_decoder_capability;
+ struct debug_cap m_debug;
+ int log_input_buffers(const char *, int);
+ int log_output_buffers(OMX_BUFFERHEADERTYPE *);
+ int log_im_buffer(OMX_BUFFERHEADERTYPE * buffer);
+};
+
+#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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/power_module.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/power_module.h
new file mode 100644
index 0000000..ba47c2f
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/power_module.h
@@ -0,0 +1,42 @@
+/*-------------------------------------------------------------------------
+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 <hardware/power.h>
+
+class PowerModule
+{
+ public:
+ static PowerModule *getInstance();
+ power_module_t *getPowerModuleHandle();
+ private:
+ static PowerModule *mPowerModuleInstance;
+ power_module_t *mPowerModuleHandle;
+ PowerModule() {}
+};
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/inc/qtypes.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/qtypes.h
new file mode 100644
index 0000000..bef6e2d
--- /dev/null
+++ b/msmcobalt/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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/queue.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/queue.h
new file mode 100644
index 0000000..f22e43c
--- /dev/null
+++ b/msmcobalt/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/msmcobalt/mm-video-v4l2/vidc/vdec/inc/ts_parser.h b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/ts_parser.h
new file mode 100644
index 0000000..2d5d1a4
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/inc/ts_parser.h
@@ -0,0 +1,106 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2015, 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<stdlib.h>
+
+#include <stdio.h>
+#include <inttypes.h>
+
+#ifdef _ANDROID_
+extern "C" {
+#include<utils/Log.h>
+}
+#else
+#define ALOGE(fmt, args...) fprintf(stderr, fmt, ##args)
+#endif /* _ANDROID_ */
+
+class omx_time_stamp_reorder
+{
+ class auto_lock {
+ public:
+ auto_lock(pthread_mutex_t *lock)
+ : mLock(lock) {
+ if (mLock)
+ pthread_mutex_lock(mLock);
+ }
+ ~auto_lock() {
+ if (mLock)
+ pthread_mutex_unlock(mLock);
+ }
+ private:
+ pthread_mutex_t *mLock;
+ };
+
+ 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;
+ pthread_mutex_t m_lock;
+};
+#endif
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/src/frameparser.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/frameparser.cpp
new file mode 100644
index 0000000..5e8e551
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/frameparser.cpp
@@ -0,0 +1,638 @@
+/*--------------------------------------------------------------------------
+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 <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <stdint.h>
+
+#include "frameparser.h"
+#include "vidc_debug.h"
+
+#ifdef _ANDROID_
+extern "C" {
+#include<utils/Log.h>
+}
+#endif//_ANDROID_
+
+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("FrameParser: dest_len %u source_len %u",(unsigned int)dest_len, (unsigned int)source_len);
+
+ if (source_len == 0 && (source->nFlags & 0x01)) {
+ DEBUG_PRINT_LOW("FrameParser: EOS rxd!! Notify it as a complete frame");
+ *partialframe = 0;
+ return 1;
+ }
+
+ DEBUG_PRINT_LOW("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 ("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("FrameParser: Parsed Len = %u", (unsigned int)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;
+ OMX_U32 bytes_to_skip = 0;
+ switch (parse_state) {
+ case A5:
+ *partialframe = 0;
+ check_skip_frame_boundary(partialframe);
+ bytes_to_skip = 3;
+ break;
+ case A4:
+ *partialframe = 0;
+ check_skip_frame_boundary(partialframe);
+ bytes_to_skip = 4;
+ break;
+ case A3:
+ if (source->nFlags & OMX_BUFFERFLAG_EOS) {
+ bytes_to_skip = 0;
+ } else {
+ bytes_to_skip = 3;
+ }
+ break;
+ case A2:
+ if (source->nFlags & OMX_BUFFERFLAG_EOS) {
+ bytes_to_skip = 0;
+ } else {
+ bytes_to_skip = 2;
+ }
+ break;
+ case A1:
+ if (source->nFlags & OMX_BUFFERFLAG_EOS) {
+ bytes_to_skip = 0;
+ } else {
+ bytes_to_skip = 1;
+ }
+ break;
+ case A0:
+ bytes_to_skip = 0;
+ break;
+ }
+
+ if (source->nFilledLen < parsed_length) {
+ DEBUG_PRINT_ERROR ("FATAL Error");
+ return -1;
+ }
+
+ if (parsed_length > bytes_to_skip) {
+ memcpy (pdest, psource, (parsed_length-bytes_to_skip));
+ dest->nFilledLen += (parsed_length-bytes_to_skip);
+ }
+
+ 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 || nal_length == 0) {
+ DEBUG_PRINT_LOW("FrameParser: NAL Parsing Error! dest_len %u "
+ "nal_length %u", (unsigned int)dest_len, nal_length);
+ return -1;
+ }
+
+ if (source_len == 0 ) {
+ if (source->nFlags & OMX_BUFFERFLAG_EOS) {
+ DEBUG_PRINT_LOW("FrameParser: EOS rxd for nallength!!"
+ " Notify it as a complete frame");
+ *partialframe = 0;
+ return 1;
+ } else {
+ DEBUG_PRINT_ERROR("FrameParser: NAL Parsing Error!"
+ "Buffer recieved with source_len = %u and with"
+ "flags %u", (unsigned int)source_len, (unsigned int)source->nFlags);
+ 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/msmcobalt/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp
new file mode 100644
index 0000000..13d4eac
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp
@@ -0,0 +1,1587 @@
+/*--------------------------------------------------------------------------
+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 <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/time.h>
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+extern "C" {
+#include<utils/Log.h>
+}
+
+#endif
+
+/* =======================================================================
+
+ DEFINITIONS AND DECLARATIONS FOR MODULE
+
+ This section contains definitions for constants, macros, types, variables
+ and other items needed by this module.
+
+ ========================================================================== */
+
+
+#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<uint32> (*pos);
+ return static_cast<uint32> (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...");
+ }
+ cursor <<= 8;
+ //cursor |= static_cast<uint32> (*pos);
+ cursor |= static_cast<uint32> (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_cast<uint32>STD_MIN(static_cast<int>(8 - bit),
+ static_cast<int>(n - i));
+ x <<= s;
+
+ x |= ((next () >> ((8 - static_cast<uint32>(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<uint32>(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<int32> ((x >> 1) + 1);
+ else return - static_cast<int32> (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:
+<In>
+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
+
+<Out>
+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("@#@# 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:
+<In>
+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
+<out>
+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", 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("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("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",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[%u]!", (unsigned int)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 [%u]!", (unsigned int)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 : %u", (unsigned int)pan_scan_param->rect_id);
+ ALOGE("-->rect_cancel_flag : %u", pan_scan_param->rect_cancel_flag);
+
+ ALOGE("-->cnt : %u", (unsigned int)pan_scan_param->cnt);
+
+ for (OMX_U32 i = 0; i < pan_scan_param->cnt; i++) {
+ ALOGE("-->rect_left_offset : %d", (int)pan_scan_param->rect_left_offset[i]);
+ ALOGE("-->rect_right_offset : %d", (int)pan_scan_param->rect_right_offset[i]);
+ ALOGE("-->rect_top_offset : %d", (int)pan_scan_param->rect_top_offset[i]);
+ ALOGE("-->rect_bottom_offset : %d", (int)pan_scan_param->rect_bottom_offset[i]);
+ }
+ ALOGE("-->repetition_period : %u", (unsigned int)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
+ profile = value;
+ 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_U32 h264_stream_parser::get_profile()
+{
+ return profile;
+}
+
+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("%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("## frame_packing_arrangement.id = %u", frame_packing_arrangement.id);
+ ALOGV("## frame_packing_arrangement.cancel_flag = %u",
+ frame_packing_arrangement.cancel_flag);
+ if (!frame_packing_arrangement.cancel_flag) {
+ ALOGV("## frame_packing_arrangement.type = %u",
+ frame_packing_arrangement.type);
+ ALOGV("## frame_packing_arrangement.quincunx_sampling_flag = %u",
+ frame_packing_arrangement.quincunx_sampling_flag);
+ ALOGV("## frame_packing_arrangement.content_interpretation_type = %u",
+ frame_packing_arrangement.content_interpretation_type);
+ ALOGV("## frame_packing_arrangement.spatial_flipping_flag = %u",
+ frame_packing_arrangement.spatial_flipping_flag);
+ ALOGV("## frame_packing_arrangement.frame0_flipped_flag = %u",
+ frame_packing_arrangement.frame0_flipped_flag);
+ ALOGV("## frame_packing_arrangement.field_views_flag = %u",
+ frame_packing_arrangement.field_views_flag);
+ ALOGV("## frame_packing_arrangement.current_frame_is_frame0_flag = %u",
+ frame_packing_arrangement.current_frame_is_frame0_flag);
+ ALOGV("## frame_packing_arrangement.frame0_self_contained_flag = %u",
+ frame_packing_arrangement.frame0_self_contained_flag);
+ ALOGV("## frame_packing_arrangement.frame1_self_contained_flag = %u",
+ frame_packing_arrangement.frame1_self_contained_flag);
+ ALOGV("## frame_packing_arrangement.reserved_byte = %u",
+ frame_packing_arrangement.reserved_byte);
+ ALOGV("## frame_packing_arrangement.repetition_period = %u",
+ frame_packing_arrangement.repetition_period);
+ ALOGV("## 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("%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("%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(%u)", 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 : %u", 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 <class NODE_STRUCT>
+void omx_dl_list<NODE_STRUCT>::add_multiple(NODE_STRUCT *data_arr, int data_num)
+{
+ for (int idx = 0; idx < data_num; idx++)
+ add_last(&data_arr[idx]);
+}
+
+ template <class NODE_STRUCT>
+NODE_STRUCT *omx_dl_list<NODE_STRUCT>::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 <class NODE_STRUCT>
+NODE_STRUCT *omx_dl_list<NODE_STRUCT>::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 <class NODE_STRUCT>
+void omx_dl_list<NODE_STRUCT>::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 <class NODE_STRUCT>
+NODE_STRUCT* omx_dl_list<NODE_STRUCT>::watch_first()
+{
+ return head;
+}
+
+ template <class NODE_STRUCT>
+NODE_STRUCT* omx_dl_list<NODE_STRUCT>::watch_last()
+{
+ return tail;
+}
+
+#endif
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp
new file mode 100644
index 0000000..198789a
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/hevc_utils.cpp
@@ -0,0 +1,221 @@
+/*--------------------------------------------------------------------------
+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 "vidc_debug.h"
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/time.h>
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#endif
+
+
+/* =======================================================================
+
+ 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:
+<In>
+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
+<out>
+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("@#@# Pos = %x NalType = %x buflen = %u", pos-1, nalu_type, (unsigned int) 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("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("AU Boundary with NAL type %d ", 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",isNewFrame);
+ return true;
+}
+
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/src/message_queue.c b/msmcobalt/mm-video-v4l2/vidc/vdec/src/message_queue.c
new file mode 100644
index 0000000..ced773a
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/message_queue.c
@@ -0,0 +1,163 @@
+/*--------------------------------------------------------------------------
+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 "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("queue_get_cmd: Invalid Input parameter");
+ 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("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("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/msmcobalt/mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp
new file mode 100644
index 0000000..916f4e4
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/mp4_utils.cpp
@@ -0,0 +1,340 @@
+/*--------------------------------------------------------------------------
+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 "vidc_debug.h"
+# include <stdio.h>
+#ifdef _ANDROID_
+extern "C" {
+#include<utils/Log.h>
+}
+#endif//_ANDROID_
+
+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", 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/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp
new file mode 100644
index 0000000..2698d52
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec.cpp
@@ -0,0 +1,6418 @@
+/**
+ * @copyright
+ *
+ * Copyright (c) 2015-2016, 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.
+ *
+ * @file
+ *
+ * omx_swvdec.cpp
+ *
+ * @brief
+ *
+ * OMX software video decoder component source.
+ */
+
+#include <assert.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+#include <cutils/properties.h>
+
+#include <media/hardware/HardwareAPI.h>
+#include <gralloc_priv.h>
+
+#include "OMX_QCOMExtns.h"
+
+#include "omx_swvdec.h"
+
+#include "swvdec_api.h"
+
+static unsigned int split_buffer_mpeg4(unsigned int *offset_array,
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr);
+
+/**
+ * ----------------
+ * PUBLIC FUNCTIONS
+ * ----------------
+ */
+
+/**
+ * @brief Create & return component class instance.
+ *
+ * @retval Pointer to new component class instance.
+ */
+void *get_omx_component_factory_fn(void)
+{
+ return new omx_swvdec;
+}
+
+/**
+ * @brief Component constructor.
+ */
+omx_swvdec::omx_swvdec():
+ m_state(OMX_StateInvalid),
+ m_status_flags(0),
+ m_swvdec_codec(SWVDEC_CODEC_INVALID),
+ m_swvdec_handle(NULL),
+ m_swvdec_created(false),
+ m_omx_video_codingtype(OMX_VIDEO_CodingUnused),
+ m_omx_color_formattype(OMX_COLOR_FormatUnused),
+ m_sync_frame_decoding_mode(false),
+ m_android_native_buffers(false),
+ m_meta_buffer_mode_disabled(false),
+ m_meta_buffer_mode(false),
+ m_adaptive_playback_mode(false),
+ m_arbitrary_bytes_mode(false),
+ m_port_reconfig_inprogress(false),
+ m_dimensions_update_inprogress(false),
+ m_buffer_array_ip(NULL),
+ m_buffer_array_op(NULL),
+ m_meta_buffer_array(NULL)
+{
+ // memset all member variables that are composite structures
+ memset(&m_cmp, 0, sizeof(m_cmp)); // part of base class
+ memset(&m_cmp_name[0], 0, sizeof(m_cmp_name));
+ memset(&m_role_name[0], 0, sizeof(m_role_name));
+ memset(&m_frame_dimensions, 0, sizeof(m_frame_dimensions));
+ memset(&m_frame_attributes, 0, sizeof(m_frame_attributes));
+ memset(&m_frame_dimensions_max, 0, sizeof(m_frame_dimensions_max));
+ memset(&m_async_thread, 0, sizeof(m_async_thread));
+ memset(&m_port_ip, 0, sizeof(m_port_ip));
+ memset(&m_port_op, 0, sizeof(m_port_op));
+ memset(&m_callback, 0, sizeof(m_callback));
+ memset(&m_app_data, 0, sizeof(m_app_data));
+ memset(&m_prio_mgmt, 0, sizeof(m_prio_mgmt));
+ memset(&m_sem_cmd, 0, sizeof(m_sem_cmd));
+ memset(&m_meta_buffer_array_mutex, 0, sizeof(m_meta_buffer_array_mutex));
+
+ // null-terminate component name & role name strings
+ m_cmp_name[0] = '\0';
+ m_role_name[0] = '\0';
+
+ // ports are enabled & unpopulated by default
+ m_port_ip.enabled = OMX_TRUE;
+ m_port_op.enabled = OMX_TRUE;
+ m_port_ip.unpopulated = OMX_TRUE;
+ m_port_op.unpopulated = OMX_TRUE;
+}
+
+/**
+ * @brief Component destructor.
+ */
+omx_swvdec::~omx_swvdec()
+{
+}
+
+/**
+ * @brief Initialize component.
+ *
+ * @param[in] cmp_name: Component name string.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::component_init(OMX_STRING cmp_name)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_LOG_API("'%s', version date: %s",
+ cmp_name,
+ OMX_SWVDEC_VERSION_DATE);
+
+ omx_swvdec_log_init();
+
+ {
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+
+ if (property_get("omx_swvdec.meta_buffer.disable",
+ property_value,
+ NULL))
+ {
+ m_meta_buffer_mode_disabled = (bool) atoi(property_value);
+
+ OMX_SWVDEC_LOG_LOW("omx_swvdec.meta_buffer.disable: %d",
+ m_meta_buffer_mode_disabled ? 1 : 0);
+ }
+ }
+
+ if (m_state != OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("disallowed in state %s",
+ OMX_STATETYPE_STRING(m_state));
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ goto component_init_exit;
+ }
+
+ if (!strncmp(cmp_name,
+ "OMX.qti.video.decoder.mpeg4sw",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ OMX_SWVDEC_LOG_LOW("'video_decoder.mpeg4'");
+
+ strlcpy(m_cmp_name, cmp_name, OMX_MAX_STRINGNAME_SIZE);
+ strlcpy(m_role_name, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
+
+ m_swvdec_codec = SWVDEC_CODEC_MPEG4;
+ m_omx_video_codingtype = OMX_VIDEO_CodingMPEG4;
+ }
+ else if (!strncmp(cmp_name,
+ "OMX.qti.video.decoder.h263sw",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ OMX_SWVDEC_LOG_LOW("video_decoder.h263");
+
+ strlcpy(m_cmp_name, cmp_name, OMX_MAX_STRINGNAME_SIZE);
+ strlcpy(m_role_name, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
+
+ m_swvdec_codec = SWVDEC_CODEC_H263;
+ m_omx_video_codingtype = OMX_VIDEO_CodingH263;
+ }
+ else if (((!strncmp(cmp_name,
+ "OMX.qti.video.decoder.divxsw",
+ OMX_MAX_STRINGNAME_SIZE))) ||
+ ((!strncmp(cmp_name,
+ "OMX.qti.video.decoder.divx4sw",
+ OMX_MAX_STRINGNAME_SIZE))))
+ {
+ OMX_SWVDEC_LOG_LOW("video_decoder.divx");
+
+ strlcpy(m_cmp_name, cmp_name, OMX_MAX_STRINGNAME_SIZE);
+ strlcpy(m_role_name, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE);
+
+ m_swvdec_codec = SWVDEC_CODEC_MPEG4;
+ m_omx_video_codingtype = ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("'%s': invalid component name", cmp_name);
+
+ retval = OMX_ErrorInvalidComponentName;
+ goto component_init_exit;
+ }
+
+ {
+ SWVDEC_CALLBACK callback;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ callback.pfn_empty_buffer_done = swvdec_empty_buffer_done_callback;
+ callback.pfn_fill_buffer_done = swvdec_fill_buffer_done_callback;
+ callback.pfn_event_notification = swvdec_event_handler_callback;
+ callback.p_client = this;
+
+ if ((retval_swvdec = swvdec_init(&m_swvdec_handle,
+ m_swvdec_codec,
+ &callback)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ goto component_init_exit;
+ }
+
+ m_swvdec_created = true;
+
+ if ((retval = set_frame_dimensions(DEFAULT_FRAME_WIDTH,
+ DEFAULT_FRAME_HEIGHT)) !=
+ OMX_ErrorNone)
+ {
+ goto component_init_exit;
+ }
+
+ m_omx_color_formattype =
+ ((OMX_COLOR_FORMATTYPE)
+ OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m);
+
+ if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
+ OMX_ErrorNone)
+ {
+ goto component_init_exit;
+ }
+ }
+
+ if ((retval = get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_IP)) !=
+ OMX_ErrorNone)
+ {
+ goto component_init_exit;
+ }
+
+ if ((retval = get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_OP)) !=
+ OMX_ErrorNone)
+ {
+ goto component_init_exit;
+ }
+
+ if ((retval = async_thread_create()) != OMX_ErrorNone)
+ {
+ goto component_init_exit;
+ }
+
+ if (sem_init(&m_sem_cmd, 0, 0))
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to create command processing semaphore");
+
+ retval = OMX_ErrorInsufficientResources;
+ goto component_init_exit;
+ }
+
+ if (pthread_mutex_init(&m_meta_buffer_array_mutex, NULL))
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to create meta buffer info array mutex");
+
+ retval = OMX_ErrorInsufficientResources;
+ goto component_init_exit;
+ }
+
+ OMX_SWVDEC_LOG_HIGH("OMX_StateInvalid -> OMX_StateLoaded");
+
+ m_state = OMX_StateLoaded;
+
+component_init_exit:
+ return retval;
+}
+
+/**
+ * @brief De-initialize component.
+ *
+ * @param[in] cmp_handle: Component handle.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::component_deinit(OMX_HANDLETYPE cmp_handle)
+{
+ OMX_SWVDEC_LOG_API("");
+
+ if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+ }
+
+ pthread_mutex_destroy(&m_meta_buffer_array_mutex);
+
+ sem_destroy(&m_sem_cmd);
+
+ async_thread_destroy();
+
+ if (m_swvdec_created)
+ {
+ swvdec_deinit(m_swvdec_handle);
+
+ m_swvdec_handle = NULL;
+ }
+
+ OMX_SWVDEC_LOG_HIGH("all done, goodbye!");
+
+ return OMX_ErrorNone;
+}
+
+/**
+ * @brief Get component version.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] cmp_name: Component name string.
+ * @param[in,out] p_cmp_version: Pointer to component version variable.
+ * @param[in,out] p_spec_version: Pointer to OMX spec version variable.
+ * @param[in,out] p_cmp_UUID: Pointer to component UUID variable.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_component_version(OMX_HANDLETYPE cmp_handle,
+ OMX_STRING cmp_name,
+ OMX_VERSIONTYPE *p_cmp_version,
+ OMX_VERSIONTYPE *p_spec_version,
+ OMX_UUIDTYPE *p_cmp_UUID)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ (void) p_cmp_UUID;
+
+ OMX_SWVDEC_LOG_API("");
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (strncmp(cmp_name, m_cmp_name, sizeof(m_cmp_name)))
+ {
+ OMX_SWVDEC_LOG_ERROR("'%s': invalid component name", cmp_name);
+
+ retval = OMX_ErrorInvalidComponentName;
+ }
+ else if (p_cmp_version == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_cmp_version = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (p_spec_version == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_spec_version = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ p_spec_version->nVersion = OMX_SPEC_VERSION;
+ }
+
+get_component_version_exit:
+ return retval;
+}
+
+/**
+ * @brief Send command to component.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] cmd: Command.
+ * @param[in] param: Command parameter.
+ * @param[in] p_cmd_data: Pointer to command data.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::send_command(OMX_HANDLETYPE cmp_handle,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param,
+ OMX_PTR p_cmd_data)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ (void) p_cmd_data; // prevent warning for unused function argument
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ goto send_command_exit;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ goto send_command_exit;
+ }
+
+ switch (cmd)
+ {
+
+ case OMX_CommandStateSet:
+ {
+ OMX_SWVDEC_LOG_API("%s, %s",
+ OMX_COMMANDTYPE_STRING(cmd),
+ OMX_STATETYPE_STRING((OMX_STATETYPE) param));
+ break;
+ }
+
+ case OMX_CommandFlush:
+ case OMX_CommandPortDisable:
+ case OMX_CommandPortEnable:
+ {
+ OMX_SWVDEC_LOG_API("%s, port index %d",
+ OMX_COMMANDTYPE_STRING(cmd),
+ param);
+
+ if ((param != OMX_CORE_PORT_INDEX_IP) &&
+ (param != OMX_CORE_PORT_INDEX_OP) &&
+ (param != OMX_ALL))
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", param);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_API("cmd %d, param %d", cmd, param);
+
+ OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", cmd);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch (cmd)
+
+ if (retval == OMX_ErrorNone)
+ {
+ if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
+ }
+ else
+ {
+ async_post_event(OMX_SWVDEC_EVENT_CMD, cmd, param);
+
+ sem_wait(&m_sem_cmd);
+ }
+
+send_command_exit:
+ return retval;
+}
+
+/**
+ * @brief Get a parameter from component.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] param_index: Parameter index.
+ * @param[in,out] p_param_data: Pointer to parameter data.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_parameter(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE param_index,
+ OMX_PTR p_param_data)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_param_data == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_param_data = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ goto get_parameter_exit;
+ }
+
+ switch (param_index)
+ {
+
+ case OMX_IndexParamAudioInit:
+ {
+ OMX_PORT_PARAM_TYPE *p_port_param =
+ (OMX_PORT_PARAM_TYPE *) p_param_data;
+
+ p_port_param->nPorts = 0;
+ p_port_param->nStartPortNumber = 0;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamAudioInit: "
+ "%d port(s), start port index %d",
+ p_port_param->nPorts,
+ p_port_param->nStartPortNumber);
+ break;
+ }
+
+ case OMX_IndexParamImageInit:
+ {
+ OMX_PORT_PARAM_TYPE *p_port_param =
+ (OMX_PORT_PARAM_TYPE *) p_param_data;
+
+ p_port_param->nPorts = 0;
+ p_port_param->nStartPortNumber = 0;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamImageInit: "
+ "%d port(s), start port index %d",
+ p_port_param->nPorts,
+ p_port_param->nStartPortNumber);
+ break;
+ }
+
+ case OMX_IndexParamVideoInit:
+ {
+ OMX_PORT_PARAM_TYPE *p_port_param =
+ (OMX_PORT_PARAM_TYPE *) p_param_data;
+
+ p_port_param->nPorts = 2;
+ p_port_param->nStartPortNumber = 0;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoInit: "
+ "%d port(s), start port index %d",
+ p_port_param->nPorts,
+ p_port_param->nStartPortNumber);
+ break;
+ }
+
+ case OMX_IndexParamOtherInit:
+ {
+ OMX_PORT_PARAM_TYPE *p_port_param =
+ (OMX_PORT_PARAM_TYPE *) p_param_data;
+
+ p_port_param->nPorts = 0;
+ p_port_param->nStartPortNumber = 0;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamOtherInit: "
+ "%d port(s), start port index %d",
+ p_port_param->nPorts,
+ p_port_param->nStartPortNumber);
+ break;
+ }
+
+ case OMX_IndexConfigPriorityMgmt:
+ {
+ OMX_PRIORITYMGMTTYPE *p_prio_mgmt =
+ (OMX_PRIORITYMGMTTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexConfigPriorityMgmt");
+
+ memcpy(p_prio_mgmt, &m_prio_mgmt, sizeof(OMX_PRIORITYMGMTTYPE));
+ break;
+ }
+
+ case OMX_IndexParamStandardComponentRole:
+ {
+ OMX_PARAM_COMPONENTROLETYPE *p_cmp_role =
+ (OMX_PARAM_COMPONENTROLETYPE *) p_param_data;
+
+ strlcpy((char *) p_cmp_role->cRole,
+ m_role_name,
+ OMX_MAX_STRINGNAME_SIZE);
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamStandardComponentRole: %s",
+ p_cmp_role->cRole);
+ break;
+ }
+
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *p_port_def =
+ (OMX_PARAM_PORTDEFINITIONTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamPortDefinition, port index %d",
+ p_port_def->nPortIndex);
+
+ retval = get_port_definition(p_port_def);
+ break;
+ }
+
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ OMX_PARAM_BUFFERSUPPLIERTYPE *p_buffer_supplier =
+ (OMX_PARAM_BUFFERSUPPLIERTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamCompBufferSupplier, port index %d",
+ p_buffer_supplier->nPortIndex);
+
+ if ((p_buffer_supplier->nPortIndex == OMX_CORE_PORT_INDEX_IP) ||
+ (p_buffer_supplier->nPortIndex == OMX_CORE_PORT_INDEX_OP))
+ {
+ p_buffer_supplier->eBufferSupplier = OMX_BufferSupplyUnspecified;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_buffer_supplier->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoPortFormat, "
+ "port index %d, index %d",
+ p_port_format->nPortIndex,
+ p_port_format->nIndex);
+
+ retval = get_video_port_format(p_port_format);
+ break;
+ }
+
+ case OMX_IndexParamVideoMpeg2:
+ {
+ OMX_SWVDEC_LOG_ERROR("OMX_IndexParamVideoMpeg2: unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoMpeg4: unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_IndexParamVideoAvc:
+ {
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoAvc: unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_IndexParamVideoH263:
+ {
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoH263: unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *p_profilelevel =
+ (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoProfileLevelQuerySupported, "
+ "port index %d, profile index %d",
+ p_profilelevel->nPortIndex,
+ p_profilelevel->nProfileIndex);
+
+ retval = get_supported_profilelevel(p_profilelevel);
+ break;
+ }
+
+ default:
+ {
+ /**
+ * Vendor-specific extension indices checked here since they are not
+ * part of the OMX_INDEXTYPE enumerated type.
+ */
+
+ switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
+ {
+
+ case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
+ {
+ GetAndroidNativeBufferUsageParams *p_buffer_usage =
+ (GetAndroidNativeBufferUsageParams *) p_param_data;
+
+ OMX_SWVDEC_LOG_API(
+ "OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage, "
+ "port index %d", p_buffer_usage->nPortIndex);
+
+ if (p_buffer_usage->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ p_buffer_usage->nUsage = (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
+ GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_SW_WRITE_OFTEN);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_buffer_usage->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_QcomIndexFlexibleYUVDescription:
+ {
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexFlexibleYUVDescription");
+
+ retval = describe_color_format((DescribeColorFormatParams *)
+ p_param_data);
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR("param index '0x%08x' invalid",
+ (OMX_QCOM_EXTN_INDEXTYPE) param_index);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
+
+ } // default case
+
+ } // switch (param_index)
+
+get_parameter_exit:
+ return retval;
+}
+
+/**
+ * @brief Set a parameter to component.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] param_index: Parameter index.
+ * @param[in] p_param_data: Pointer to parameter data.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_parameter(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE param_index,
+ OMX_PTR p_param_data)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_param_data == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_param_data = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if ((m_state != OMX_StateLoaded) &&
+ (m_port_reconfig_inprogress == false))
+ {
+ OMX_SWVDEC_LOG_ERROR("disallowed in state %s",
+ OMX_STATETYPE_STRING(m_state));
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ goto set_parameter_exit;
+ }
+
+ switch (param_index)
+ {
+
+ case OMX_IndexParamPriorityMgmt:
+ {
+ OMX_PRIORITYMGMTTYPE *p_prio_mgmt =
+ (OMX_PRIORITYMGMTTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexConfigPriorityMgmt: "
+ "group ID %d, group priority %d",
+ p_prio_mgmt->nGroupID,
+ p_prio_mgmt->nGroupPriority);
+
+ if (m_state != OMX_StateLoaded)
+ {
+ OMX_SWVDEC_LOG_ERROR("'%d' state invalid; "
+ "should be in loaded state",
+ m_state);
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ memcpy(&m_prio_mgmt, p_prio_mgmt, sizeof(OMX_PRIORITYMGMTTYPE));
+ }
+
+ break;
+ }
+
+ case OMX_IndexParamStandardComponentRole:
+ {
+ OMX_PARAM_COMPONENTROLETYPE *p_cmp_role =
+ (OMX_PARAM_COMPONENTROLETYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamStandardComponentRole '%s'",
+ p_cmp_role->cRole);
+
+ if (m_state != OMX_StateLoaded)
+ {
+ OMX_SWVDEC_LOG_ERROR("'%d' state invalid; "
+ "should be in loaded state",
+ m_state);
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ if (strncmp((char *) p_cmp_role->cRole,
+ m_role_name,
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ OMX_SWVDEC_LOG_ERROR("'%s': invalid component role name",
+ p_cmp_role->cRole);
+
+ retval = OMX_ErrorBadParameter;
+ }
+ }
+
+ break;
+ }
+
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *p_port_def =
+ (OMX_PARAM_PORTDEFINITIONTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamPortDefinition, port index %d",
+ p_port_def->nPortIndex);
+
+ if ((m_state != OMX_StateLoaded) &&
+ (((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP) &&
+ (m_port_ip.enabled == OMX_TRUE) &&
+ (m_port_ip.populated == OMX_TRUE)) ||
+ ((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP) &&
+ (m_port_op.enabled == OMX_TRUE) &&
+ (m_port_op.populated == OMX_TRUE))))
+ {
+ OMX_SWVDEC_LOG_ERROR("OMX_IndexParamPortDefinition "
+ "disallowed in state %s "
+ "while port index %d is enabled & populated",
+ OMX_STATETYPE_STRING(m_state),
+ p_port_def->nPortIndex);
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ retval = set_port_definition(p_port_def);
+ }
+
+ break;
+ }
+
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ OMX_PARAM_BUFFERSUPPLIERTYPE *p_buffer_supplier =
+ (OMX_PARAM_BUFFERSUPPLIERTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamCompBufferSupplier: "
+ "port index %d, buffer supplier %d",
+ p_buffer_supplier->nPortIndex,
+ (int) p_buffer_supplier->eBufferSupplier);
+
+ if ((p_buffer_supplier->nPortIndex != OMX_CORE_PORT_INDEX_IP) &&
+ (p_buffer_supplier->nPortIndex != OMX_CORE_PORT_INDEX_OP))
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_buffer_supplier->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ case OMX_IndexParamVideoPortFormat:
+ {
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoPortFormat, port index %d",
+ p_port_format->nPortIndex);
+
+ if ((m_state != OMX_StateLoaded) &&
+ (((p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP) &&
+ (m_port_ip.enabled == OMX_TRUE) &&
+ (m_port_ip.populated == OMX_TRUE)) ||
+ ((p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP) &&
+ (m_port_op.enabled == OMX_TRUE) &&
+ (m_port_op.populated == OMX_TRUE))))
+ {
+ OMX_SWVDEC_LOG_ERROR("OMX_IndexParamVideoPortFormat "
+ "disallowed in state %s "
+ "while port index %d is enabled & populated",
+ OMX_STATETYPE_STRING(m_state),
+ p_port_format->nPortIndex);
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ retval = set_video_port_format(p_port_format);
+ }
+
+ break;
+ }
+
+ case OMX_IndexParamVideoMpeg2:
+ {
+ OMX_SWVDEC_LOG_ERROR("OMX_IndexParamVideoMpeg2 unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoMpeg4 unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_IndexParamVideoAvc:
+ {
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoAvc unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_IndexParamVideoH263:
+ {
+ OMX_SWVDEC_LOG_API("OMX_IndexParamVideoH263 unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ default:
+ {
+ /**
+ * Vendor-specific extension indices checked here since they are not
+ * part of the OMX_INDEXTYPE enumerated type.
+ */
+
+ switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
+ {
+
+ case OMX_QcomIndexPortDefn:
+ {
+ OMX_QCOM_PARAM_PORTDEFINITIONTYPE *p_port_def =
+ (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexPortDefn, port index %d",
+ p_port_def->nPortIndex);
+
+ if ((m_state != OMX_StateLoaded) &&
+ (((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP) &&
+ (m_port_ip.enabled == OMX_TRUE) &&
+ (m_port_ip.populated == OMX_TRUE)) ||
+ ((p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP) &&
+ (m_port_op.enabled == OMX_TRUE) &&
+ (m_port_op.populated == OMX_TRUE))))
+ {
+ OMX_SWVDEC_LOG_ERROR("OMX_QcomIndexPortDefn "
+ "disallowed in state %s "
+ "while port index %d "
+ "is enabled & populated",
+ OMX_STATETYPE_STRING(m_state),
+ p_port_def->nPortIndex);
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ retval = set_port_definition_qcom(p_port_def);
+ }
+
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoDivx:
+ {
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoDivx");
+
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
+ {
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoSyncFrameDecodingMode");
+
+ m_sync_frame_decoding_mode = true;
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoDecoderPictureOrder:
+ {
+ QOMX_VIDEO_DECODER_PICTURE_ORDER *p_picture_order =
+ (QOMX_VIDEO_DECODER_PICTURE_ORDER *) p_param_data;
+
+ switch (p_picture_order->eOutputPictureOrder)
+ {
+
+ case QOMX_VIDEO_DISPLAY_ORDER:
+ {
+ OMX_SWVDEC_LOG_API(
+ "OMX_QcomIndexParamVideoDecoderPictureOrder, "
+ "QOMX_VIDEO_DISPLAY_ORDER");
+
+ break;
+ }
+
+ case QOMX_VIDEO_DECODE_ORDER:
+ {
+ OMX_SWVDEC_LOG_API(
+ "OMX_QcomIndexParamVideoDecoderPictureOrder, "
+ "QOMX_VIDEO_DECODE_ORDER");
+
+ OMX_SWVDEC_LOG_ERROR(
+ "OMX_QcomIndexParamVideoDecoderPictureOrder, "
+ "QOMX_VIDEO_DECODE_ORDER; unsupported");
+
+ retval = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR(
+ "OMX_QcomIndexParamVideoDecoderPictureOrder, %d; invalid",
+ p_picture_order->eOutputPictureOrder);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ }
+
+ break;
+ }
+
+ case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
+ {
+ OMX_SWVDEC_LOG_API(
+ "OMX_GoogleAndroidIndexEnableAndroidNativeBuffers, %s",
+ (((EnableAndroidNativeBuffersParams *) p_param_data)->enable ?
+ "enable" :
+ "disable"));
+
+ m_android_native_buffers =
+ (bool) (((EnableAndroidNativeBuffersParams *)
+ p_param_data)->enable);
+
+ break;
+ }
+
+ case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
+ {
+ OMX_SWVDEC_LOG_ERROR("OMX_GoogleAndroidIndexUseAndroidNativeBuffer "
+ "unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ case OMX_QcomIndexParamEnableTimeStampReorder:
+ {
+ OMX_SWVDEC_LOG_API(
+ "OMX_QcomIndexParamEnableTimeStampReorder, %s",
+ (((QOMX_INDEXTIMESTAMPREORDER *) p_param_data)->bEnable ?
+ "enable" :
+ "disable"));
+
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoMetaBufferMode:
+ {
+ StoreMetaDataInBuffersParams *p_meta_data =
+ (StoreMetaDataInBuffersParams *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoMetaBufferMode, "
+ "port index %d, %s",
+ p_meta_data->nPortIndex,
+ (p_meta_data->bStoreMetaData ?
+ "enable" :
+ "disable"));
+
+ if (p_meta_data->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ if (p_meta_data->bStoreMetaData && m_meta_buffer_mode_disabled)
+ {
+ OMX_SWVDEC_LOG_ERROR("meta buffer mode disabled "
+ "via ADB setprop: "
+ "'omx_swvdec.meta_buffer.disable'");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ m_meta_buffer_mode = (bool) p_meta_data->bStoreMetaData;
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_meta_data->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
+ {
+ PrepareForAdaptivePlaybackParams *p_adaptive_playback_params =
+ (PrepareForAdaptivePlaybackParams *) p_param_data;
+
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexParamVideoAdaptivePlaybackMode, "
+ "port index %d, %s, max dimensions: %d x %d",
+ p_adaptive_playback_params->nPortIndex,
+ (p_adaptive_playback_params->bEnable ?
+ "enable" :
+ "disable"),
+ p_adaptive_playback_params->nMaxFrameWidth,
+ p_adaptive_playback_params->nMaxFrameHeight);
+
+ if (p_adaptive_playback_params->nPortIndex ==
+ OMX_CORE_PORT_INDEX_OP)
+ {
+ if (p_adaptive_playback_params->bEnable)
+ {
+ m_adaptive_playback_mode = true;
+
+ retval =
+ set_adaptive_playback(
+ p_adaptive_playback_params->nMaxFrameWidth,
+ p_adaptive_playback_params->nMaxFrameHeight);
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_adaptive_playback_params->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR("param index '0x%08x' invalid",
+ (OMX_QCOM_EXTN_INDEXTYPE) param_index);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch ((OMX_QCOM_EXTN_INDEXTYPE) param_index)
+
+ break;
+ } // default case
+
+ } // switch (param_index)
+
+set_parameter_exit:
+ return retval;
+}
+
+/**
+ * @brief Get a configuration from component.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] config_index: Configuration index.
+ * @param[in] p_config_data: Pointer to configuration data.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_config(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE config_index,
+ OMX_PTR p_config_data)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_config_data == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_config_data = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ goto get_config_exit;
+ }
+
+ switch (config_index)
+ {
+
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ OMX_CONFIG_RECTTYPE *p_recttype = (OMX_CONFIG_RECTTYPE *) p_config_data;
+
+ OMX_SWVDEC_LOG_API("OMX_IndexConfigCommonOutputCrop, port index %d",
+ p_recttype->nPortIndex);
+
+ if (p_recttype->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ if (m_dimensions_update_inprogress)
+ {
+ retval = get_frame_dimensions_swvdec();
+
+ m_dimensions_update_inprogress = false;
+ }
+
+ if (retval == OMX_ErrorNone)
+ {
+ p_recttype->nLeft = 0;
+ p_recttype->nTop = 0;
+ p_recttype->nWidth = m_frame_dimensions.width;
+ p_recttype->nHeight = m_frame_dimensions.height;
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_recttype->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ default:
+ {
+ switch ((OMX_QCOM_EXTN_INDEXTYPE) config_index)
+ {
+
+ case OMX_QcomIndexConfigInterlaced:
+ {
+ OMX_QCOM_CONFIG_INTERLACETYPE *p_config_interlacetype =
+ (OMX_QCOM_CONFIG_INTERLACETYPE *) p_config_data;
+
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexConfigInterlaced, "
+ "port index %d, index %d",
+ p_config_interlacetype->nPortIndex,
+ p_config_interlacetype->nIndex);
+
+ if (p_config_interlacetype->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ if (p_config_interlacetype->nIndex == 0)
+ {
+ p_config_interlacetype->eInterlaceType =
+ OMX_QCOM_InterlaceFrameProgressive;
+ }
+ else if (p_config_interlacetype->nIndex == 1)
+ {
+ p_config_interlacetype->eInterlaceType =
+ OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
+ }
+ else if (p_config_interlacetype->nIndex == 2)
+ {
+ p_config_interlacetype->eInterlaceType =
+ OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("index '%d' unsupported; "
+ "no more interlaced types",
+ p_config_interlacetype->nIndex);
+
+ retval = OMX_ErrorNoMore;
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_config_interlacetype->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ case OMX_QcomIndexQueryNumberOfVideoDecInstance:
+ {
+ QOMX_VIDEO_QUERY_DECODER_INSTANCES *p_decoder_instances =
+ (QOMX_VIDEO_QUERY_DECODER_INSTANCES *) p_config_data;
+
+ OMX_SWVDEC_LOG_API("OMX_QcomIndexQueryNumberOfVideoDecInstance");
+
+ p_decoder_instances->nNumOfInstances = OMX_SWVDEC_NUM_INSTANCES;
+ break;
+ }
+
+ case OMX_QcomIndexConfigVideoFramePackingArrangement:
+ {
+ OMX_SWVDEC_LOG_API(
+ "OMX_QcomIndexConfigVideoFramePackingArrangement");
+
+ OMX_SWVDEC_LOG_ERROR(
+ "OMX_QcomIndexConfigVideoFramePackingArrangement unsupported");
+
+ retval = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR("config index '0x%08x' invalid", config_index);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch ((OMX_QCOM_EXTN_INDEXTYPE) config_index)
+
+ break;
+ }
+
+ } // switch (config_index)
+
+get_config_exit:
+ return retval;
+}
+
+/**
+ * @brief Set a configuration to component.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_config(OMX_HANDLETYPE cmp_handle,
+ OMX_INDEXTYPE config_index,
+ OMX_PTR p_config_data)
+{
+ (void) cmp_handle;
+ (void) p_config_data;
+
+ OMX_SWVDEC_LOG_API("config index 0x%08x", config_index);
+
+ OMX_SWVDEC_LOG_ERROR("not implemented");
+
+ return OMX_ErrorNotImplemented;
+}
+
+/**
+ * @brief Translate a vendor-specific extension string to a standard index type.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] param_name: Parameter name (extension string).
+ * @param[in,out] p_index_type: Pointer to extension string's index type.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_extension_index(OMX_HANDLETYPE cmp_handle,
+ OMX_STRING param_name,
+ OMX_INDEXTYPE *p_index_type)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_index_type == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_index_type = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ goto get_extension_index_exit;
+ }
+
+ OMX_SWVDEC_LOG_API("'%s'", param_name);
+
+ if (!strncmp(param_name,
+ "OMX.QCOM.index.param.video.SyncFrameDecodingMode",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type =
+ (OMX_INDEXTYPE) OMX_QcomIndexParamVideoSyncFrameDecodingMode;
+ }
+ else if (!strncmp(param_name,
+ "OMX.QCOM.index.param.IndexExtraData",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type = (OMX_INDEXTYPE) OMX_QcomIndexParamIndexExtraDataType;
+ }
+ else if (!strncmp(param_name,
+ "OMX.google.android.index.enableAndroidNativeBuffers",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type =
+ (OMX_INDEXTYPE) OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
+ }
+ else if (!strncmp(param_name,
+ "OMX.google.android.index.useAndroidNativeBuffer2",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type =
+ (OMX_INDEXTYPE) OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
+ }
+ else if (!strncmp(param_name,
+ "OMX.google.android.index.useAndroidNativeBuffer",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type =
+ (OMX_INDEXTYPE) OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
+ }
+ else if (!strncmp(param_name,
+ "OMX.google.android.index.getAndroidNativeBufferUsage",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type =
+ (OMX_INDEXTYPE) OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
+ }
+ else if (!strncmp(param_name,
+ "OMX.google.android.index.storeMetaDataInBuffers",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type = (OMX_INDEXTYPE) OMX_QcomIndexParamVideoMetaBufferMode;
+ }
+ else if (!strncmp(param_name,
+ "OMX.google.android.index.describeColorFormat",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type = (OMX_INDEXTYPE) OMX_QcomIndexFlexibleYUVDescription;
+ }
+ else if (!strncmp(param_name,
+ "OMX.google.android.index.prepareForAdaptivePlayback",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ *p_index_type =
+ (OMX_INDEXTYPE) OMX_QcomIndexParamVideoAdaptivePlaybackMode;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("'%s': not implemented", param_name);
+
+ retval = OMX_ErrorNotImplemented;
+ }
+
+get_extension_index_exit:
+ return retval;
+}
+
+/**
+ * @brief Get component state.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in,out] p_state: Pointer to state variable.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_state(OMX_HANDLETYPE cmp_handle,
+ OMX_STATETYPE *p_state)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_API("%s", OMX_STATETYPE_STRING(m_state));
+
+ *p_state = m_state;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Component tunnel request.
+ *
+ * @retval OMX_ErrorNotImplemented
+ */
+OMX_ERRORTYPE omx_swvdec::component_tunnel_request(
+ OMX_HANDLETYPE cmp_handle,
+ OMX_U32 port,
+ OMX_HANDLETYPE peer_component,
+ OMX_U32 peer_port,
+ OMX_TUNNELSETUPTYPE *p_tunnel_setup)
+{
+ (void) cmp_handle;
+ (void) port;
+ (void) peer_component;
+ (void) peer_port;
+ (void) p_tunnel_setup;
+
+ OMX_SWVDEC_LOG_API("");
+
+ OMX_SWVDEC_LOG_ERROR("not implemented");
+
+ return OMX_ErrorNotImplemented;
+}
+
+/**
+ * @brief Use buffer.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
+ * structure.
+ * @param[in] port: Port index.
+ * @param[in] p_app_data: Pointer to IL client app data.
+ * @param[in] bytes: Size of buffer to be allocated in bytes.
+ * @param[in] p_buffer: Pointer to buffer to be used.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::use_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR p_app_data,
+ OMX_U32 bytes,
+ OMX_U8 *p_buffer)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (pp_buffer_hdr == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("pp_buffer_hdr = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_API("port index %d, %p", port, p_buffer);
+
+ if (port == OMX_CORE_PORT_INDEX_OP)
+ {
+ retval = buffer_use_op(pp_buffer_hdr, p_app_data, bytes, p_buffer);
+
+ if (retval == OMX_ErrorNone)
+ {
+ SWVDEC_STATUS retval_swvdec;
+
+ if ((m_status_flags & (1 << PENDING_STATE_LOADED_TO_IDLE)) &&
+ (m_port_ip.populated == OMX_TRUE) &&
+ (m_port_op.populated == OMX_TRUE))
+ {
+ if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ goto use_buffer_exit;
+ }
+
+ m_status_flags &= ~(1 << PENDING_STATE_LOADED_TO_IDLE);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandStateSet,
+ OMX_StateIdle);
+ }
+
+ if ((m_status_flags & (1 << PENDING_PORT_ENABLE_OP)) &&
+ (m_port_op.populated == OMX_TRUE))
+ {
+ if (m_port_reconfig_inprogress)
+ {
+ if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+
+ m_status_flags &= ~(1 << PENDING_PORT_ENABLE_OP);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandPortEnable,
+ OMX_CORE_PORT_INDEX_OP);
+ }
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ }
+
+use_buffer_exit:
+ return retval;
+}
+
+/**
+ * @brief Allocate new buffer & associated header.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
+ * structure.
+ * @param[in] port: Port index.
+ * @param[in] p_app_data: Pointer to IL client app data.
+ * @param[in] bytes: Size of buffer to be allocated in bytes.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::allocate_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR p_app_data,
+ OMX_U32 bytes)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (pp_buffer_hdr == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("pp_buffer_hdr = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_API("port index %d, %d bytes", port, bytes);
+
+ if (port == OMX_CORE_PORT_INDEX_IP)
+ {
+ retval = buffer_allocate_ip(pp_buffer_hdr,
+ p_app_data,
+ bytes);
+ }
+ else if (port == OMX_CORE_PORT_INDEX_OP)
+ {
+ if (m_meta_buffer_mode == true)
+ {
+ OMX_SWVDEC_LOG_ERROR("'meta buffer mode' enabled");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (m_android_native_buffers == true)
+ {
+ OMX_SWVDEC_LOG_ERROR("'android native buffers' enabled");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ retval = buffer_allocate_op(pp_buffer_hdr,
+ p_app_data,
+ bytes);
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index %d invalid", port);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ if (retval == OMX_ErrorNone)
+ {
+ SWVDEC_STATUS retval_swvdec;
+
+ if ((m_status_flags & (1 << PENDING_STATE_LOADED_TO_IDLE)) &&
+ (m_port_ip.populated == OMX_TRUE) &&
+ (m_port_op.populated == OMX_TRUE))
+ {
+ if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ goto allocate_buffer_exit;
+ }
+
+ m_status_flags &= ~(1 << PENDING_STATE_LOADED_TO_IDLE);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandStateSet,
+ OMX_StateIdle);
+ }
+
+ if ((m_status_flags & (1 << PENDING_PORT_ENABLE_IP)) &&
+ (m_port_ip.populated == OMX_TRUE))
+ {
+ m_status_flags &= ~(1 << PENDING_PORT_ENABLE_IP);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandPortEnable,
+ OMX_CORE_PORT_INDEX_IP);
+ }
+
+ if ((m_status_flags & (1 << PENDING_PORT_ENABLE_OP)) &&
+ (m_port_op.populated == OMX_TRUE))
+ {
+ if (m_port_reconfig_inprogress)
+ {
+ if ((retval_swvdec = swvdec_start(m_swvdec_handle)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+
+ m_status_flags &= ~(1 << PENDING_PORT_ENABLE_OP);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandPortEnable,
+ OMX_CORE_PORT_INDEX_OP);
+ }
+ }
+ }
+
+allocate_buffer_exit:
+ return retval;
+}
+
+/**
+ * @brief Release buffer & associated header.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] port: Port index.
+ * @param[in] p_buffer_hdr: Pointer to buffer's buffer header.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::free_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_U32 port,
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_buffer_hdr == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if ((port != OMX_CORE_PORT_INDEX_IP) &&
+ (port != OMX_CORE_PORT_INDEX_OP))
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else if (m_state != OMX_StateIdle)
+ {
+ if (m_state != OMX_StateExecuting)
+ {
+ OMX_SWVDEC_LOG_ERROR("disallowed in state %s",
+ OMX_STATETYPE_STRING(m_state));
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ if (((port == OMX_CORE_PORT_INDEX_IP) && m_port_ip.enabled) ||
+ ((port == OMX_CORE_PORT_INDEX_OP) && m_port_op.enabled))
+ {
+ OMX_SWVDEC_LOG_ERROR("port index %d not disabled", port);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ }
+ }
+
+ if (retval == OMX_ErrorNone)
+ {
+ OMX_SWVDEC_LOG_API("port index %d, %p", port, p_buffer_hdr);
+
+ if (port == OMX_CORE_PORT_INDEX_IP)
+ {
+ retval = buffer_deallocate_ip(p_buffer_hdr);
+ }
+ else
+ {
+ retval = buffer_deallocate_op(p_buffer_hdr);
+ }
+ }
+
+ if ((retval == OMX_ErrorNone) &&
+ (m_status_flags & (1 << PENDING_STATE_IDLE_TO_LOADED)))
+ {
+ if ((m_port_ip.unpopulated == OMX_TRUE) &&
+ (m_port_op.unpopulated == OMX_TRUE))
+ {
+ SWVDEC_STATUS retval_swvdec;
+
+ if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) ==
+ SWVDEC_STATUS_SUCCESS)
+ {
+ m_status_flags &= ~(1 << PENDING_STATE_IDLE_TO_LOADED);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandStateSet,
+ OMX_StateLoaded);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+ }
+
+ if ((retval == OMX_ErrorNone) &&
+ (m_status_flags & (1 << PENDING_PORT_DISABLE_IP)) &&
+ m_port_ip.unpopulated)
+ {
+ m_status_flags &= ~(1 << PENDING_PORT_DISABLE_IP);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandPortDisable,
+ OMX_CORE_PORT_INDEX_IP);
+ }
+
+ if ((retval == OMX_ErrorNone) &&
+ (m_status_flags & (1 << PENDING_PORT_DISABLE_OP)) &&
+ m_port_op.unpopulated)
+ {
+ if (m_port_reconfig_inprogress)
+ {
+ SWVDEC_STATUS retval_swvdec;
+
+ if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+
+ m_status_flags &= ~(1 << PENDING_PORT_DISABLE_OP);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandPortDisable,
+ OMX_CORE_PORT_INDEX_OP);
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Send a buffer to component's input port to be emptied.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] p_buffer_hdr: Pointer to buffer's buffer header.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::empty_this_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_buffer_hdr == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (p_buffer_hdr->pBuffer == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pBuffer = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (p_buffer_hdr->pInputPortPrivate == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pInputPortPrivate = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (m_port_ip.enabled == OMX_FALSE)
+ {
+ OMX_SWVDEC_LOG_ERROR("ip port disabled");
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else if (p_buffer_hdr->nInputPortIndex != OMX_CORE_PORT_INDEX_IP)
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_buffer_hdr->nInputPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ goto empty_this_buffer_exit;
+ }
+
+ for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
+ {
+ if (p_buffer_hdr == &(m_buffer_array_ip[ii].buffer_header))
+ {
+ OMX_SWVDEC_LOG_LOW("ip buffer %p has index %d",
+ p_buffer_hdr->pBuffer,
+ ii);
+ break;
+ }
+ }
+
+ if (ii == m_port_ip.def.nBufferCountActual)
+ {
+ OMX_SWVDEC_LOG_ERROR("ip buffer %p not found",
+ p_buffer_hdr->pBuffer);
+
+ retval = OMX_ErrorBadParameter;
+ goto empty_this_buffer_exit;
+ }
+
+ OMX_SWVDEC_LOG_API("%p: buffer %p, flags 0x%08x, filled length %d, "
+ "timestamp %lld",
+ p_buffer_hdr,
+ p_buffer_hdr->pBuffer,
+ p_buffer_hdr->nFlags,
+ p_buffer_hdr->nFilledLen,
+ p_buffer_hdr->nTimeStamp);
+
+ async_post_event(OMX_SWVDEC_EVENT_ETB,
+ (unsigned long) p_buffer_hdr,
+ (unsigned long) ii);
+
+empty_this_buffer_exit:
+ return retval;
+}
+
+/**
+ * @brief Send a buffer to component's output port to be filled.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] p_buffer_hdr: Pointer to buffer's buffer header.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::fill_this_buffer(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ SWVDEC_BUFFER *p_buffer_swvdec;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_buffer_hdr == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (p_buffer_hdr->pBuffer == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pBuffer = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (p_buffer_hdr->pOutputPortPrivate == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr->pOutputPortPrivate = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (m_port_op.enabled == OMX_FALSE)
+ {
+ OMX_SWVDEC_LOG_ERROR("op port disabled");
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else if (p_buffer_hdr->nOutputPortIndex != OMX_CORE_PORT_INDEX_OP)
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_buffer_hdr->nOutputPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ goto fill_this_buffer_exit;
+ }
+
+ OMX_SWVDEC_LOG_API("%p", p_buffer_hdr);
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ if (p_buffer_hdr == &(m_buffer_array_op[ii].buffer_header))
+ {
+ OMX_SWVDEC_LOG_LOW("op buffer %p has index %d",
+ p_buffer_hdr->pBuffer,
+ ii);
+ break;
+ }
+ }
+
+ if (ii == m_port_op.def.nBufferCountActual)
+ {
+ OMX_SWVDEC_LOG_ERROR("op buffer %p not found",
+ p_buffer_hdr->pBuffer);
+
+ retval = OMX_ErrorBadParameter;
+ goto fill_this_buffer_exit;
+ }
+
+ p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
+
+ if (m_meta_buffer_mode)
+ {
+ struct VideoDecoderOutputMetaData *p_meta_data;
+
+ private_handle_t *p_private_handle;
+
+ struct vdec_bufferpayload *p_buffer_payload;
+
+ p_meta_data =
+ (struct VideoDecoderOutputMetaData *) p_buffer_hdr->pBuffer;
+
+ p_private_handle = (private_handle_t *) (p_meta_data->pHandle);
+
+ p_buffer_payload = &m_buffer_array_op[ii].buffer_payload;
+
+ if (p_private_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR(
+ "p_buffer_hdr->pBuffer->pHandle = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ goto fill_this_buffer_exit;
+ }
+
+ pthread_mutex_lock(&m_meta_buffer_array_mutex);
+
+ if (m_meta_buffer_array[ii].ref_count == 0)
+ {
+ unsigned char *bufferaddr;
+
+ bufferaddr = (unsigned char *) mmap(NULL,
+ m_port_op.def.nBufferSize,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ p_private_handle->fd,
+ 0);
+
+ if (bufferaddr == MAP_FAILED)
+ {
+ OMX_SWVDEC_LOG_ERROR("mmap() failed for "
+ "fd %d of size %d",
+ p_private_handle->fd,
+ m_port_op.def.nBufferSize);
+
+ pthread_mutex_unlock(&m_meta_buffer_array_mutex);
+
+ retval = OMX_ErrorInsufficientResources;
+ goto fill_this_buffer_exit;
+ }
+
+ p_buffer_payload->bufferaddr = bufferaddr;
+ p_buffer_payload->pmem_fd = p_private_handle->fd;
+ p_buffer_payload->buffer_len = m_port_op.def.nBufferSize;
+ p_buffer_payload->mmaped_size = m_port_op.def.nBufferSize;
+
+ p_buffer_swvdec->p_buffer = bufferaddr;
+ p_buffer_swvdec->size = m_port_op.def.nBufferSize;
+ p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
+ }
+
+ meta_buffer_ref_add(ii, p_buffer_payload->pmem_fd);
+
+ pthread_mutex_unlock(&m_meta_buffer_array_mutex);
+ }
+
+ OMX_SWVDEC_LOG_LOW("%p: buffer %p",
+ p_buffer_hdr,
+ p_buffer_swvdec->p_buffer);
+
+ async_post_event(OMX_SWVDEC_EVENT_FTB,
+ (unsigned long) p_buffer_hdr,
+ (unsigned long) ii);
+
+fill_this_buffer_exit:
+ return retval;
+}
+
+/**
+ * @brief Set component's callback structure.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in] p_callbacks: Pointer to callback structure.
+ * @param[in] p_app_data: Pointer to IL client app data.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_callbacks(OMX_HANDLETYPE cmp_handle,
+ OMX_CALLBACKTYPE *p_callbacks,
+ OMX_PTR p_app_data)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_LOG_API("");
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (p_callbacks->EventHandler == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_callbacks->EventHandler = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (p_callbacks->EmptyBufferDone == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_callbacks->EmptyBufferDone = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else if (p_callbacks->FillBufferDone == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_callbacks->FillBufferDone = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ m_callback = *p_callbacks;
+ m_app_data = p_app_data;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Use EGL image.
+ *
+ * @retval OMX_ErrorNotImplemented
+ */
+OMX_ERRORTYPE omx_swvdec::use_EGL_image(OMX_HANDLETYPE cmp_handle,
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_U32 port,
+ OMX_PTR p_app_data,
+ void *egl_image)
+{
+ (void) cmp_handle;
+ (void) pp_buffer_hdr;
+ (void) port;
+ (void) p_app_data;
+ (void) egl_image;
+
+ OMX_SWVDEC_LOG_API("");
+
+ OMX_SWVDEC_LOG_ERROR("not implemented");
+
+ return OMX_ErrorNotImplemented;
+}
+
+/**
+ * @brief Enumerate component role.
+ *
+ * @param[in] cmp_handle: Component handle.
+ * @param[in,out] p_role: Pointer to component role string.
+ * @param[in] index: Role index being queried.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::component_role_enum(OMX_HANDLETYPE cmp_handle,
+ OMX_U8 *p_role,
+ OMX_U32 index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in invalid state");
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (cmp_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cmp_handle = NULL");
+
+ retval = OMX_ErrorInvalidComponent;
+ }
+ else if (index > 0)
+ {
+ OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; no more roles", index);
+
+ retval = OMX_ErrorNoMore;
+ }
+ else
+ {
+ memcpy(p_role, m_role_name, OMX_MAX_STRINGNAME_SIZE);
+
+ OMX_SWVDEC_LOG_API("index '%d': '%s'", index, p_role);
+ }
+
+ return retval;
+}
+
+/**
+ * -------------------------
+ * SwVdec callback functions
+ * -------------------------
+ */
+
+/**
+ * @brief SwVdec empty buffer done callback.
+ *
+ * @param[in] swvdec_handle: SwVdec handle.
+ * @param[in] p_buffer_ip: Pointer to input buffer structure.
+ * @param[in] p_client_handle: Pointer to SwVdec's client handle.
+ *
+ * @retval SWVDEC_STATUS_SUCCESS
+ * @retval SWVDEC_STATUS_NULL_POINTER
+ * @retval SWVDEC_STATUS_INVALID_PARAMETERS
+ */
+SWVDEC_STATUS omx_swvdec::swvdec_empty_buffer_done_callback(
+ SWVDEC_HANDLE swvdec_handle,
+ SWVDEC_BUFFER *p_buffer_ip,
+ void *p_client_handle)
+{
+ SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
+
+ if (p_buffer_ip == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_ip = NULL");
+
+ retval = SWVDEC_STATUS_NULL_POINTER;
+ }
+ else if (p_client_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
+
+ retval = SWVDEC_STATUS_NULL_POINTER;
+ }
+ else
+ {
+ omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
+
+ if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
+ {
+ OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
+
+ retval = SWVDEC_STATUS_INVALID_PARAMETERS;
+ }
+ else
+ {
+ p_omx_swvdec->swvdec_empty_buffer_done(p_buffer_ip);
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief SwVdec fill buffer done callback.
+ *
+ * @param[in] swvdec_handle: SwVdec handle.
+ * @param[in] p_buffer_op: Pointer to output buffer structure.
+ * @param[in] p_client_handle: Pointer to SwVdec's client handle.
+ *
+ * @retval SWVDEC_STATUS_SUCCESS
+ * @retval SWVDEC_STATUS_NULL_POINTER
+ * @retval SWVDEC_STATUS_INVALID_PARAMETERS
+ */
+SWVDEC_STATUS omx_swvdec::swvdec_fill_buffer_done_callback(
+ SWVDEC_HANDLE swvdec_handle,
+ SWVDEC_BUFFER *p_buffer_op,
+ void *p_client_handle)
+{
+ SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
+
+ if (p_buffer_op == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_op = NULL");
+
+ retval = SWVDEC_STATUS_NULL_POINTER;
+ }
+ else if (p_client_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
+
+ retval = SWVDEC_STATUS_NULL_POINTER;
+ }
+ else
+ {
+ omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
+
+ if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
+ {
+ OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
+
+ retval = SWVDEC_STATUS_INVALID_PARAMETERS;
+ }
+ else
+ {
+ p_omx_swvdec->swvdec_fill_buffer_done(p_buffer_op);
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief SwVdec event handler callback.
+ *
+ * @param[in] swvdec_handle: SwVdec handle.
+ * @param[in] event: Event.
+ * @param[in] p_data: Pointer to event-specific data.
+ * @param[in] p_client_handle: Pointer to SwVdec's client handle.
+ *
+ * @retval SWVDEC_STATUS_SUCCESS
+ * @retval SWVDEC_STATUS_NULL_POINTER
+ * @retval SWVDEC_STATUS_INVALID_PARAMETERS
+ */
+SWVDEC_STATUS omx_swvdec::swvdec_event_handler_callback(
+ SWVDEC_HANDLE swvdec_handle,
+ SWVDEC_EVENT event,
+ void *p_data,
+ void *p_client_handle)
+{
+ SWVDEC_STATUS retval = SWVDEC_STATUS_SUCCESS;
+
+ if ((event == SWVDEC_EVENT_RELEASE_REFERENCE) && (p_data == NULL))
+ {
+ OMX_SWVDEC_LOG_ERROR("p_data = NULL");
+
+ retval = SWVDEC_STATUS_NULL_POINTER;
+ }
+ else if (p_client_handle == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_client_handle = NULL");
+
+ retval = SWVDEC_STATUS_NULL_POINTER;
+ }
+ else
+ {
+ omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_client_handle;
+
+ if (swvdec_handle != p_omx_swvdec->m_swvdec_handle)
+ {
+ OMX_SWVDEC_LOG_ERROR("invalid SwVdec handle");
+
+ retval = SWVDEC_STATUS_INVALID_PARAMETERS;
+ }
+ else
+ {
+ p_omx_swvdec->swvdec_event_handler(event, p_data);
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * -----------------
+ * PRIVATE FUNCTIONS
+ * -----------------
+ */
+
+/**
+ * @brief Set frame dimensions for OMX component & SwVdec core.
+ *
+ * @param[in] width: Frame width.
+ * @param[in] height: Frame height.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_frame_dimensions(unsigned int width,
+ unsigned int height)
+{
+ OMX_ERRORTYPE retval;
+
+ m_frame_dimensions.width = width;
+ m_frame_dimensions.height = height;
+
+ OMX_SWVDEC_LOG_HIGH("%d x %d",
+ m_frame_dimensions.width,
+ m_frame_dimensions.height);
+
+ retval = set_frame_dimensions_swvdec();
+
+ return retval;
+}
+
+/**
+ * @brief Set frame attributes for OMX component & SwVdec core, based on
+ * frame dimensions & color format.
+ *
+ * @param[in] color_format: Color format.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_frame_attributes(
+ OMX_COLOR_FORMATTYPE color_format)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int width = m_frame_dimensions.width;
+ unsigned int height = m_frame_dimensions.height;
+
+ unsigned int scanlines_uv;
+
+ unsigned int plane_size_y;
+ unsigned int plane_size_uv;
+
+ switch (color_format)
+ {
+
+ case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:
+ {
+ /**
+ * alignment factors:
+ *
+ * - stride: 128
+ * - scanlines_y: 32
+ * - scanlines_uv: 16
+ * - size: 4096
+ */
+
+ m_frame_attributes.stride = ALIGN(width, 128);
+ m_frame_attributes.scanlines = ALIGN(height, 32);
+
+ scanlines_uv = ALIGN(height / 2, 16);
+
+ plane_size_y = (m_frame_attributes.stride *
+ m_frame_attributes.scanlines);
+
+ plane_size_uv = m_frame_attributes.stride * scanlines_uv;
+
+ m_frame_attributes.size = ALIGN(plane_size_y + plane_size_uv, 4096);
+
+ OMX_SWVDEC_LOG_HIGH("'OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m': "
+ "stride %d, scanlines %d, size %d",
+ m_frame_attributes.stride,
+ m_frame_attributes.scanlines,
+ m_frame_attributes.size);
+
+ break;
+ }
+
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ {
+ /**
+ * alignment factors:
+ *
+ * - stride: 16
+ * - scanlines_y: 16
+ * - scanlines_uv: 16
+ * - size: 4096
+ */
+
+ m_frame_attributes.stride = ALIGN(width, 16);
+ m_frame_attributes.scanlines = ALIGN(height, 16);
+
+ scanlines_uv = ALIGN(height / 2, 16);
+
+ plane_size_y = (m_frame_attributes.stride *
+ m_frame_attributes.scanlines);
+
+ plane_size_uv = m_frame_attributes.stride * scanlines_uv;
+
+ m_frame_attributes.size = ALIGN(plane_size_y + plane_size_uv, 4096);
+
+ OMX_SWVDEC_LOG_HIGH("'OMX_COLOR_FormatYUV420SemiPlanar': "
+ "stride %d, scanlines %d, size %d",
+ m_frame_attributes.stride,
+ m_frame_attributes.scanlines,
+ m_frame_attributes.size);
+
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR("'0x%08x' color format invalid or unsupported",
+ color_format);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch (color_format)
+
+ if (retval == OMX_ErrorNone)
+ {
+ m_omx_color_formattype = color_format;
+
+ retval = set_frame_attributes_swvdec();
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Set maximum adaptive playback frame dimensions for OMX component &
+ * SwVdec core.
+ *
+ * @param[in] width: Max adaptive playback frame width.
+ * @param[in] height: Max adaptive playback frame height.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_adaptive_playback(unsigned int max_width,
+ unsigned int max_height)
+{
+ OMX_ERRORTYPE retval;
+
+ m_frame_dimensions_max.width = max_width;
+ m_frame_dimensions_max.height = max_height;
+
+ OMX_SWVDEC_LOG_HIGH("%d x %d",
+ m_frame_dimensions_max.width,
+ m_frame_dimensions_max.height);
+
+ retval = set_adaptive_playback_swvdec();
+
+ if (retval == OMX_ErrorNone)
+ {
+ retval = set_frame_dimensions(max_width, max_height);
+ }
+
+ if (retval == OMX_ErrorNone)
+ {
+ retval = set_frame_attributes(m_omx_color_formattype);
+ }
+
+set_adaptive_playback_exit:
+ return retval;
+}
+
+/**
+ * @brief Get video port format for input or output port.
+ *
+ * @param[in,out] p_port_format: Pointer to video port format type.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_video_port_format(
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP)
+ {
+ if (p_port_format->nIndex == 0)
+ {
+ p_port_format->eColorFormat = OMX_COLOR_FormatUnused;
+
+ p_port_format->eCompressionFormat = m_omx_video_codingtype;
+
+ OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
+ "compression format 0x%08x",
+ p_port_format->eColorFormat,
+ p_port_format->eCompressionFormat);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; "
+ "no more compression formats",
+ p_port_format->nIndex);
+
+ retval = OMX_ErrorNoMore;
+ }
+ }
+ else if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ if (p_port_format->nIndex == 0)
+ {
+ p_port_format->eColorFormat =
+ OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m;
+
+ p_port_format->eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+ OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
+ "compression format 0x%08x",
+ p_port_format->eColorFormat,
+ p_port_format->eCompressionFormat);
+ }
+ else if (p_port_format->nIndex == 1)
+ {
+ p_port_format->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+
+ p_port_format->eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+ OMX_SWVDEC_LOG_HIGH("color format 0x%08x, "
+ "compression format 0x%08x",
+ p_port_format->eColorFormat,
+ p_port_format->eCompressionFormat);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_HIGH("index '%d' unsupported; no more color formats",
+ p_port_format->nIndex);
+
+ retval = OMX_ErrorNoMore;
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_port_format->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Set video port format for input or output port.
+ *
+ * @param[in] p_port_format: Pointer to video port format type.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_video_port_format(
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *p_port_format)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_IP)
+ {
+ OMX_SWVDEC_LOG_HIGH("OMX_IndexParamVideoPortFormat, port index 0; "
+ "doing nothing");
+ }
+ else if (p_port_format->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ retval = set_frame_attributes(p_port_format->eColorFormat);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_port_format->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+set_video_port_format_exit:
+ return retval;
+}
+
+/**
+ * @brief Get port definition for input or output port.
+ *
+ * @param[in,out] p_port_def: Pointer to port definition type.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_port_definition(
+ OMX_PARAM_PORTDEFINITIONTYPE *p_port_def)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ p_port_def->eDomain = OMX_PortDomainVideo;
+
+ if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
+ {
+ if ((retval = get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_IP)) !=
+ OMX_ErrorNone)
+ {
+ goto get_port_definition_exit;
+ }
+
+ p_port_def->eDir = OMX_DirInput;
+ p_port_def->nBufferCountActual = m_port_ip.def.nBufferCountActual;
+ p_port_def->nBufferCountMin = m_port_ip.def.nBufferCountMin;
+ p_port_def->nBufferSize = m_port_ip.def.nBufferSize;
+ p_port_def->bEnabled = m_port_ip.enabled;
+ p_port_def->bPopulated = m_port_ip.populated;
+
+ OMX_SWVDEC_LOG_HIGH("port index %d: "
+ "count actual %d, count min %d, size %d",
+ p_port_def->nPortIndex,
+ p_port_def->nBufferCountActual,
+ p_port_def->nBufferCountMin,
+ p_port_def->nBufferSize);
+
+ // frame dimensions & attributes don't apply to input port
+
+ p_port_def->format.video.eColorFormat = OMX_COLOR_FormatUnused;
+ p_port_def->format.video.eCompressionFormat = m_omx_video_codingtype;
+ }
+ else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ if ((retval = get_frame_dimensions_swvdec()) != OMX_ErrorNone)
+ {
+ goto get_port_definition_exit;
+ }
+
+ p_port_def->format.video.nFrameWidth = m_frame_dimensions.width;
+ p_port_def->format.video.nFrameHeight = m_frame_dimensions.height;
+
+ if (m_port_reconfig_inprogress)
+ {
+ if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
+ OMX_ErrorNone)
+ {
+ goto get_port_definition_exit;
+ }
+ }
+
+ if ((retval = get_frame_attributes_swvdec()) != OMX_ErrorNone)
+ {
+ goto get_port_definition_exit;
+ }
+
+ p_port_def->format.video.nStride = m_frame_attributes.stride;
+ p_port_def->format.video.nSliceHeight = m_frame_attributes.scanlines;
+
+ OMX_SWVDEC_LOG_HIGH("port index %d: "
+ "%d x %d, stride %d, sliceheight %d",
+ p_port_def->nPortIndex,
+ p_port_def->format.video.nFrameWidth,
+ p_port_def->format.video.nFrameHeight,
+ p_port_def->format.video.nStride,
+ p_port_def->format.video.nSliceHeight);
+
+ /**
+ * Query to SwVdec core for buffer requirements is not allowed in
+ * executing state since it will overwrite the component's buffer
+ * requirements updated via the most recent set_parameter().
+ *
+ * Buffer requirements communicated to component via set_parameter() are
+ * not propagated to SwVdec core.
+ *
+ * The only execption is if port reconfiguration is in progress, in
+ * which case the query to SwVdec core is required since buffer
+ * requirements can change based on new dimensions.
+ */
+ if ((m_state != OMX_StateExecuting) || m_port_reconfig_inprogress)
+ {
+ if ((retval =
+ get_buffer_requirements_swvdec(OMX_CORE_PORT_INDEX_OP)) !=
+ OMX_ErrorNone)
+ {
+ goto get_port_definition_exit;
+ }
+ }
+
+ p_port_def->eDir = OMX_DirOutput;
+ p_port_def->nBufferCountActual = m_port_op.def.nBufferCountActual;
+ p_port_def->nBufferCountMin = m_port_op.def.nBufferCountMin;
+ p_port_def->nBufferSize = m_port_op.def.nBufferSize;
+ p_port_def->bEnabled = m_port_op.enabled;
+ p_port_def->bPopulated = m_port_op.populated;
+
+ OMX_SWVDEC_LOG_HIGH("port index %d: "
+ "count actual %d, count min %d, size %d",
+ p_port_def->nPortIndex,
+ p_port_def->nBufferCountActual,
+ p_port_def->nBufferCountMin,
+ p_port_def->nBufferSize);
+
+ p_port_def->format.video.eColorFormat = m_omx_color_formattype;
+ p_port_def->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+ if (m_omx_color_formattype ==
+ OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m)
+ {
+ OMX_SWVDEC_LOG_HIGH(
+ "port index %d: color format '0x%08x': "
+ "OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m",
+ p_port_def->nPortIndex,
+ p_port_def->format.video.eColorFormat);
+ }
+ else if (m_omx_color_formattype == OMX_COLOR_FormatYUV420SemiPlanar)
+ {
+ OMX_SWVDEC_LOG_HIGH("port index %d: color format '0x%08x': "
+ "OMX_COLOR_FormatYUV420SemiPlanar",
+ p_port_def->nPortIndex,
+ p_port_def->format.video.eColorFormat);
+ }
+ else
+ {
+ assert(0);
+ retval = OMX_ErrorUndefined;
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", p_port_def->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+get_port_definition_exit:
+ return retval;
+}
+
+/**
+ * @brief Set port definition for input or output port.
+ *
+ * @param[in] p_port_def: Pointer to port definition type.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_port_definition(
+ OMX_PARAM_PORTDEFINITIONTYPE *p_port_def)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_LOG_HIGH("port index %d: "
+ "count actual %d, count min %d, size %d",
+ p_port_def->nPortIndex,
+ p_port_def->nBufferCountActual,
+ p_port_def->nBufferCountMin,
+ p_port_def->nBufferSize);
+
+ if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
+ {
+ m_port_ip.def.nBufferCountActual = p_port_def->nBufferCountActual;
+ m_port_ip.def.nBufferCountMin = p_port_def->nBufferCountMin;
+ m_port_ip.def.nBufferSize = p_port_def->nBufferSize;
+ }
+ else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ /**
+ * OMX component's output port nBufferSize is not updated based on what
+ * IL client sends; instead it is updated based on the possibly updated
+ * frame attributes.
+ *
+ * This is because set_parameter() for output port definition only has
+ * updates to buffer counts or frame dimensions.
+ */
+
+ m_port_op.def.nBufferCountActual = p_port_def->nBufferCountActual;
+ m_port_op.def.nBufferCountMin = p_port_def->nBufferCountMin;
+
+ OMX_SWVDEC_LOG_HIGH("port index %d: %d x %d",
+ p_port_def->nPortIndex,
+ p_port_def->format.video.nFrameWidth,
+ p_port_def->format.video.nFrameHeight);
+
+ /**
+ * Update frame dimensions & attributes if:
+ *
+ * 1. not in adaptive playback mode
+ * OR
+ * 2. new frame dimensions greater than adaptive playback mode's
+ * max frame dimensions
+ */
+
+ if ((m_adaptive_playback_mode == false) ||
+ (p_port_def->format.video.nFrameWidth >
+ m_frame_dimensions_max.width) ||
+ (p_port_def->format.video.nFrameHeight >
+ m_frame_dimensions_max.height))
+ {
+ OMX_SWVDEC_LOG_HIGH("updating frame dimensions & attributes");
+
+ if ((retval =
+ set_frame_dimensions(p_port_def->format.video.nFrameWidth,
+ p_port_def->format.video.nFrameHeight)) !=
+ OMX_ErrorNone)
+ {
+ goto set_port_definition_exit;
+ }
+
+ if ((retval = set_frame_attributes(m_omx_color_formattype)) !=
+ OMX_ErrorNone)
+ {
+ goto set_port_definition_exit;
+ }
+
+ // nBufferSize updated based on (possibly new) frame attributes
+
+ m_port_op.def.nBufferSize = m_frame_attributes.size;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_HIGH("not updating frame dimensions & attributes");
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", p_port_def->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+set_port_definition_exit:
+ return retval;
+}
+
+/**
+ * @brief Get supported profile & level.
+ *
+ * The supported profiles & levels are not queried from SwVdec core, but
+ * hard-coded. This should ideally be replaced with a query to SwVdec core.
+ *
+ * @param[in,out] p_profilelevel: Pointer to video profile & level type.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_supported_profilelevel(
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *p_profilelevel)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (p_profilelevel == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_profilelevel = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ goto get_supported_profilelevel_exit;
+ }
+
+ if (p_profilelevel->nPortIndex != OMX_CORE_PORT_INDEX_IP)
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_profilelevel->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ goto get_supported_profilelevel_exit;
+ }
+
+ if (m_omx_video_codingtype == OMX_VIDEO_CodingH263)
+ {
+ if (p_profilelevel->nProfileIndex == 0)
+ {
+ p_profilelevel->eProfile = OMX_VIDEO_H263ProfileBaseline;
+ p_profilelevel->eLevel = OMX_VIDEO_H263Level70;
+
+ OMX_SWVDEC_LOG_HIGH("H.263 baseline profile, level 70");
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_HIGH("profile index '%d' unsupported; "
+ "no more profiles",
+ p_profilelevel->nProfileIndex);
+
+ retval = OMX_ErrorNoMore;
+ }
+ }
+ else if ((m_omx_video_codingtype == OMX_VIDEO_CodingMPEG4) ||
+ (m_omx_video_codingtype ==
+ ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx)))
+ {
+ if (p_profilelevel->nProfileIndex == 0)
+ {
+ p_profilelevel->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
+ p_profilelevel->eLevel = OMX_VIDEO_MPEG4Level5;
+
+ OMX_SWVDEC_LOG_HIGH("MPEG-4 simple profile, level 5");
+ }
+ else if (p_profilelevel->nProfileIndex == 1)
+ {
+ p_profilelevel->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
+ p_profilelevel->eLevel = OMX_VIDEO_MPEG4Level5;
+
+ OMX_SWVDEC_LOG_HIGH("MPEG-4 advanced simple profile, level 5");
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_HIGH("profile index '%d' unsupported; "
+ "no more profiles",
+ p_profilelevel->nProfileIndex);
+
+ retval = OMX_ErrorNoMore;
+ }
+ }
+ else
+ {
+ assert(0);
+ retval = OMX_ErrorUndefined;
+ }
+
+get_supported_profilelevel_exit:
+ return retval;
+}
+
+/**
+ * @brief Describe color format.
+ *
+ * @param[in,out] p_params: Pointer to 'DescribeColorFormatParams' structure.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::describe_color_format(
+ DescribeColorFormatParams *p_params)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (p_params == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_params = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ else
+ {
+ MediaImage *p_img = &p_params->sMediaImage;
+
+ switch (p_params->eColorFormat)
+ {
+
+ case OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar32m:
+ {
+ size_t stride, scanlines;
+
+ p_img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
+ p_img->mNumPlanes = 3;
+
+ p_img->mWidth = p_params->nFrameWidth;
+ p_img->mHeight = p_params->nFrameHeight;
+
+ /**
+ * alignment factors:
+ *
+ * - stride: 128
+ * - scanlines: 32
+ */
+ stride = ALIGN(p_img->mWidth, 128);
+ scanlines = ALIGN(p_img->mHeight, 32);
+
+ p_img->mBitDepth = 8;
+
+ // plane 0 (Y)
+ p_img->mPlane[MediaImage::Y].mOffset = 0;
+ p_img->mPlane[MediaImage::Y].mColInc = 1;
+ p_img->mPlane[MediaImage::Y].mRowInc = stride;
+ p_img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
+ p_img->mPlane[MediaImage::Y].mVertSubsampling = 1;
+
+ // plane 1 (U)
+ p_img->mPlane[MediaImage::U].mOffset = stride * scanlines;
+ p_img->mPlane[MediaImage::U].mColInc = 2;
+ p_img->mPlane[MediaImage::U].mRowInc = stride;
+ p_img->mPlane[MediaImage::U].mHorizSubsampling = 2;
+ p_img->mPlane[MediaImage::U].mVertSubsampling = 2;
+
+ // plane 2 (V)
+ p_img->mPlane[MediaImage::V].mOffset = stride * scanlines + 1;
+ p_img->mPlane[MediaImage::V].mColInc = 2;
+ p_img->mPlane[MediaImage::V].mRowInc = stride;
+ p_img->mPlane[MediaImage::V].mHorizSubsampling = 2;
+ p_img->mPlane[MediaImage::V].mVertSubsampling = 2;
+
+ break;
+ }
+
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ {
+ // do nothing; standard OMX color formats should not be described
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR("color format '0x%08x' invalid/unsupported",
+ p_params->eColorFormat);
+
+ p_img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch (p_params->eColorFormat)
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Set QTI vendor-specific port definition for input or output port.
+ *
+ * @param[in] p_port_def: Pointer to QTI vendor-specific port definition type.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_port_definition_qcom(
+ OMX_QCOM_PARAM_PORTDEFINITIONTYPE *p_port_def)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_IP)
+ {
+ switch (p_port_def->nFramePackingFormat)
+ {
+
+ case OMX_QCOM_FramePacking_Arbitrary:
+ {
+ OMX_SWVDEC_LOG_HIGH("OMX_QCOM_FramePacking_Arbitrary");
+
+ m_arbitrary_bytes_mode = true;
+
+ break;
+ }
+
+ case OMX_QCOM_FramePacking_OnlyOneCompleteFrame:
+ {
+ OMX_SWVDEC_LOG_HIGH(
+ "OMX_QCOM_FramePacking_OnlyOneCompleteFrame");
+
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR(
+ "frame packing format '%d' unsupported",
+ p_port_def->nFramePackingFormat);
+
+ retval = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+
+ }
+ }
+ else if (p_port_def->nPortIndex == OMX_CORE_PORT_INDEX_OP)
+ {
+ OMX_SWVDEC_LOG_HIGH("nMemRegion %d, nCacheAttr %d",
+ p_port_def->nMemRegion,
+ p_port_def->nCacheAttr);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ p_port_def->nPortIndex);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Set SwVdec frame dimensions based on OMX component frame dimensions.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_frame_dimensions_swvdec()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ SWVDEC_PROPERTY property;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ property.id = SWVDEC_PROPERTY_ID_FRAME_DIMENSIONS;
+
+ property.info.frame_dimensions.width = m_frame_dimensions.width;
+ property.info.frame_dimensions.height = m_frame_dimensions.height;
+
+ if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Set SwVdec frame attributes based on OMX component frame attributes.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::set_frame_attributes_swvdec()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ SWVDEC_FRAME_ATTRIBUTES *p_frame_attributes;
+
+ SWVDEC_PROPERTY property;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ p_frame_attributes = &property.info.frame_attributes;
+
+ property.id = SWVDEC_PROPERTY_ID_FRAME_ATTRIBUTES;
+
+ p_frame_attributes->color_format = SWVDEC_COLOR_FORMAT_SEMIPLANAR_NV12;
+
+ p_frame_attributes->stride = m_frame_attributes.stride;
+ p_frame_attributes->scanlines = m_frame_attributes.scanlines;
+ p_frame_attributes->size = m_frame_attributes.size;
+
+ if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Set maximum adaptive playback frame dimensions for SwVdec core.
+ */
+OMX_ERRORTYPE omx_swvdec::set_adaptive_playback_swvdec()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ SWVDEC_PROPERTY property;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ property.id = SWVDEC_PROPERTY_ID_ADAPTIVE_PLAYBACK;
+
+ property.info.frame_dimensions.width = m_frame_dimensions_max.width;
+ property.info.frame_dimensions.height = m_frame_dimensions_max.height;
+
+ if ((retval_swvdec = swvdec_setproperty(m_swvdec_handle, &property)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Get SwVdec frame dimensions and set OMX component frame dimensions.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_frame_dimensions_swvdec()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ SWVDEC_PROPERTY property;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ property.id = SWVDEC_PROPERTY_ID_FRAME_DIMENSIONS;
+
+ if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ else
+ {
+ m_frame_dimensions.width = property.info.frame_dimensions.width;
+ m_frame_dimensions.height = property.info.frame_dimensions.height;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Get SwVdec frame attributes and set OMX component frame attributes.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_frame_attributes_swvdec()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ SWVDEC_PROPERTY property;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ property.id = SWVDEC_PROPERTY_ID_FRAME_ATTRIBUTES;
+
+ if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ else
+ {
+ m_frame_attributes.stride = property.info.frame_attributes.stride;
+ m_frame_attributes.scanlines = property.info.frame_attributes.scanlines;
+ m_frame_attributes.size = property.info.frame_attributes.size;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Get SwVdec buffer requirements; set input or output port definitions.
+ *
+ * @param[in] port_index: Port index.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::get_buffer_requirements_swvdec(
+ unsigned int port_index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ SWVDEC_PROPERTY property;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ SWVDEC_BUFFER_REQ *p_buffer_req;
+
+ if (port_index == OMX_CORE_PORT_INDEX_IP)
+ {
+ property.id = SWVDEC_PROPERTY_ID_BUFFER_REQ_IP;
+
+ p_buffer_req = &property.info.buffer_req_ip;
+
+ if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ goto get_buffer_requirements_swvdec_exit;
+ }
+
+ m_port_ip.def.nBufferSize = p_buffer_req->size;
+ m_port_ip.def.nBufferCountMin = p_buffer_req->mincount;
+ m_port_ip.def.nBufferCountActual = MAX(p_buffer_req->mincount,
+ OMX_SWVDEC_IP_BUFFER_COUNT_MIN);
+ m_port_ip.def.nBufferAlignment = p_buffer_req->alignment;
+
+ OMX_SWVDEC_LOG_HIGH("ip port: %d bytes x %d, %d-byte aligned",
+ m_port_ip.def.nBufferSize,
+ m_port_ip.def.nBufferCountActual,
+ m_port_ip.def.nBufferAlignment);
+ }
+ else if (port_index == OMX_CORE_PORT_INDEX_OP)
+ {
+ property.id = SWVDEC_PROPERTY_ID_BUFFER_REQ_OP;
+
+ p_buffer_req = &property.info.buffer_req_op;
+
+ if ((retval_swvdec = swvdec_getproperty(m_swvdec_handle, &property)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ goto get_buffer_requirements_swvdec_exit;
+ }
+
+ if (m_sync_frame_decoding_mode)
+ {
+ p_buffer_req->mincount = 1;
+ }
+
+ m_port_op.def.nBufferSize = p_buffer_req->size;
+ m_port_op.def.nBufferCountMin = p_buffer_req->mincount;
+ m_port_op.def.nBufferCountActual = MAX(p_buffer_req->mincount,
+ m_port_op.def.nBufferCountActual);
+ m_port_op.def.nBufferAlignment = p_buffer_req->alignment;
+
+ OMX_SWVDEC_LOG_HIGH("op port: %d bytes x %d, %d-byte aligned",
+ m_port_op.def.nBufferSize,
+ m_port_op.def.nBufferCountActual,
+ m_port_op.def.nBufferAlignment);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid", port_index);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+get_buffer_requirements_swvdec_exit:
+ return retval;
+}
+
+/**
+ * @brief Allocate input buffer, and input buffer info array if ncessary.
+ *
+ * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
+ * structure.
+ * @param[in] p_app_data: Pointer to IL client app data.
+ * @param[in] size: Size of buffer to be allocated in bytes.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip(
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_PTR p_app_data,
+ OMX_U32 size)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ if (size != m_port_ip.def.nBufferSize)
+ {
+ OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
+ "configured size (%d bytes)",
+ size,
+ m_port_ip.def.nBufferSize);
+
+ retval = OMX_ErrorBadParameter;
+ goto buffer_allocate_ip_exit;
+ }
+
+ if (m_buffer_array_ip == NULL)
+ {
+ OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
+ m_port_ip.def.nBufferCountActual,
+ (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
+
+ if ((retval = buffer_allocate_ip_info_array()) != OMX_ErrorNone)
+ {
+ goto buffer_allocate_ip_exit;
+ }
+ }
+
+ for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
+ {
+ if (m_buffer_array_ip[ii].buffer_populated == false)
+ {
+ OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
+ break;
+ }
+ }
+
+ if (ii < m_port_ip.def.nBufferCountActual)
+ {
+ int pmem_fd = -1;
+
+ unsigned char *bufferaddr;
+
+ OMX_SWVDEC_LOG_HIGH("ip buffer %d: %d bytes being allocated",
+ ii,
+ size);
+
+ m_buffer_array_ip[ii].ion_info.ion_fd_device =
+ ion_memory_alloc_map(&m_buffer_array_ip[ii].ion_info.ion_alloc_data,
+ &m_buffer_array_ip[ii].ion_info.ion_fd_data,
+ size,
+ m_port_ip.def.nBufferAlignment);
+
+ if (m_buffer_array_ip[ii].ion_info.ion_fd_device < 0)
+ {
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_ip_exit;
+ }
+
+ pmem_fd = m_buffer_array_ip[ii].ion_info.ion_fd_data.fd;
+
+ bufferaddr = (unsigned char *) mmap(NULL,
+ size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ pmem_fd,
+ 0);
+
+ if (bufferaddr == MAP_FAILED)
+ {
+ OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
+ pmem_fd,
+ size);
+
+ close(pmem_fd);
+ ion_memory_free(&m_buffer_array_ip[ii].ion_info);
+
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_ip_exit;
+ }
+
+ *pp_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
+
+ m_buffer_array_ip[ii].buffer_payload.bufferaddr = bufferaddr;
+ m_buffer_array_ip[ii].buffer_payload.pmem_fd = pmem_fd;
+ m_buffer_array_ip[ii].buffer_payload.buffer_len = size;
+ m_buffer_array_ip[ii].buffer_payload.mmaped_size = size;
+ m_buffer_array_ip[ii].buffer_payload.offset = 0;
+
+ m_buffer_array_ip[ii].buffer_swvdec.p_buffer = bufferaddr;
+ m_buffer_array_ip[ii].buffer_swvdec.size = size;
+ m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
+ (void *) ((unsigned long) ii);
+
+ m_buffer_array_ip[ii].buffer_populated = true;
+
+ OMX_SWVDEC_LOG_HIGH("ip buffer %d: %p, %d bytes",
+ ii,
+ bufferaddr,
+ size);
+
+ (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
+ (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
+ (*pp_buffer_hdr)->nAllocLen = size;
+ (*pp_buffer_hdr)->pAppPrivate = p_app_data;
+ (*pp_buffer_hdr)->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
+ (*pp_buffer_hdr)->pInputPortPrivate =
+ (void *) &(m_buffer_array_ip[ii].buffer_payload);
+
+ m_port_ip.populated = port_ip_populated();
+ m_port_ip.unpopulated = OMX_FALSE;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("all %d ip buffers allocated",
+ m_port_ip.def.nBufferCountActual);
+
+ retval = OMX_ErrorInsufficientResources;
+ }
+
+buffer_allocate_ip_exit:
+ return retval;
+}
+
+/**
+ * @brief Allocate output buffer, and output buffer info array if necessary.
+ *
+ * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
+ * structure.
+ * @param[in] p_app_data: Pointer to IL client app data.
+ * @param[in] size: Size of buffer to be allocated in bytes.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::buffer_allocate_op(
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_PTR p_app_data,
+ OMX_U32 size)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ if (size != m_port_op.def.nBufferSize)
+ {
+ OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
+ "configured size (%d bytes)",
+ size,
+ m_port_op.def.nBufferSize);
+
+ retval = OMX_ErrorBadParameter;
+ goto buffer_allocate_op_exit;
+ }
+
+ if (m_buffer_array_op == NULL)
+ {
+ OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
+ m_port_op.def.nBufferCountActual,
+ (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
+
+ if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
+ {
+ goto buffer_allocate_op_exit;
+ }
+ }
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ if (m_buffer_array_op[ii].buffer_populated == false)
+ {
+ OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
+ break;
+ }
+ }
+
+ if (ii < m_port_op.def.nBufferCountActual)
+ {
+ int pmem_fd = -1;
+
+ unsigned char *bufferaddr;
+
+ OMX_SWVDEC_LOG_HIGH("op buffer %d: %d bytes being allocated",
+ ii,
+ size);
+
+ m_buffer_array_op[ii].ion_info.ion_fd_device =
+ ion_memory_alloc_map(&m_buffer_array_op[ii].ion_info.ion_alloc_data,
+ &m_buffer_array_op[ii].ion_info.ion_fd_data,
+ size,
+ m_port_op.def.nBufferAlignment);
+
+ if (m_buffer_array_op[ii].ion_info.ion_fd_device < 0)
+ {
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_op_exit;
+ }
+
+ pmem_fd = m_buffer_array_op[ii].ion_info.ion_fd_data.fd;
+
+ bufferaddr = (unsigned char *) mmap(NULL,
+ size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ pmem_fd,
+ 0);
+
+ if (bufferaddr == MAP_FAILED)
+ {
+ OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
+ pmem_fd,
+ size);
+
+ close(pmem_fd);
+ ion_memory_free(&m_buffer_array_op[ii].ion_info);
+
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_op_exit;
+ }
+
+ *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
+
+ m_buffer_array_op[ii].buffer_payload.bufferaddr = bufferaddr;
+ m_buffer_array_op[ii].buffer_payload.pmem_fd = pmem_fd;
+ m_buffer_array_op[ii].buffer_payload.buffer_len = size;
+ m_buffer_array_op[ii].buffer_payload.mmaped_size = size;
+ m_buffer_array_op[ii].buffer_payload.offset = 0;
+
+ m_buffer_array_op[ii].buffer_swvdec.p_buffer = bufferaddr;
+ m_buffer_array_op[ii].buffer_swvdec.size = size;
+ m_buffer_array_op[ii].buffer_swvdec.p_client_data =
+ (void *) ((unsigned long) ii);
+
+ m_buffer_array_op[ii].buffer_populated = true;
+
+ OMX_SWVDEC_LOG_HIGH("op buffer %d: %p, %d bytes",
+ ii,
+ bufferaddr,
+ size);
+
+ (*pp_buffer_hdr)->pBuffer = (OMX_U8 *) bufferaddr;
+ (*pp_buffer_hdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ (*pp_buffer_hdr)->nVersion.nVersion = OMX_SPEC_VERSION;
+ (*pp_buffer_hdr)->nAllocLen = size;
+ (*pp_buffer_hdr)->pAppPrivate = p_app_data;
+ (*pp_buffer_hdr)->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
+ (*pp_buffer_hdr)->pOutputPortPrivate =
+ (void *) &(m_buffer_array_op[ii].buffer_payload);
+
+ m_port_op.populated = port_op_populated();
+ m_port_op.unpopulated = OMX_FALSE;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("all %d op buffers allocated",
+ m_port_op.def.nBufferCountActual);
+
+ retval = OMX_ErrorInsufficientResources;
+ }
+
+buffer_allocate_op_exit:
+ return retval;
+}
+
+/**
+ * @brief Allocate input buffer info array.
+ */
+OMX_ERRORTYPE omx_swvdec::buffer_allocate_ip_info_array()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr;
+
+ if (m_buffer_array_ip != NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
+
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_ip_info_array_exit;
+ }
+
+ OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
+ m_port_ip.def.nBufferCountActual,
+ (m_port_ip.def.nBufferCountActual > 1) ? "s" : "");
+
+ m_buffer_array_ip =
+ (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
+ m_port_ip.def.nBufferCountActual);
+
+ if (m_buffer_array_ip == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
+ "%d element%s, %zu bytes requested",
+ m_port_ip.def.nBufferCountActual,
+ (m_port_ip.def.nBufferCountActual > 1) ? "s" : "",
+ sizeof(OMX_SWVDEC_BUFFER_INFO) *
+ m_port_ip.def.nBufferCountActual);
+
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_ip_info_array_exit;
+ }
+
+ for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
+ {
+ p_buffer_hdr = &m_buffer_array_ip[ii].buffer_header;
+
+ // reset file descriptors
+
+ m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
+ m_buffer_array_ip[ii].ion_info.ion_fd_device = -1;
+
+ m_buffer_array_ip[ii].buffer_swvdec.p_client_data =
+ (void *) ((unsigned long) ii);
+
+ p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ p_buffer_hdr->nInputPortIndex = OMX_CORE_PORT_INDEX_IP;
+ p_buffer_hdr->pInputPortPrivate =
+ (void *) &(m_buffer_array_ip[ii].buffer_payload);
+ }
+
+buffer_allocate_ip_info_array_exit:
+ return retval;
+}
+
+/**
+ * @brief Allocate output buffer info array.
+ */
+OMX_ERRORTYPE omx_swvdec::buffer_allocate_op_info_array()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr;
+
+ if (m_buffer_array_op != NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("buffer info array already allocated");
+
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_op_info_array_exit;
+ }
+
+ OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
+ m_port_op.def.nBufferCountActual,
+ (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
+
+ m_buffer_array_op =
+ (OMX_SWVDEC_BUFFER_INFO *) calloc(sizeof(OMX_SWVDEC_BUFFER_INFO),
+ m_port_op.def.nBufferCountActual);
+
+ if (m_buffer_array_op == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to allocate buffer info array; "
+ "%d element%s, %zu bytes requested",
+ m_port_op.def.nBufferCountActual,
+ (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
+ sizeof(OMX_SWVDEC_BUFFER_INFO) *
+ m_port_op.def.nBufferCountActual);
+
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_allocate_op_info_array_exit;
+ }
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ p_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
+
+ // reset file descriptors
+
+ m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
+ m_buffer_array_op[ii].ion_info.ion_fd_device = -1;
+
+ m_buffer_array_op[ii].buffer_swvdec.p_client_data =
+ (void *) ((unsigned long) ii);
+
+ p_buffer_hdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ p_buffer_hdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ p_buffer_hdr->nOutputPortIndex = OMX_CORE_PORT_INDEX_OP;
+ p_buffer_hdr->pOutputPortPrivate =
+ (void *) &(m_buffer_array_op[ii].buffer_payload);
+ }
+
+buffer_allocate_op_info_array_exit:
+ return retval;
+}
+
+/**
+ * @brief Use buffer allocated by IL client; allocate output buffer info array
+ * if necessary.
+ *
+ * @param[in,out] pp_buffer_hdr: Pointer to pointer to buffer header type
+ * structure.
+ * @param[in] p_app_data: Pointer to IL client app data.
+ * @param[in] size: Size of buffer to be allocated in bytes.
+ * @param[in] p_buffer: Pointer to buffer to be used.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::buffer_use_op(
+ OMX_BUFFERHEADERTYPE **pp_buffer_hdr,
+ OMX_PTR p_app_data,
+ OMX_U32 size,
+ OMX_U8 *p_buffer)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ (void) size;
+
+ if (m_buffer_array_op == NULL)
+ {
+ OMX_SWVDEC_LOG_HIGH("allocating buffer info array, %d element%s",
+ m_port_op.def.nBufferCountActual,
+ (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
+
+ if ((retval = buffer_allocate_op_info_array()) != OMX_ErrorNone)
+ {
+ goto buffer_use_op_exit;
+ }
+ }
+
+ if (m_meta_buffer_mode && (m_meta_buffer_array == NULL))
+ {
+ OMX_SWVDEC_LOG_HIGH("allocating meta buffer info array, %d element%s",
+ m_port_op.def.nBufferCountActual,
+ (m_port_op.def.nBufferCountActual > 1) ? "s" : "");
+
+ if ((retval = meta_buffer_array_allocate()) != OMX_ErrorNone)
+ {
+ goto buffer_use_op_exit;
+ }
+ }
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ if (m_buffer_array_op[ii].buffer_populated == false)
+ {
+ OMX_SWVDEC_LOG_LOW("buffer %d not populated", ii);
+ break;
+ }
+ }
+
+ if (ii < m_port_op.def.nBufferCountActual)
+ {
+ struct vdec_bufferpayload *p_buffer_payload;
+
+ SWVDEC_BUFFER *p_buffer_swvdec;
+
+ *pp_buffer_hdr = &m_buffer_array_op[ii].buffer_header;
+ p_buffer_payload = &m_buffer_array_op[ii].buffer_payload;
+ p_buffer_swvdec = &m_buffer_array_op[ii].buffer_swvdec;
+
+ if (m_meta_buffer_mode)
+ {
+ p_buffer_swvdec->size = m_port_op.def.nBufferSize;
+ p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
+
+ m_buffer_array_op[ii].buffer_populated = true;
+
+ (*pp_buffer_hdr)->pBuffer = p_buffer;
+ (*pp_buffer_hdr)->pAppPrivate = p_app_data;
+ (*pp_buffer_hdr)->nAllocLen =
+ sizeof(struct VideoDecoderOutputMetaData);
+
+ OMX_SWVDEC_LOG_HIGH("op buffer %d: %p (meta buffer)",
+ ii,
+ *pp_buffer_hdr);
+
+ m_port_op.populated = port_op_populated();
+ m_port_op.unpopulated = OMX_FALSE;
+ }
+ else if (m_android_native_buffers)
+ {
+ private_handle_t *p_handle;
+
+ OMX_U8 *p_buffer_mapped;
+
+ p_handle = (private_handle_t *) p_buffer;
+
+ if (((OMX_U32) p_handle->size) < m_port_op.def.nBufferSize)
+ {
+ OMX_SWVDEC_LOG_ERROR("requested size (%d bytes) not equal to "
+ "configured size (%d bytes)",
+ p_handle->size,
+ m_port_op.def.nBufferSize);
+
+ retval = OMX_ErrorBadParameter;
+ goto buffer_use_op_exit;
+ }
+
+ m_port_op.def.nBufferSize = p_handle->size;
+
+ p_buffer_mapped = (OMX_U8 *) mmap(NULL,
+ p_handle->size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ p_handle->fd,
+ 0);
+
+ if (p_buffer_mapped == MAP_FAILED)
+ {
+ OMX_SWVDEC_LOG_ERROR("mmap() failed for fd %d of size %d",
+ p_handle->fd,
+ p_handle->size);
+
+ retval = OMX_ErrorInsufficientResources;
+ goto buffer_use_op_exit;
+ }
+
+ p_buffer_payload->bufferaddr = p_buffer_mapped;
+ p_buffer_payload->pmem_fd = p_handle->fd;
+ p_buffer_payload->buffer_len = p_handle->size;
+ p_buffer_payload->mmaped_size = p_handle->size;
+ p_buffer_payload->offset = 0;
+
+ p_buffer_swvdec->p_buffer = p_buffer_mapped;
+ p_buffer_swvdec->size = m_port_op.def.nBufferSize;
+ p_buffer_swvdec->p_client_data = (void *) ((unsigned long) ii);
+
+ m_buffer_array_op[ii].buffer_populated = true;
+
+ (*pp_buffer_hdr)->pBuffer = (m_android_native_buffers ?
+ ((OMX_U8 *) p_handle) :
+ p_buffer_mapped);
+ (*pp_buffer_hdr)->pAppPrivate = p_app_data;
+ (*pp_buffer_hdr)->nAllocLen = m_port_op.def.nBufferSize;
+
+ m_buffer_array_op[ii].ion_info.ion_fd_data.fd = p_handle->fd;
+
+ OMX_SWVDEC_LOG_HIGH("op buffer %d: %p",
+ ii,
+ *pp_buffer_hdr);
+
+ m_port_op.populated = port_op_populated();
+ m_port_op.unpopulated = OMX_FALSE;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("neither 'meta buffer mode' nor "
+ "'android native buffers' enabled");
+
+ retval = OMX_ErrorBadParameter;
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("all %d op buffers populated",
+ m_port_op.def.nBufferCountActual);
+
+ retval = OMX_ErrorInsufficientResources;
+ }
+
+buffer_use_op_exit:
+ return retval;
+}
+
+/**
+ * @brief De-allocate input buffer.
+ *
+ * @param[in] p_buffer_hdr: Pointer to buffer header structure.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::buffer_deallocate_ip(
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ if (p_buffer_hdr == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ goto buffer_deallocate_ip_exit;
+ }
+ else if (m_buffer_array_ip == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("ip buffer array not allocated");
+
+ retval = OMX_ErrorBadParameter;
+ goto buffer_deallocate_ip_exit;
+ }
+
+ for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
+ {
+ if (p_buffer_hdr == &(m_buffer_array_ip[ii].buffer_header))
+ {
+ OMX_SWVDEC_LOG_LOW("%p has index %d",
+ p_buffer_hdr->pBuffer,
+ ii);
+ break;
+ }
+ }
+
+ if (ii < m_port_ip.def.nBufferCountActual)
+ {
+ if (m_buffer_array_ip[ii].buffer_payload.pmem_fd > 0)
+ {
+ m_buffer_array_ip[ii].buffer_populated = false;
+
+ m_port_ip.populated = OMX_FALSE;
+
+ munmap(m_buffer_array_ip[ii].buffer_payload.bufferaddr,
+ m_buffer_array_ip[ii].buffer_payload.mmaped_size);
+
+ close(m_buffer_array_ip[ii].buffer_payload.pmem_fd);
+ m_buffer_array_ip[ii].buffer_payload.pmem_fd = -1;
+
+ ion_memory_free(&m_buffer_array_ip[ii].ion_info);
+
+ for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
+ {
+ if (m_buffer_array_ip[ii].buffer_populated)
+ {
+ break;
+ }
+ }
+
+ if (ii == m_port_ip.def.nBufferCountActual)
+ {
+ buffer_deallocate_ip_info_array();
+
+ m_port_ip.unpopulated = OMX_TRUE;
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("%p: pmem_fd %d",
+ p_buffer_hdr->pBuffer,
+ m_buffer_array_ip[ii].buffer_payload.pmem_fd);
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
+
+ retval = OMX_ErrorBadParameter;
+ }
+
+buffer_deallocate_ip_exit:
+ return retval;
+}
+
+/**
+ * @brief De-allocate output buffer.
+ *
+ * @param[in] p_buffer_hdr: Pointer to buffer header structure.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::buffer_deallocate_op(
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ unsigned int ii;
+
+ if (p_buffer_hdr == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_buffer_hdr = NULL");
+
+ retval = OMX_ErrorBadParameter;
+ goto buffer_deallocate_op_exit;
+ }
+ else if (m_buffer_array_op == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("op buffer array not allocated");
+
+ retval = OMX_ErrorBadParameter;
+ goto buffer_deallocate_op_exit;
+ }
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ if (p_buffer_hdr == &(m_buffer_array_op[ii].buffer_header))
+ {
+ OMX_SWVDEC_LOG_LOW("%p has index %d",
+ p_buffer_hdr->pBuffer,
+ ii);
+ break;
+ }
+ }
+
+ if (ii < m_port_op.def.nBufferCountActual)
+ {
+ if (m_meta_buffer_mode)
+ {
+ // do nothing; munmap() & FD reset done in FBD or RR
+ }
+ else if (m_android_native_buffers)
+ {
+ munmap(m_buffer_array_op[ii].buffer_payload.bufferaddr,
+ m_buffer_array_op[ii].buffer_payload.mmaped_size);
+
+ m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
+ }
+ else
+ {
+ munmap(m_buffer_array_op[ii].buffer_payload.bufferaddr,
+ m_buffer_array_op[ii].buffer_payload.mmaped_size);
+
+ close(m_buffer_array_op[ii].buffer_payload.pmem_fd);
+
+ m_buffer_array_op[ii].buffer_payload.pmem_fd = -1;
+
+ ion_memory_free(&m_buffer_array_op[ii].ion_info);
+ }
+
+ m_buffer_array_op[ii].buffer_populated = false;
+
+ m_port_op.populated = OMX_FALSE;
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ if (m_buffer_array_op[ii].buffer_populated)
+ {
+ break;
+ }
+ }
+
+ if (ii == m_port_op.def.nBufferCountActual)
+ {
+ buffer_deallocate_op_info_array();
+
+ m_port_op.unpopulated = OMX_TRUE;
+
+ if (m_meta_buffer_mode)
+ {
+ meta_buffer_array_deallocate();
+ }
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("%p not found", p_buffer_hdr->pBuffer);
+
+ retval = OMX_ErrorBadParameter;
+ }
+
+buffer_deallocate_op_exit:
+ return retval;
+}
+
+/**
+ * @brief De-allocate input buffer info array.
+ */
+void omx_swvdec::buffer_deallocate_ip_info_array()
+{
+ assert(m_buffer_array_ip != NULL);
+
+ free(m_buffer_array_ip);
+
+ m_buffer_array_ip = NULL;
+}
+
+/**
+ * @brief De-allocate output buffer info array.
+ */
+void omx_swvdec::buffer_deallocate_op_info_array()
+{
+ assert(m_buffer_array_op != NULL);
+
+ free(m_buffer_array_op);
+
+ m_buffer_array_op = NULL;
+}
+
+/**
+ * @brief Allocate meta buffer info array.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::meta_buffer_array_allocate()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ m_meta_buffer_array = ((OMX_SWVDEC_META_BUFFER_INFO *)
+ calloc(sizeof(OMX_SWVDEC_META_BUFFER_INFO),
+ m_port_op.def.nBufferCountActual));
+
+ if (m_meta_buffer_array == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to allocate meta_buffer info array; "
+ "%d element%s, %zu bytes requested",
+ m_port_op.def.nBufferCountActual,
+ (m_port_op.def.nBufferCountActual > 1) ? "s" : "",
+ sizeof(OMX_SWVDEC_META_BUFFER_INFO) *
+ m_port_op.def.nBufferCountActual);
+
+ retval = OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ unsigned int ii;
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ m_meta_buffer_array[ii].fd = -1;
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief De-allocate meta buffer info array.
+ */
+void omx_swvdec::meta_buffer_array_deallocate()
+{
+ assert(m_meta_buffer_array != NULL);
+
+ free(m_meta_buffer_array);
+
+ m_meta_buffer_array = NULL;
+}
+
+/**
+ * @brief Add meta buffer reference.
+ *
+ * @param[in] index: Buffer index.
+ * @param[in] fd: File descriptor.
+ */
+void omx_swvdec::meta_buffer_ref_add(unsigned int index, int fd)
+{
+ if (m_meta_buffer_array[index].ref_count == 0)
+ {
+ m_meta_buffer_array[index].fd = fd;
+ }
+
+ m_meta_buffer_array[index].ref_count++;
+}
+
+/**
+ * @brief Remove meta buffer reference.
+ *
+ * @param[in] index: Buffer index.
+ */
+void omx_swvdec::meta_buffer_ref_remove(unsigned int index)
+{
+ pthread_mutex_lock(&m_meta_buffer_array_mutex);
+
+ m_meta_buffer_array[index].ref_count--;
+
+ if (m_meta_buffer_array[index].ref_count == 0)
+ {
+ m_meta_buffer_array[index].fd = -1;
+
+ munmap(m_buffer_array_op[index].buffer_payload.bufferaddr,
+ m_buffer_array_op[index].buffer_payload.mmaped_size);
+
+ m_buffer_array_op[index].buffer_payload.bufferaddr = NULL;
+ m_buffer_array_op[index].buffer_payload.offset = 0;
+ m_buffer_array_op[index].buffer_payload.mmaped_size = 0;
+
+ m_buffer_array_op[index].buffer_swvdec.p_buffer = NULL;
+ m_buffer_array_op[index].buffer_swvdec.size = 0;
+ }
+
+ pthread_mutex_unlock(&m_meta_buffer_array_mutex);
+}
+
+/**
+ * @brief Split MPEG-4 bitstream buffer into multiple frames (if they exist).
+ *
+ * @param[in,out] offset_array: Array of offsets to frame headers.
+ * @param[in] p_buffer_hdr: Pointer to buffer header.
+ *
+ * @retval Number of frames in buffer.
+ */
+unsigned int split_buffer_mpeg4(unsigned int *offset_array,
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr)
+{
+ unsigned char *p_buffer = p_buffer_hdr->pBuffer;
+
+ unsigned int byte_count = 0;
+
+ unsigned int num_frame_headers = 0;
+
+ unsigned int next_4bytes;
+
+ while ((byte_count < p_buffer_hdr->nFilledLen) &&
+ (num_frame_headers < OMX_SWVDEC_MAX_FRAMES_PER_ETB))
+ {
+ next_4bytes = *((unsigned int *) p_buffer);
+
+ next_4bytes = __builtin_bswap32(next_4bytes);
+
+ if (next_4bytes == 0x000001B6)
+ {
+ OMX_SWVDEC_LOG_HIGH("%p, buffer %p: "
+ "frame header at %d bytes offset",
+ p_buffer_hdr,
+ p_buffer_hdr->pBuffer,
+ byte_count);
+
+ offset_array[num_frame_headers] = byte_count;
+
+ num_frame_headers++;
+
+ p_buffer += 4;
+ byte_count += 4;
+ }
+ else
+ {
+ p_buffer++;
+ byte_count++;
+ }
+ }
+
+ return num_frame_headers;
+}
+
+/**
+ * @brief Check if ip port is populated, i.e., if all ip buffers are populated.
+ *
+ * @retval true
+ * @retval false
+ */
+OMX_BOOL omx_swvdec::port_ip_populated()
+{
+ OMX_BOOL retval = OMX_FALSE;
+
+ if (m_buffer_array_ip != NULL)
+ {
+ unsigned int ii;
+
+ for (ii = 0; ii < m_port_ip.def.nBufferCountActual; ii++)
+ {
+ if (m_buffer_array_ip[ii].buffer_populated == false)
+ {
+ break;
+ }
+ }
+
+ if (ii == m_port_ip.def.nBufferCountActual)
+ {
+ retval = OMX_TRUE;
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Check if op port is populated, i.e., if all op buffers are populated.
+ *
+ * @retval true
+ * @retval false
+ */
+OMX_BOOL omx_swvdec::port_op_populated()
+{
+ OMX_BOOL retval = OMX_FALSE;
+
+ if (m_buffer_array_op != NULL)
+ {
+ unsigned int ii;
+
+ for (ii = 0; ii < m_port_op.def.nBufferCountActual; ii++)
+ {
+ if (m_buffer_array_op[ii].buffer_populated == false)
+ {
+ break;
+ }
+ }
+
+ if (ii == m_port_op.def.nBufferCountActual)
+ {
+ retval = OMX_TRUE;
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Flush input, output, or both input & output ports.
+ *
+ * @param[in] port_index: Index of port to flush.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::flush(unsigned int port_index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (((port_index == OMX_CORE_PORT_INDEX_IP) &&
+ m_port_ip.flush_inprogress) ||
+ ((port_index == OMX_CORE_PORT_INDEX_OP) &&
+ m_port_op.flush_inprogress) ||
+ ((port_index == OMX_ALL) &&
+ m_port_ip.flush_inprogress &&
+ m_port_op.flush_inprogress))
+ {
+ OMX_SWVDEC_LOG_HIGH("flush port index %d already in progress",
+ port_index);
+ }
+ else
+ {
+ SWVDEC_FLUSH_TYPE swvdec_flush_type;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ if (port_index == OMX_CORE_PORT_INDEX_IP)
+ {
+ m_port_ip.flush_inprogress = OMX_TRUE;
+
+ // no separate SwVdec flush type for input
+ }
+ else if (port_index == OMX_CORE_PORT_INDEX_OP)
+ {
+ m_port_op.flush_inprogress = OMX_TRUE;
+
+ swvdec_flush_type = (m_port_ip.flush_inprogress ?
+ SWVDEC_FLUSH_TYPE_ALL :
+ SWVDEC_FLUSH_TYPE_OP);
+
+ if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
+ swvdec_flush_type)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+ else if (port_index == OMX_ALL)
+ {
+ m_port_ip.flush_inprogress = OMX_TRUE;
+ m_port_op.flush_inprogress = OMX_TRUE;
+
+ swvdec_flush_type = SWVDEC_FLUSH_TYPE_ALL;
+
+ if ((retval_swvdec = swvdec_flush(m_swvdec_handle,
+ swvdec_flush_type)) !=
+ SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+ else
+ {
+ assert(0);
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Allocate & map ION memory.
+ */
+int omx_swvdec::ion_memory_alloc_map(struct ion_allocation_data *p_alloc_data,
+ struct ion_fd_data *p_fd_data,
+ OMX_U32 size,
+ OMX_U32 alignment)
+{
+ int fd = -EINVAL;
+ int rc = -EINVAL;
+
+ if ((p_alloc_data == NULL) || (p_fd_data == NULL) || (size == 0))
+ {
+ OMX_SWVDEC_LOG_ERROR("invalid arguments");
+ goto ion_memory_alloc_map_exit;
+ }
+
+ if ((fd = open("/dev/ion", O_RDONLY)) < 0)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to open ion device; fd = %d", fd);
+ goto ion_memory_alloc_map_exit;
+ }
+
+ p_alloc_data->len = size;
+ p_alloc_data->align = (alignment < 4096) ? 4096 : alignment;
+ p_alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
+ p_alloc_data->flags = 0;
+
+ OMX_SWVDEC_LOG_LOW("heap_id_mask 0x%08x, len %zu, align %zu",
+ p_alloc_data->heap_id_mask,
+ p_alloc_data->len,
+ p_alloc_data->align);
+
+ rc = ioctl(fd, ION_IOC_ALLOC, p_alloc_data);
+
+ if (rc || (p_alloc_data->handle == 0))
+ {
+ OMX_SWVDEC_LOG_ERROR("ioctl() for allocation failed");
+
+ close(fd);
+ fd = -ENOMEM;
+
+ goto ion_memory_alloc_map_exit;
+ }
+
+ p_fd_data->handle = p_alloc_data->handle;
+
+ if (ioctl(fd, ION_IOC_MAP, p_fd_data))
+ {
+ struct vdec_ion ion_buf_info;
+
+ OMX_SWVDEC_LOG_ERROR("ioctl() for mapping failed");
+
+ ion_buf_info.ion_alloc_data = *p_alloc_data;
+ ion_buf_info.ion_fd_device = fd;
+ ion_buf_info.ion_fd_data = *p_fd_data;
+
+ ion_memory_free(&ion_buf_info);
+
+ p_fd_data->fd = -1;
+
+ close(fd);
+ fd = -ENOMEM;
+
+ goto ion_memory_alloc_map_exit;
+ }
+
+ion_memory_alloc_map_exit:
+ return fd;
+}
+
+/**
+ * @brief Free ION memory.
+ */
+void omx_swvdec::ion_memory_free(struct vdec_ion *p_ion_buf_info)
+{
+ if (p_ion_buf_info == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_ion_buf_info = NULL");
+ goto ion_memory_free_exit;
+ }
+
+ if (ioctl(p_ion_buf_info->ion_fd_device,
+ ION_IOC_FREE,
+ &p_ion_buf_info->ion_alloc_data.handle))
+ {
+ OMX_SWVDEC_LOG_ERROR("ioctl() for freeing failed");
+ }
+
+ close(p_ion_buf_info->ion_fd_device);
+
+ p_ion_buf_info->ion_fd_device = -1;
+ p_ion_buf_info->ion_alloc_data.handle = 0;
+ p_ion_buf_info->ion_fd_data.fd = -1;
+
+ion_memory_free_exit:
+ return;
+}
+
+/**
+ * @brief Flush cached ION output buffer.
+ *
+ * @param[in] index: Index of buffer in output buffer info array.
+ */
+void omx_swvdec::ion_flush_op(unsigned int index)
+{
+ if (index < m_port_op.def.nBufferCountActual)
+ {
+ struct vdec_bufferpayload *p_buffer_payload =
+ &m_buffer_array_op[index].buffer_payload;
+
+ if(p_buffer_payload)
+ {
+ if(p_buffer_payload->bufferaddr != NULL)
+ {
+ __builtin___clear_cache(reinterpret_cast<char*>((size_t*)p_buffer_payload->bufferaddr),
+ reinterpret_cast<char*>((size_t*)p_buffer_payload->bufferaddr +p_buffer_payload->buffer_len));
+ }
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
+ }
+
+ return;
+}
+
+/**
+ * ----------------------------
+ * component callback functions
+ * ----------------------------
+ */
+
+/**
+ * @brief Empty buffer done callback.
+ *
+ * @param[in] p_buffer_ip: Pointer to input buffer structure.
+ */
+void omx_swvdec::swvdec_empty_buffer_done(SWVDEC_BUFFER *p_buffer_ip)
+{
+ unsigned long index = (unsigned long) p_buffer_ip->p_client_data;
+
+ m_buffer_array_ip[index].buffer_header.nFilledLen =
+ p_buffer_ip->filled_length;
+
+ async_post_event(OMX_SWVDEC_EVENT_EBD,
+ (unsigned long) &m_buffer_array_ip[index].buffer_header,
+ index);
+}
+
+/**
+ * @brief Fill buffer done callback.
+ *
+ * @param[in] p_buffer_op: Pointer to output buffer structure.
+ */
+void omx_swvdec::swvdec_fill_buffer_done(SWVDEC_BUFFER *p_buffer_op)
+{
+ unsigned long index = (unsigned long) p_buffer_op->p_client_data;
+
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr;
+
+ if (index < ((unsigned long) m_port_op.def.nBufferCountActual))
+ {
+ p_buffer_hdr = &m_buffer_array_op[index].buffer_header;
+
+ p_buffer_hdr->nFlags = p_buffer_op->flags;
+ p_buffer_hdr->nTimeStamp = p_buffer_op->timestamp;
+ p_buffer_hdr->nFilledLen = ((m_meta_buffer_mode &&
+ p_buffer_op->filled_length) ?
+ p_buffer_hdr->nAllocLen :
+ p_buffer_op->filled_length);
+ }
+
+ async_post_event(OMX_SWVDEC_EVENT_FBD,
+ (unsigned long) &m_buffer_array_op[index].buffer_header,
+ index);
+}
+
+/**
+ * @brief Event handler callback.
+ *
+ * @param[in] event: Event.
+ * @param[in] p_data: Pointer to event-specific data.
+ */
+void omx_swvdec::swvdec_event_handler(SWVDEC_EVENT event, void *p_data)
+{
+ switch (event)
+ {
+
+ case SWVDEC_EVENT_FLUSH_ALL_DONE:
+ {
+ async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_IP, 0, 0);
+ async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
+
+ break;
+ }
+
+ case SWVDEC_EVENT_FLUSH_OP_DONE:
+ {
+ async_post_event(OMX_SWVDEC_EVENT_FLUSH_PORT_OP, 0, 0);
+
+ break;
+ }
+
+ case SWVDEC_EVENT_RELEASE_REFERENCE:
+ {
+ SWVDEC_BUFFER *p_buffer_op = (SWVDEC_BUFFER *) p_data;
+
+ unsigned long index = (unsigned long) p_buffer_op->p_client_data;
+
+ OMX_SWVDEC_LOG_LOW("release reference: %p", p_buffer_op->p_buffer);
+
+ assert(index < ((unsigned long) m_port_op.def.nBufferCountActual));
+
+ if (m_meta_buffer_mode)
+ {
+ meta_buffer_ref_remove(index);
+ }
+
+ break;
+ }
+
+ case SWVDEC_EVENT_RECONFIG_REQUIRED:
+ {
+ async_post_event(OMX_SWVDEC_EVENT_PORT_RECONFIG, 0, 0);
+
+ break;
+ }
+
+ case SWVDEC_EVENT_DIMENSIONS_UPDATED:
+ {
+ async_post_event(OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED, 0, 0);
+
+ break;
+ }
+
+ case SWVDEC_EVENT_FATAL_ERROR:
+ default:
+ {
+ async_post_event(OMX_SWVDEC_EVENT_ERROR, OMX_ErrorHardware, 0);
+
+ break;
+ }
+
+ }
+}
+
+/**
+ * @brief Translate SwVdec status return value to OMX error type return value.
+ *
+ * @param[in] retval_swvdec: SwVdec status return value.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::retval_swvdec2omx(SWVDEC_STATUS retval_swvdec)
+{
+ OMX_ERRORTYPE retval_omx;
+
+ switch (retval_swvdec)
+ {
+
+ SWVDEC_STATUS_SUCCESS:
+ retval_omx = OMX_ErrorNone;
+ break;
+
+ SWVDEC_STATUS_FAILURE:
+ retval_omx = OMX_ErrorUndefined;
+ break;
+
+ SWVDEC_STATUS_NULL_POINTER:
+ SWVDEC_STATUS_INVALID_PARAMETERS:
+ retval_omx = OMX_ErrorBadParameter;
+ break;
+
+ SWVDEC_STATUS_INVALID_STATE:
+ retval_omx = OMX_ErrorInvalidState;
+ break;
+
+ SWVDEC_STATUS_INSUFFICIENT_RESOURCES:
+ retval_omx = OMX_ErrorInsufficientResources;
+ break;
+
+ SWVDEC_STATUS_UNSUPPORTED:
+ retval_omx = OMX_ErrorUnsupportedSetting;
+ break;
+
+ SWVDEC_STATUS_NOT_IMPLEMENTED:
+ retval_omx = OMX_ErrorNotImplemented;
+ break;
+
+ default:
+ retval_omx = OMX_ErrorUndefined;
+ break;
+
+ }
+
+ return retval_omx;
+}
+
+/**
+ * @brief Create asynchronous thread.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_thread_create()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ pthread_attr_t thread_attributes;
+
+ if (sem_init(&m_async_thread.sem_thread_created, 0, 0))
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to create async thread created semaphore");
+
+ retval = OMX_ErrorInsufficientResources;
+ }
+ else if (sem_init(&m_async_thread.sem_event, 0, 0))
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to create async thread event semaphore");
+
+ retval = OMX_ErrorInsufficientResources;
+ }
+ else if (pthread_attr_init(&thread_attributes))
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to create thread attributes object");
+
+ retval = OMX_ErrorInsufficientResources;
+ }
+ else if (pthread_attr_setdetachstate(&thread_attributes,
+ PTHREAD_CREATE_JOINABLE))
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to set detach state attribute");
+
+ retval = OMX_ErrorInsufficientResources;
+
+ pthread_attr_destroy(&thread_attributes);
+ }
+ else
+ {
+ m_async_thread.created = false;
+ m_async_thread.exit = false;
+
+ if (pthread_create(&m_async_thread.handle,
+ &thread_attributes,
+ (void *(*)(void *)) async_thread,
+ this))
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to create async thread");
+
+ retval = OMX_ErrorInsufficientResources;
+
+ pthread_attr_destroy(&thread_attributes);
+ }
+ else
+ {
+ if (pthread_setname_np(m_async_thread.handle, "swvdec_async"))
+ {
+ // don't return error
+ OMX_SWVDEC_LOG_ERROR("failed to set async thread name");
+ }
+
+ sem_wait(&m_async_thread.sem_thread_created);
+
+ m_async_thread.created = true;
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Destroy asynchronous thread.
+ */
+void omx_swvdec::async_thread_destroy()
+{
+ if (m_async_thread.created)
+ {
+ m_async_thread.exit = true;
+
+ sem_post(&m_async_thread.sem_event);
+
+ pthread_join(m_async_thread.handle, NULL);
+
+ m_async_thread.created = false;
+ }
+
+ m_async_thread.exit = false;
+
+ sem_destroy(&m_async_thread.sem_event);
+ sem_destroy(&m_async_thread.sem_thread_created);
+}
+
+/**
+ * @brief Post event to appropriate queue.
+ *
+ * @param[in] event_id: Event ID.
+ * @param[in] event_param1: Event parameter 1.
+ * @param[in] event_param2: Event parameter 2.
+ */
+void omx_swvdec::async_post_event(unsigned long event_id,
+ unsigned long event_param1,
+ unsigned long event_param2)
+{
+ OMX_SWVDEC_EVENT_INFO event_info;
+
+ event_info.event_id = event_id;
+ event_info.event_param1 = event_param1;
+ event_info.event_param2 = event_param2;
+
+ switch (event_id)
+ {
+
+ case OMX_SWVDEC_EVENT_ETB:
+ case OMX_SWVDEC_EVENT_EBD:
+ {
+ m_queue_port_ip.push(&event_info);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_FTB:
+ case OMX_SWVDEC_EVENT_FBD:
+ {
+ m_queue_port_op.push(&event_info);
+ break;
+ }
+
+ default:
+ {
+ m_queue_command.push(&event_info);
+ break;
+ }
+
+ }
+
+ sem_post(&m_async_thread.sem_event);
+}
+
+/**
+ * @brief Asynchronous thread.
+ *
+ * @param[in] p_cmp: Pointer to OMX SwVdec component class.
+ */
+void omx_swvdec::async_thread(void *p_cmp)
+{
+ if (p_cmp == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
+ }
+ else
+ {
+ omx_swvdec *p_omx_swvdec = (omx_swvdec *) p_cmp;
+
+ ASYNC_THREAD *p_async_thread = &p_omx_swvdec->m_async_thread;
+
+ OMX_SWVDEC_LOG_HIGH("created");
+
+ sem_post(&p_async_thread->sem_thread_created);
+
+ while (p_async_thread->exit == false)
+ {
+ sem_wait(&p_async_thread->sem_event);
+
+ if (p_async_thread->exit == true)
+ {
+ break;
+ }
+
+ p_omx_swvdec->async_process_event(p_cmp);
+ }
+ }
+
+ OMX_SWVDEC_LOG_HIGH("exiting");
+}
+
+/**
+ * @brief Process event.
+ *
+ * @param[in] p_cmp: Pointer to OMX SwVdec component class.
+ */
+void omx_swvdec::async_process_event(void *p_cmp)
+{
+ omx_swvdec *p_omx_swvdec;
+
+ OMX_SWVDEC_EVENT_INFO event_info;
+
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (p_cmp == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("p_cmp = NULL");
+
+ goto async_process_event_exit;
+ }
+
+ p_omx_swvdec = (omx_swvdec *) p_cmp;
+
+ // NOTE: queues popped in order of priority; do not change!
+
+ if ((p_omx_swvdec->m_queue_command.pop(&event_info) == false) &&
+ (p_omx_swvdec->m_queue_port_op.pop(&event_info) == false) &&
+ (p_omx_swvdec->m_queue_port_ip.pop(&event_info) == false))
+ {
+ OMX_SWVDEC_LOG_LOW("no event popped");
+
+ goto async_process_event_exit;
+ }
+
+ switch (event_info.event_id)
+ {
+
+ case OMX_SWVDEC_EVENT_CMD:
+ {
+ OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
+ OMX_U32 param = (OMX_U32) event_info.event_param2;
+
+ retval = p_omx_swvdec->async_process_event_cmd(cmd, param);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_CMD_ACK:
+ {
+ OMX_COMMANDTYPE cmd = (OMX_COMMANDTYPE) event_info.event_param1;
+ OMX_U32 param = (OMX_U32) event_info.event_param2;
+
+ retval = p_omx_swvdec->async_process_event_cmd_ack(cmd, param);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_ERROR:
+ {
+ OMX_ERRORTYPE error_code = (OMX_ERRORTYPE) event_info.event_param1;
+
+ retval = p_omx_swvdec->async_process_event_error(error_code);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_ETB:
+ {
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr =
+ (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ unsigned int index = event_info.event_param2;
+
+ retval = p_omx_swvdec->async_process_event_etb(p_buffer_hdr, index);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_FTB:
+ {
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr =
+ (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ unsigned int index = event_info.event_param2;
+
+ retval = p_omx_swvdec->async_process_event_ftb(p_buffer_hdr, index);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_EBD:
+ {
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr =
+ (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ unsigned int index = event_info.event_param2;
+
+ retval = p_omx_swvdec->async_process_event_ebd(p_buffer_hdr, index);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_FBD:
+ {
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr =
+ (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ unsigned int index = event_info.event_param2;
+
+ retval = p_omx_swvdec->async_process_event_fbd(p_buffer_hdr, index);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_EOS:
+ {
+ retval = p_omx_swvdec->async_process_event_eos();
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_FLUSH_PORT_IP:
+ {
+ retval = p_omx_swvdec->async_process_event_flush_port_ip();
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_FLUSH_PORT_OP:
+ {
+ retval = p_omx_swvdec->async_process_event_flush_port_op();
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_PORT_RECONFIG:
+ {
+ retval = p_omx_swvdec->async_process_event_port_reconfig();
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_DIMENSIONS_UPDATED:
+ {
+ retval = p_omx_swvdec->async_process_event_dimensions_updated();
+ break;
+ }
+
+ default:
+ {
+ assert(0);
+
+ retval = OMX_ErrorUndefined;
+ break;
+ }
+
+ }
+
+ if (retval != OMX_ErrorNone)
+ {
+ p_omx_swvdec->async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
+ }
+
+async_process_event_exit:
+ return;
+}
+
+/**
+ * @brief Process command event.
+ *
+ * @param[in] cmd: Command.
+ * @param[in] param: Command parameter.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_cmd(OMX_COMMANDTYPE cmd,
+ OMX_U32 param)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ bool cmd_ack = false;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ switch (cmd)
+ {
+
+ case OMX_CommandStateSet:
+ {
+ retval = async_process_event_cmd_state_set(&cmd_ack,
+ (OMX_STATETYPE) param);
+ break;
+ }
+
+ case OMX_CommandFlush:
+ {
+ retval = async_process_event_cmd_flush((unsigned int) param);
+ break;
+ }
+
+ case OMX_CommandPortDisable:
+ {
+ retval = async_process_event_cmd_port_disable(&cmd_ack,
+ (unsigned int) param);
+ break;
+ }
+
+ case OMX_CommandPortEnable:
+ {
+ retval = async_process_event_cmd_port_enable(&cmd_ack,
+ (unsigned int) param);
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch (cmd)
+
+ if (retval != OMX_ErrorNone)
+ {
+ async_post_event(OMX_SWVDEC_EVENT_ERROR, retval, 0);
+ }
+ else if (cmd_ack)
+ {
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK, cmd, param);
+ }
+
+ sem_post(&m_sem_cmd);
+
+ return retval;
+}
+
+/**
+ * @brief Process command acknowledgement event.
+ *
+ * @param[in] cmd: Command.
+ * @param[in] param: Command parameter.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_ack(OMX_COMMANDTYPE cmd,
+ OMX_U32 param)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ switch (cmd)
+ {
+
+ case OMX_CommandStateSet:
+ {
+ OMX_SWVDEC_LOG_HIGH("%s -> %s",
+ OMX_STATETYPE_STRING(m_state),
+ OMX_STATETYPE_STRING((OMX_STATETYPE) param));
+
+ m_state = (OMX_STATETYPE) param;
+
+ OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
+ "OMX_CommandStateSet, %s",
+ OMX_STATETYPE_STRING(m_state));
+
+ m_callback.EventHandler(&m_cmp,
+ m_app_data,
+ OMX_EventCmdComplete,
+ OMX_CommandStateSet,
+ (OMX_U32) m_state,
+ NULL);
+ break;
+ }
+
+ case OMX_CommandFlush:
+ case OMX_CommandPortEnable:
+ case OMX_CommandPortDisable:
+ {
+ if ((cmd == OMX_CommandPortEnable) && m_port_reconfig_inprogress)
+ {
+ m_port_reconfig_inprogress = false;
+ }
+
+ OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventCmdComplete, "
+ "%s, port index %d",
+ OMX_COMMANDTYPE_STRING(cmd),
+ param);
+
+ m_callback.EventHandler(&m_cmp,
+ m_app_data,
+ OMX_EventCmdComplete,
+ cmd,
+ param,
+ NULL);
+ break;
+ }
+
+ default:
+ {
+ OMX_SWVDEC_LOG_ERROR("cmd '%d' invalid", (int) cmd);
+
+ retval = OMX_ErrorBadParameter;
+ break;
+ }
+
+ } // switch (cmd)
+
+ return retval;
+}
+
+/**
+ * @brief Process error event.
+ *
+ * @param[in] error_code: Error code.
+ *
+ * @retval OMX_ErrorNone
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_error(OMX_ERRORTYPE error_code)
+{
+ if (error_code == OMX_ErrorInvalidState)
+ {
+ OMX_SWVDEC_LOG_HIGH("%s -> OMX_StateInvalid",
+ OMX_STATETYPE_STRING(m_state));
+
+ m_state = OMX_StateInvalid;
+ }
+
+ OMX_SWVDEC_LOG_CALLBACK("EventHandler(): OMX_EventError, 0x%08x",
+ error_code);
+
+ m_callback.EventHandler(&m_cmp,
+ m_app_data,
+ OMX_EventError,
+ (OMX_U32) error_code,
+ 0,
+ NULL);
+
+ return OMX_ErrorNone;
+}
+
+/**
+ * @brief Process OMX_CommandStateSet.
+ *
+ * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
+ * @param[in] state_new: New state to which transition is requested.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_state_set(
+ bool *p_cmd_ack,
+ OMX_STATETYPE state_new)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ SWVDEC_STATUS retval_swvdec;
+
+ OMX_SWVDEC_LOG_HIGH("'%s-to-%s' requested",
+ OMX_STATETYPE_STRING(m_state),
+ OMX_STATETYPE_STRING(state_new));
+
+ /**
+ * Only the following state transitions are allowed via CommandStateSet:
+ *
+ * LOADED -> IDLE -> EXECUTING
+ * LOADED <- IDLE <- EXECUTING
+ */
+
+ if (m_state == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("in state %s", OMX_STATETYPE_STRING(m_state));
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if (state_new == OMX_StateInvalid)
+ {
+ OMX_SWVDEC_LOG_ERROR("requested transition to state %s",
+ OMX_STATETYPE_STRING(state_new));
+
+ retval = OMX_ErrorInvalidState;
+ }
+ else if ((m_state == OMX_StateLoaded) &&
+ (state_new == OMX_StateIdle))
+ {
+ if ((m_port_ip.populated == OMX_TRUE) &&
+ (m_port_op.populated == OMX_TRUE))
+ {
+ if ((retval_swvdec = swvdec_start(m_swvdec_handle)) ==
+ SWVDEC_STATUS_SUCCESS)
+ {
+ *p_cmd_ack = true;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to start SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+ else
+ {
+ m_status_flags |= (1 << PENDING_STATE_LOADED_TO_IDLE);
+
+ OMX_SWVDEC_LOG_LOW("'loaded-to-idle' pending");
+ }
+ }
+ else if ((m_state == OMX_StateIdle) &&
+ (state_new == OMX_StateExecuting))
+ {
+ *p_cmd_ack = true;
+ }
+ else if ((m_state == OMX_StateExecuting) &&
+ (state_new == OMX_StateIdle))
+ {
+ m_status_flags |= (1 << PENDING_STATE_EXECUTING_TO_IDLE);
+
+ OMX_SWVDEC_LOG_LOW("'executing-to-idle' pending");
+
+ retval = flush(OMX_ALL);
+ }
+ else if ((m_state == OMX_StateIdle) &&
+ (state_new == OMX_StateLoaded))
+ {
+ if ((m_port_ip.unpopulated == OMX_TRUE) &&
+ (m_port_op.unpopulated == OMX_TRUE))
+ {
+ if ((retval_swvdec = swvdec_stop(m_swvdec_handle)) ==
+ SWVDEC_STATUS_SUCCESS)
+ {
+ *p_cmd_ack = true;
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to stop SwVdec");
+
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+ else
+ {
+ m_status_flags |= (1 << PENDING_STATE_IDLE_TO_LOADED);
+
+ OMX_SWVDEC_LOG_LOW("'idle-to-loaded' pending");
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("state transition '%s -> %s' illegal",
+ OMX_STATETYPE_STRING(m_state),
+ OMX_STATETYPE_STRING(state_new));
+
+ retval = ((state_new == m_state) ?
+ OMX_ErrorSameState :
+ OMX_ErrorIncorrectStateTransition);
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Process OMX_CommandFlush.
+ *
+ * @param[in] port_index: Index of port to flush.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_flush(unsigned int port_index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_LOG_HIGH("flush port index %d requested", port_index);
+
+ if (port_index == OMX_CORE_PORT_INDEX_IP)
+ {
+ m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
+
+ OMX_SWVDEC_LOG_LOW("ip port flush pending");
+ }
+ else if (port_index == OMX_CORE_PORT_INDEX_OP)
+ {
+ m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
+
+ OMX_SWVDEC_LOG_LOW("op port flush pending");
+ }
+ else if (port_index == OMX_ALL)
+ {
+ m_status_flags |= (1 << PENDING_PORT_FLUSH_IP);
+ m_status_flags |= (1 << PENDING_PORT_FLUSH_OP);
+
+ OMX_SWVDEC_LOG_LOW("ip & op ports flush pending");
+ }
+
+ retval = flush(port_index);
+
+ return retval;
+}
+
+/**
+ * @brief Process OMX_CommandPortDisable.
+ *
+ * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
+ * @param[in] port_index: Index of port to disable.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_disable(
+ bool *p_cmd_ack,
+ unsigned int port_index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_LOG_HIGH("disable port index %d requested", port_index);
+
+ if (port_index == OMX_CORE_PORT_INDEX_IP)
+ {
+ if (m_port_ip.enabled == OMX_FALSE)
+ {
+ OMX_SWVDEC_LOG_ERROR("ip port already disabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else
+ {
+ m_port_ip.enabled = OMX_FALSE;
+
+ if (m_port_ip.unpopulated)
+ {
+ *p_cmd_ack = true;
+ }
+ else
+ {
+ m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
+
+ OMX_SWVDEC_LOG_LOW("ip port disable pending");
+
+ if (m_port_ip.num_pending_buffers)
+ {
+ retval = flush(port_index);
+ }
+ }
+ }
+ }
+ else if (port_index == OMX_CORE_PORT_INDEX_OP)
+ {
+ if (m_port_op.enabled == OMX_FALSE)
+ {
+ OMX_SWVDEC_LOG_ERROR("op port already disabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else
+ {
+ m_port_op.enabled = OMX_FALSE;
+
+ if (m_port_op.unpopulated)
+ {
+ *p_cmd_ack = true;
+ }
+ else
+ {
+ m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
+
+ OMX_SWVDEC_LOG_LOW("op port disable pending");
+
+ if (m_port_op.num_pending_buffers)
+ {
+ retval = flush(port_index);
+ }
+ }
+ }
+ }
+ else if (port_index == OMX_ALL)
+ {
+ if (m_port_ip.enabled == OMX_FALSE)
+ {
+ OMX_SWVDEC_LOG_ERROR("ip port already disabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else if (m_port_op.enabled == OMX_FALSE)
+ {
+ OMX_SWVDEC_LOG_ERROR("op port already disabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else
+ {
+ if (m_port_ip.unpopulated && m_port_op.unpopulated)
+ {
+ *p_cmd_ack = true;
+ }
+ else
+ {
+ m_port_ip.enabled = OMX_FALSE;
+ m_port_op.enabled = OMX_FALSE;
+
+ if (m_port_ip.unpopulated == OMX_FALSE)
+ {
+ m_status_flags |= (1 << PENDING_PORT_DISABLE_IP);
+
+ OMX_SWVDEC_LOG_LOW("ip port disable pending");
+
+ if (m_port_ip.num_pending_buffers)
+ {
+ retval = flush(port_index);
+ }
+ }
+
+ if ((retval == OMX_ErrorNone) &&
+ (m_port_op.unpopulated == OMX_FALSE))
+ {
+ m_status_flags |= (1 << PENDING_PORT_DISABLE_OP);
+
+ OMX_SWVDEC_LOG_LOW("op port disable pending");
+
+ if (m_port_op.num_pending_buffers)
+ {
+ retval = flush(port_index);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ port_index);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Process OMX_CommandPortEnable.
+ *
+ * @param[in,out] p_cmd_ack: Pointer to 'command acknowledge' boolean variable.
+ * @param[in] port_index: Index of port to enable.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_cmd_port_enable(
+ bool *p_cmd_ack,
+ unsigned int port_index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_LOG_HIGH("enable port index %d requested", port_index);
+
+ if (port_index == OMX_CORE_PORT_INDEX_IP)
+ {
+ if (m_port_ip.enabled)
+ {
+ OMX_SWVDEC_LOG_ERROR("ip port already enabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else
+ {
+ m_port_ip.enabled = OMX_TRUE;
+
+ if (m_port_ip.populated)
+ {
+ *p_cmd_ack = true;
+ }
+ else
+ {
+ m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
+
+ OMX_SWVDEC_LOG_LOW("ip port enable pending");
+ }
+ }
+ }
+ else if (port_index == OMX_CORE_PORT_INDEX_OP)
+ {
+ if (m_port_op.enabled)
+ {
+ OMX_SWVDEC_LOG_ERROR("op port already enabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else
+ {
+ m_port_op.enabled = OMX_TRUE;
+
+ if (m_port_op.populated)
+ {
+ *p_cmd_ack = true;
+ }
+ else
+ {
+ m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
+
+ OMX_SWVDEC_LOG_LOW("op port enable pending");
+ }
+ }
+ }
+ else if (port_index == OMX_ALL)
+ {
+ if (m_port_ip.enabled)
+ {
+ OMX_SWVDEC_LOG_ERROR("ip port already enabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else if (m_port_op.enabled)
+ {
+ OMX_SWVDEC_LOG_ERROR("op port already enabled");
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+ else
+ {
+ m_port_ip.enabled = OMX_TRUE;
+ m_port_op.enabled = OMX_TRUE;
+
+ if (m_port_ip.populated && m_port_op.populated)
+ {
+ *p_cmd_ack = true;
+ }
+ else if (m_port_ip.populated == false)
+ {
+ m_status_flags |= (1 << PENDING_PORT_ENABLE_IP);
+
+ OMX_SWVDEC_LOG_LOW("ip port enable pending");
+ }
+ else if (m_port_op.populated == false)
+ {
+ m_status_flags |= (1 << PENDING_PORT_ENABLE_OP);
+
+ OMX_SWVDEC_LOG_LOW("op port enable pending");
+ }
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("port index '%d' invalid",
+ port_index);
+
+ retval = OMX_ErrorBadPortIndex;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Process ETB event.
+ *
+ * @param[in] p_buffer_hdr: Pointer to buffer header.
+ * @param[in] index: Index of buffer in input buffer info array.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_etb(
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ m_port_ip.num_pending_buffers++;
+
+ if ((p_buffer_hdr->nFilledLen == 0) &&
+ ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS) == 0))
+ {
+ OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
+ "zero length & no EOS flag",
+ p_buffer_hdr,
+ p_buffer_hdr->pBuffer);
+
+ async_post_event(OMX_SWVDEC_EVENT_EBD,
+ (unsigned long) p_buffer_hdr,
+ (unsigned long) index);
+ }
+ else if (m_port_ip.flush_inprogress)
+ {
+ OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
+ "ip port flush in progress",
+ p_buffer_hdr,
+ p_buffer_hdr->pBuffer);
+
+ async_post_event(OMX_SWVDEC_EVENT_EBD,
+ (unsigned long) p_buffer_hdr,
+ (unsigned long) index);
+ }
+ else
+ {
+ SWVDEC_STATUS retval_swvdec;
+
+ SWVDEC_BUFFER *p_buffer_swvdec =
+ &(m_buffer_array_ip[index].buffer_swvdec);
+
+ if (p_buffer_hdr->nFilledLen &&
+ ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
+ {
+ m_queue_timestamp.push(p_buffer_hdr->nTimeStamp);
+ }
+
+ assert(p_buffer_swvdec->p_buffer == p_buffer_hdr->pBuffer);
+
+ if (m_arbitrary_bytes_mode &&
+ p_buffer_hdr->nFilledLen &&
+ ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == 0))
+ {
+ unsigned int offset_array[OMX_SWVDEC_MAX_FRAMES_PER_ETB] = {0};
+
+ unsigned int num_frame_headers = 1;
+
+ if ((m_omx_video_codingtype ==
+ ((OMX_VIDEO_CODINGTYPE) QOMX_VIDEO_CodingDivx)) ||
+ (m_omx_video_codingtype == OMX_VIDEO_CodingMPEG4))
+ {
+ num_frame_headers = split_buffer_mpeg4(offset_array,
+ p_buffer_hdr);
+ }
+ else
+ {
+ assert(0);
+ }
+
+ if(num_frame_headers > 1)
+ {
+ m_buffer_array_ip[index].split_count = num_frame_headers - 1;
+
+ for (unsigned int ii = 0; ii < num_frame_headers; ii++)
+ {
+ p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
+ p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
+
+ if (ii == 0)
+ {
+ p_buffer_swvdec->offset = 0;
+ p_buffer_swvdec->filled_length = (offset_array[ii + 1] ?
+ offset_array[ii + 1] :
+ p_buffer_hdr->nFilledLen);
+ }
+ else
+ {
+ p_buffer_swvdec->offset = offset_array[ii];
+ p_buffer_swvdec->filled_length =
+ p_buffer_hdr->nFilledLen - offset_array[ii];
+ }
+
+ m_diag.dump_ip(p_buffer_swvdec->p_buffer +
+ p_buffer_swvdec->offset,
+ p_buffer_swvdec->filled_length);
+
+ retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
+ p_buffer_swvdec);
+
+ if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ break;
+ }
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_HIGH("No frame detected for Buffer %p, with TS %lld",
+ p_buffer_hdr->pBuffer, p_buffer_hdr->nTimeStamp );
+
+ p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
+ p_buffer_swvdec->offset = 0;
+ p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
+ p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
+
+ m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
+ p_buffer_swvdec->filled_length);
+
+ retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
+ p_buffer_swvdec);
+
+ if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+ }
+ else
+ {
+ p_buffer_swvdec->flags = p_buffer_hdr->nFlags;
+ p_buffer_swvdec->offset = 0;
+ p_buffer_swvdec->timestamp = p_buffer_hdr->nTimeStamp;
+ p_buffer_swvdec->filled_length = p_buffer_hdr->nFilledLen;
+
+ m_diag.dump_ip(p_buffer_swvdec->p_buffer + p_buffer_swvdec->offset,
+ p_buffer_swvdec->filled_length);
+
+ retval_swvdec = swvdec_emptythisbuffer(m_swvdec_handle,
+ p_buffer_swvdec);
+
+ if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+ }
+ return retval;
+}
+
+/**
+ * @brief Process FTB event.
+ *
+ * @param[in] p_buffer_hdr: Pointer to buffer header.
+ * @param[in] index: Index of buffer in output buffer info array.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_ftb(
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ m_port_op.num_pending_buffers++;
+
+ if (m_port_op.flush_inprogress)
+ {
+ OMX_SWVDEC_LOG_HIGH("returning %p, buffer %p; "
+ "op port flush in progress",
+ p_buffer_hdr,
+ m_buffer_array_op[index].buffer_swvdec.p_buffer);
+
+ async_post_event(OMX_SWVDEC_EVENT_FBD,
+ (unsigned long) p_buffer_hdr,
+ (unsigned long) index);
+ }
+ else
+ {
+ SWVDEC_STATUS retval_swvdec;
+
+ SWVDEC_BUFFER *p_buffer_swvdec =
+ &(m_buffer_array_op[index].buffer_swvdec);
+
+ retval_swvdec = swvdec_fillthisbuffer(m_swvdec_handle, p_buffer_swvdec);
+
+ if (retval_swvdec != SWVDEC_STATUS_SUCCESS)
+ {
+ retval = retval_swvdec2omx(retval_swvdec);
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Process EBD event.
+ *
+ * @param[in] p_buffer_hdr: Pointer to buffer header.
+ * @param[in] index: Index of buffer in output buffer info array.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_ebd(
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (index < m_port_ip.def.nBufferCountActual)
+ {
+ if (m_arbitrary_bytes_mode && m_buffer_array_ip[index].split_count)
+ {
+ m_buffer_array_ip[index].split_count--;
+ }
+ else
+ {
+ m_port_ip.num_pending_buffers--;
+
+ OMX_SWVDEC_LOG_CALLBACK(
+ "EmptyBufferDone(): %p, buffer %p",
+ p_buffer_hdr,
+ m_buffer_array_ip[index].buffer_swvdec.p_buffer);
+
+ m_callback.EmptyBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
+
+ retval = OMX_ErrorBadParameter;
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Process FBD event.
+ *
+ * @param[in] p_buffer_hdr: Pointer to buffer header.
+ * @param[in] index: Index of buffer in output buffer info array.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_fbd(
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr,
+ unsigned int index)
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ static long long timestamp_prev = 0;
+
+ if (index < m_port_op.def.nBufferCountActual)
+ {
+ OMX_U8 *p_buffer;
+
+ p_buffer = m_buffer_array_op[index].buffer_swvdec.p_buffer;
+
+ m_port_op.num_pending_buffers--;
+
+ if (m_port_op.flush_inprogress)
+ {
+ p_buffer_hdr->nFilledLen = 0;
+ p_buffer_hdr->nTimeStamp = 0;
+ p_buffer_hdr->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
+ }
+
+ if (p_buffer_hdr->nFilledLen)
+ {
+ if (m_sync_frame_decoding_mode)
+ {
+ OMX_SWVDEC_LOG_LOW("sync frame decoding mode; "
+ "setting timestamp to zero");
+
+ p_buffer_hdr->nTimeStamp = 0;
+ }
+ else
+ {
+ if (m_queue_timestamp.empty())
+ {
+ OMX_SWVDEC_LOG_ERROR("timestamp queue empty; "
+ "re-using previous timestamp %lld",
+ timestamp_prev);
+
+ p_buffer_hdr->nTimeStamp = timestamp_prev;
+ }
+ else
+ {
+ p_buffer_hdr->nTimeStamp = m_queue_timestamp.top();
+
+ m_queue_timestamp.pop();
+
+ timestamp_prev = p_buffer_hdr->nTimeStamp;
+ }
+ }
+
+ ion_flush_op(index);
+
+ if (m_meta_buffer_mode)
+ {
+ pthread_mutex_lock(&m_meta_buffer_array_mutex);
+ }
+
+ m_diag.dump_op(p_buffer,
+ m_frame_dimensions.width,
+ m_frame_dimensions.height,
+ m_frame_attributes.stride,
+ m_frame_attributes.scanlines);
+
+ if (m_meta_buffer_mode)
+ {
+ pthread_mutex_unlock(&m_meta_buffer_array_mutex);
+ }
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_LOW("filled length zero; "
+ "setting timestamp to zero");
+
+ p_buffer_hdr->nTimeStamp = 0;
+ }
+
+ if (p_buffer_hdr->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ async_post_event(OMX_SWVDEC_EVENT_EOS, 0, 0);
+
+ OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
+ m_queue_timestamp.size());
+
+ while (m_queue_timestamp.empty() == false)
+ {
+ m_queue_timestamp.pop();
+ }
+ }
+
+ if (m_meta_buffer_mode &&
+ ((p_buffer_hdr->nFlags & OMX_BUFFERFLAG_READONLY)) == 0)
+ {
+ meta_buffer_ref_remove(index);
+ }
+
+ OMX_SWVDEC_LOG_CALLBACK(
+ "FillBufferDone(): %p, buffer %p, "
+ "flags 0x%08x, filled length %d, timestamp %lld",
+ p_buffer_hdr,
+ p_buffer,
+ p_buffer_hdr->nFlags,
+ p_buffer_hdr->nFilledLen,
+ p_buffer_hdr->nTimeStamp);
+
+ m_callback.FillBufferDone(&m_cmp, m_app_data, p_buffer_hdr);
+ }
+ else
+ {
+ OMX_SWVDEC_LOG_ERROR("buffer index '%d' invalid", index);
+
+ retval = OMX_ErrorBadParameter;
+ }
+
+async_process_event_fbd_exit:
+ return retval;
+}
+
+/**
+ * @brief Process EOS event.
+ *
+ * @retval OMX_ErrorNone
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_eos()
+{
+ OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
+ "OMX_EventBufferFlag, port index %d, EOS",
+ OMX_CORE_PORT_INDEX_OP);
+
+ m_callback.EventHandler(&m_cmp,
+ m_app_data,
+ OMX_EventBufferFlag,
+ OMX_CORE_PORT_INDEX_OP,
+ OMX_BUFFERFLAG_EOS,
+ NULL);
+
+ return OMX_ErrorNone;
+}
+
+/**
+ * @brief Process input port flush event.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_ip()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_EVENT_INFO event_info;
+
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr;
+
+ unsigned int index;
+
+ while (m_queue_port_ip.pop(&event_info))
+ {
+ switch (event_info.event_id)
+ {
+
+ case OMX_SWVDEC_EVENT_ETB:
+ {
+ p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ index = event_info.event_param2;
+
+ // compensate decrement in async_process_event_ebd()
+ m_port_ip.num_pending_buffers++;
+
+ retval = async_process_event_ebd(p_buffer_hdr, index);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_EBD:
+ {
+ p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ index = event_info.event_param2;
+
+ retval = async_process_event_ebd(p_buffer_hdr, index);
+ break;
+ }
+
+ default:
+ {
+ assert(0);
+ break;
+ }
+
+ }
+ }
+
+ assert(m_port_ip.num_pending_buffers == 0);
+
+ if ((retval == OMX_ErrorNone) &&
+ (m_status_flags & (1 << PENDING_PORT_FLUSH_IP)))
+ {
+ m_status_flags &= ~(1 << PENDING_PORT_FLUSH_IP);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandFlush,
+ OMX_CORE_PORT_INDEX_IP);
+ }
+
+ m_port_ip.flush_inprogress = OMX_FALSE;
+
+ return retval;
+}
+
+/**
+ * @brief Process output port flush event.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_flush_port_op()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ OMX_SWVDEC_EVENT_INFO event_info;
+
+ OMX_BUFFERHEADERTYPE *p_buffer_hdr;
+
+ unsigned int index;
+
+ while (m_queue_port_op.pop(&event_info))
+ {
+ switch (event_info.event_id)
+ {
+
+ case OMX_SWVDEC_EVENT_FTB:
+ {
+ p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ index = event_info.event_param2;
+
+ // compensate decrement in async_process_event_fbd()
+ m_port_op.num_pending_buffers++;
+
+ retval = async_process_event_fbd(p_buffer_hdr, index);
+ break;
+ }
+
+ case OMX_SWVDEC_EVENT_FBD:
+ {
+ p_buffer_hdr = (OMX_BUFFERHEADERTYPE *) event_info.event_param1;
+
+ index = event_info.event_param2;
+
+ retval = async_process_event_fbd(p_buffer_hdr, index);
+ break;
+ }
+
+ default:
+ {
+ assert(0);
+ break;
+ }
+
+ }
+ }
+
+ assert(m_port_op.num_pending_buffers == 0);
+
+ if ((retval == OMX_ErrorNone) &&
+ (m_status_flags & (1 << PENDING_PORT_FLUSH_OP)))
+ {
+ m_status_flags &= ~(1 << PENDING_PORT_FLUSH_OP);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandFlush,
+ OMX_CORE_PORT_INDEX_OP);
+ }
+
+ if ((retval == OMX_ErrorNone) &&
+ (m_status_flags & (1 << PENDING_STATE_EXECUTING_TO_IDLE)))
+ {
+ m_status_flags &= ~(1 << PENDING_STATE_EXECUTING_TO_IDLE);
+
+ async_post_event(OMX_SWVDEC_EVENT_CMD_ACK,
+ OMX_CommandStateSet,
+ OMX_StateIdle);
+ }
+
+ if (m_port_reconfig_inprogress == false)
+ {
+ OMX_SWVDEC_LOG_LOW("flushing %zu elements in timestamp queue",
+ m_queue_timestamp.size());
+
+ while (m_queue_timestamp.empty() == false)
+ {
+ m_queue_timestamp.pop();
+ }
+ }
+
+ m_port_op.flush_inprogress = OMX_FALSE;
+
+ return retval;
+}
+
+/**
+ * @brief Process port reconfiguration event.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_port_reconfig()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_port_reconfig_inprogress)
+ {
+ OMX_SWVDEC_LOG_ERROR("port reconfiguration already in progress");
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ m_port_reconfig_inprogress = true;
+
+ OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
+ "OMX_EventPortSettingsChanged, port index %d",
+ OMX_CORE_PORT_INDEX_OP);
+
+ m_callback.EventHandler(&m_cmp,
+ m_app_data,
+ OMX_EventPortSettingsChanged,
+ OMX_CORE_PORT_INDEX_OP,
+ 0,
+ NULL);
+ }
+
+ return retval;
+}
+
+/**
+ * @brief Process dimensions updated event.
+ *
+ * @retval OMX_ERRORTYPE
+ */
+OMX_ERRORTYPE omx_swvdec::async_process_event_dimensions_updated()
+{
+ OMX_ERRORTYPE retval = OMX_ErrorNone;
+
+ if (m_dimensions_update_inprogress)
+ {
+ OMX_SWVDEC_LOG_ERROR("dimensions update already in progress");
+
+ retval = OMX_ErrorIncorrectStateOperation;
+ }
+ else
+ {
+ m_dimensions_update_inprogress = true;
+
+ OMX_SWVDEC_LOG_CALLBACK("EventHandler(): "
+ "OMX_EventPortSettingsChanged, port index %d, "
+ "OMX_IndexConfigCommonOutputCrop",
+ OMX_CORE_PORT_INDEX_OP);
+
+ m_callback.EventHandler(&m_cmp,
+ m_app_data,
+ OMX_EventPortSettingsChanged,
+ OMX_CORE_PORT_INDEX_OP,
+ OMX_IndexConfigCommonOutputCrop,
+ NULL);
+ }
+
+ return retval;
+}
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec_utils.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec_utils.cpp
new file mode 100644
index 0000000..56c3f30
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_swvdec_utils.cpp
@@ -0,0 +1,353 @@
+/**
+ * @copyright
+ *
+ * Copyright (c) 2015-2016, 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.
+ *
+ * @file
+ *
+ * omx_swvdec_utils.cpp
+ *
+ * @brief
+ *
+ * OMX software video decoder utility functions source.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <pthread.h>
+#include <time.h>
+
+#include <cutils/properties.h>
+
+#include "omx_swvdec_utils.h"
+
+#define OMX_SWVDEC_LOGLEVEL_DEFAULT 2 ///< default OMX SwVdec loglevel
+
+unsigned int g_omx_swvdec_logmask = (1 << OMX_SWVDEC_LOGLEVEL_DEFAULT) - 1;
+ ///< global OMX SwVdec logmask variable definition
+
+/**
+ * @brief Initialize OMX SwVdec log level & mask.
+ */
+void omx_swvdec_log_init()
+{
+ int omx_swvdec_loglevel = OMX_SWVDEC_LOGLEVEL_DEFAULT;
+
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+
+ if (property_get("omx_swvdec.log.level", property_value, NULL))
+ {
+ omx_swvdec_loglevel = atoi(property_value);
+
+ if (omx_swvdec_loglevel > 3)
+ {
+ omx_swvdec_loglevel = 3;
+ }
+
+ if (omx_swvdec_loglevel < 0)
+ {
+ omx_swvdec_loglevel = 0;
+ }
+
+ OMX_SWVDEC_LOG_HIGH(
+ "omx_swvdec.log.level: %d; %s",
+ omx_swvdec_loglevel,
+ (omx_swvdec_loglevel == 3) ? "error, high, & low logs" :
+ ((omx_swvdec_loglevel == 2) ? "error & high logs" :
+ ((omx_swvdec_loglevel == 1) ? "error logs" :
+ "no logs")));
+ }
+
+ g_omx_swvdec_logmask = (unsigned int) ((1 << omx_swvdec_loglevel) - 1);
+}
+
+/**
+ * @brief OMX SwVdec queue constructor.
+ */
+omx_swvdec_queue::omx_swvdec_queue()
+{
+ pthread_mutex_init(&m_mutex, NULL);
+}
+
+/**
+ * @brief OMX SwVdec queue destructor.
+ */
+omx_swvdec_queue::~omx_swvdec_queue()
+{
+ pthread_mutex_destroy(&m_mutex);
+}
+
+/**
+ * @brief Push event to queue.
+ *
+ * @param[in] p_event_info: Pointer to event information structure.
+ */
+void omx_swvdec_queue::push(OMX_SWVDEC_EVENT_INFO *p_event_info)
+{
+ pthread_mutex_lock(&m_mutex);
+
+ m_queue.push(*p_event_info);
+
+ pthread_mutex_unlock(&m_mutex);
+}
+
+/**
+ * @brief Pop event from queue.
+ *
+ * @param[in,out] p_event_info: Pointer to event information structure.
+ *
+ * @retval true if pop successful
+ * @retval false if pop unsuccessful
+ */
+bool omx_swvdec_queue::pop(OMX_SWVDEC_EVENT_INFO *p_event_info)
+{
+ bool retval = true;
+
+ pthread_mutex_lock(&m_mutex);
+
+ if (m_queue.empty())
+ {
+ retval = false;
+ }
+ else
+ {
+ *p_event_info = m_queue.front();
+
+ m_queue.pop();
+ }
+
+ pthread_mutex_unlock(&m_mutex);
+
+ return retval;
+}
+
+/**
+ * @brief OMX SwVdec diagnostics class constructor.
+ */
+omx_swvdec_diag::omx_swvdec_diag():
+ m_dump_ip(0),
+ m_dump_op(0),
+ m_filename_ip(NULL),
+ m_filename_op(NULL),
+ m_file_ip(NULL),
+ m_file_op(NULL)
+{
+ time_t time_raw;
+
+ struct tm *time_info;
+
+ char time_string[16];
+
+ char filename_ip[PROPERTY_VALUE_MAX];
+ char filename_op[PROPERTY_VALUE_MAX];
+
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+
+ time_raw = time(NULL);
+
+ time_info = localtime(&time_raw);
+
+ if (time_info != NULL)
+ {
+ // time string: "YYYYmmddTHHMMSS"
+ strftime(time_string, sizeof(time_string), "%Y%m%dT%H%M%S", time_info);
+ }
+ else
+ {
+ // time string: "19700101T000000"
+ snprintf(time_string, sizeof(time_string), "19700101T000000");
+ }
+
+ // default ip filename: "/data/misc/media/omx_swvdec_YYYYmmddTHHMMSS_ip.bin"
+ snprintf(filename_ip,
+ sizeof(filename_ip),
+ "%s/omx_swvdec_%s_ip.bin",
+ DIAG_FILE_PATH,
+ time_string);
+
+ // default op filename: "/data/misc/media/omx_swvdec_YYYYmmddTHHMMSS_op.yuv"
+ snprintf(filename_op,
+ sizeof(filename_op),
+ "%s/omx_swvdec_%s_op.yuv",
+ DIAG_FILE_PATH,
+ time_string);
+
+ if (property_get("omx_swvdec.dump.ip", property_value, NULL))
+ {
+ m_dump_ip = atoi(property_value);
+
+ OMX_SWVDEC_LOG_HIGH("omx_swvdec.dump.ip: %d", m_dump_ip);
+ }
+
+ if (property_get("omx_swvdec.dump.op", property_value, NULL))
+ {
+ m_dump_op = atoi(property_value);
+
+ OMX_SWVDEC_LOG_HIGH("omx_swvdec.dump.op: %d", m_dump_op);
+ }
+
+ if (m_dump_ip && property_get("omx_swvdec.filename.ip",
+ property_value,
+ filename_ip))
+ {
+ m_filename_ip =
+ (char *) malloc((strlen(property_value) + 1) * sizeof(char));
+
+ if (m_filename_ip == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to allocate %zu bytes for "
+ "input filename string",
+ (strlen(property_value) + 1) * sizeof(char));
+ }
+ else
+ {
+ strlcpy(m_filename_ip, property_value, strlen(m_filename_ip));
+
+ OMX_SWVDEC_LOG_HIGH("omx_swvdec.filename.ip: %s", m_filename_ip);
+
+ if ((m_file_ip = fopen(m_filename_ip, "wb")) == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cannot open input file '%s'",
+ m_filename_ip);
+ }
+ }
+ }
+
+ if (m_dump_op && property_get("omx_swvdec.filename.op",
+ property_value,
+ filename_op))
+ {
+ m_filename_op =
+ (char *) malloc((strlen(property_value) + 1) * sizeof(char));
+
+ if (m_filename_op == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("failed to allocate %zu bytes for "
+ "output filename string",
+ (strlen(property_value) + 1) * sizeof(char));
+ }
+ else
+ {
+ strlcpy(m_filename_op, property_value, strlen(m_filename_op));
+
+ OMX_SWVDEC_LOG_HIGH("omx_swvdec.filename.op: %s", m_filename_op);
+
+ if ((m_file_op = fopen(m_filename_op, "wb")) == NULL)
+ {
+ OMX_SWVDEC_LOG_ERROR("cannot open output file '%s'",
+ m_filename_op);
+ }
+ }
+ }
+}
+
+/**
+ * @brief OMX SwVdec diagnostics class destructor.
+ */
+omx_swvdec_diag::~omx_swvdec_diag()
+{
+ if (m_file_op)
+ {
+ fclose(m_file_op);
+ m_file_op = NULL;
+ }
+
+ if (m_file_ip)
+ {
+ fclose(m_file_ip);
+ m_file_ip = NULL;
+ }
+
+ if (m_filename_op)
+ {
+ free(m_filename_op);
+ m_filename_op = NULL;
+ }
+
+ if (m_filename_ip)
+ {
+ free(m_filename_ip);
+ m_filename_ip = NULL;
+ }
+}
+
+/**
+ * @brief Dump input bitstream to file.
+ *
+ * @param[in] p_buffer: Pointer to input bitstream buffer.
+ * @param[in] filled_length: Bitstream buffer's filled length.
+ */
+void omx_swvdec_diag::dump_ip(unsigned char *p_buffer,
+ unsigned int filled_length)
+{
+ if (m_dump_ip && (m_file_ip != NULL))
+ {
+ fwrite(p_buffer, sizeof(unsigned char), filled_length, m_file_ip);
+ }
+}
+
+/**
+ * @brief Dump output YUV to file.
+ *
+ * @param[in] p_buffer: Pointer to output YUV buffer.
+ * @param[in] width: Frame width.
+ * @param[in] height: Frame height.
+ * @param[in] stride: Frame stride.
+ * @param[in] scanlines: Frame scanlines.
+ */
+void omx_swvdec_diag::dump_op(unsigned char *p_buffer,
+ unsigned int width,
+ unsigned int height,
+ unsigned int stride,
+ unsigned int scanlines)
+{
+ if (m_dump_op && (m_file_op != NULL))
+ {
+ unsigned char *p_buffer_y;
+ unsigned char *p_buffer_uv;
+
+ unsigned int ii;
+
+ p_buffer_y = p_buffer;
+ p_buffer_uv = p_buffer + (stride * scanlines);
+
+ for (ii = 0; ii < height; ii++)
+ {
+ fwrite(p_buffer_y, sizeof(unsigned char), width, m_file_op);
+
+ p_buffer_y += stride;
+ }
+
+ for (ii = 0; ii < (height / 2); ii++)
+ {
+ fwrite(p_buffer_uv, sizeof(unsigned char), width, m_file_op);
+
+ p_buffer_uv += stride;
+ }
+ }
+}
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp
new file mode 100644
index 0000000..9fc4014
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp
@@ -0,0 +1,8435 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013-2015, 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 <string.h>
+#include <pthread.h>
+#include <sys/prctl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include "omx_vdec_hevc.h"
+#include <fcntl.h>
+#include <limits.h>
+#include <media/msm_media_info.h>
+#include <qdMetaData.h>
+
+#ifndef _ANDROID_
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#endif //_ANDROID_
+
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#undef USE_EGL_IMAGE_GPU
+#endif
+
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+#include <gralloc_priv.h>
+#endif
+
+#ifdef USE_EGL_IMAGE_GPU
+#include <EGL/egl.h>
+#include <EGL/eglQCOM.h>
+#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
+
+#ifdef VENUS_HEVC
+#define DEVICE_NAME "/dev/video/venus_dec"
+#else
+#define DEVICE_NAME "/dev/video/q6_dec"
+#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<utils/Log.h>
+}
+#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) ? (__num_planes) - 1 : 0)
+
+#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<omx_vdec*>(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");
+ 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");
+ break;
+ } else if (rc < 0) {
+ DEBUG_PRINT_ERROR("Error while polling: %d", 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("async_message_thread Exited");
+ 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("async_message_thread Exited");
+ 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("VIDC Port Reconfig recieved");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ 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("VIDC Port Reconfig recieved");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ 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 Flush Done Recieved");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
+ vdec_msg.status_code=VDEC_S_SUCCESS;
+ DEBUG_PRINT_HIGH("VIDC Flush Done Recieved");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
+ DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
+ 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("SYS Error Recieved");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ } else {
+ DEBUG_PRINT_HIGH("VIDC Some Event recieved");
+ continue;
+ }
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
+ return NULL;
+}
+
+void* message_thread(void *input)
+{
+ omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
+ unsigned char id;
+ int n;
+ if (omx == NULL) {
+ DEBUG_PRINT_ERROR("message thread null pointer rxd");
+ return NULL;
+ }
+
+ 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_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
+ break;
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
+ 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");
+ return;
+ }
+ 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(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", __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,
+ ion_user_handle_t 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),
+#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.debug.level", property_value, "1");
+ debug_level = atoi(property_value);
+ property_value[0] = '\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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", 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)
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", 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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", 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("STOP Command failed");
+ }
+ 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",
+ __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("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("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("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");
+ 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("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", __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("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("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("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("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("empty_buffer_done failure");
+ pThis->omx_report_error ();
+ }
+ if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
+ DEBUG_PRINT_ERROR("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("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("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_HIGH("WARNING: Unexpected flush from driver");
+ } else {
+ pThis->execute_input_flush();
+ if (pThis->m_cb.EventHandler) {
+ if (p2 != VDEC_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("OMX_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->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
+ pThis->omx_report_error ();
+ } else {
+ pThis->streaming[OUTPUT_PORT] = false;
+ }
+ if (!pThis->output_flush_progress) {
+ DEBUG_PRINT_LOW("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("Driver flush o/p Port complete");
+ if (!pThis->output_flush_progress) {
+ DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
+ } else {
+ pThis->execute_output_flush();
+ if (pThis->m_cb.EventHandler) {
+ if (p2 != VDEC_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("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->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
+ pThis->omx_report_error ();
+ break;
+ }
+ pThis->streaming[CAPTURE_PORT] = false;
+ if (!pThis->input_flush_progress) {
+ DEBUG_PRINT_LOW("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("Rxd OMX_COMPONENT_GENERATE_START_DONE");
+
+ if (pThis->m_cb.EventHandler) {
+ if (p2 != VDEC_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("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("VDEC_IOCTL_CMD_PAUSE failed");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ } else {
+ DEBUG_PRINT_LOW("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("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("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 (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("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("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__);
+ }
+ }
+ 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)DEVICE_NAME;
+ DEBUG_PRINT_LOW("Opening device %s", device_name);
+ drv_ctx.video_driver_fd = open(device_name, O_RDWR);
+
+ DEBUG_PRINT_HIGH("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", 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("Failed to create async_message_thread");
+ 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("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 ("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);
+
+ } 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;
+ 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);
+
+ } 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;
+ 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);
+
+ } 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_CodingVP8;
+ codec_type_parse = CODEC_TYPE_VP8;
+ arbitrary_bytes = false;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR:Unknown Component");
+ 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("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("Subscribe Event Failed");
+ 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");
+ /*TODO: How to handle this case */
+ } else {
+ DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
+ " version = %d, capabilities = %x", 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", 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", 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");
+ }
+ DEBUG_PRINT_HIGH("Set Format was successful");
+ 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");
+ }
+ } 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");
+ }
+ DEBUG_PRINT_HIGH("Set Format was successful");
+ 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", 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", 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",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("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("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");
+ eRet = OMX_ErrorInsufficientResources;
+ } else {
+ int temp1[2];
+ if (fds[0] == 0 || fds[1] == 0) {
+ if (pipe (temp1)) {
+ DEBUG_PRINT_ERROR("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("component_init(): message_thread creation failed");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ }
+
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("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);
+ DEBUG_PRINT_HIGH("Calling close() on Video Driver");
+ close (drv_ctx.video_driver_fd);
+ drv_ctx.video_driver_fd = -1;
+ } else {
+ DEBUG_PRINT_HIGH("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");
+ 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("send_command: Recieved a Command from Client");
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("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("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("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,ret=0;
+
+ DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
+ DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
+ 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("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");
+ 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");
+ 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");
+ 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)",\
+ 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");
+ } else {
+ DEBUG_PRINT_LOW("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_LOW("send_command_proxy(): Idle-->Executing");
+ //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
+ bFlag = 1;
+ DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
+ m_state=OMX_StateExecuting;
+ DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
+ }
+ /* Requesting transition from Idle to Idle */
+ else if (eState == OMX_StateIdle) {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
+ 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");
+ 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("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");
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Idle to Invalid */
+ else if (eState == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ /******************************/
+ /* Current State is Executing */
+ /******************************/
+ else if (m_state == OMX_StateExecuting) {
+ DEBUG_PRINT_LOW("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("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_LOW("PAUSE Command Issued");
+ m_state = OMX_StatePause;
+ bFlag = 1;
+ }
+ /* Requesting transition from Executing to Loaded */
+ else if (eState == OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
+ 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("send_command_proxy(): Executing --> WaitForResources");
+ 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("send_command_proxy(): Executing --> Executing");
+ 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("send_command_proxy(): Executing --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",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("Pause --> Executing");
+ 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("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("Pause --> loaded");
+ 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("Pause --> WaitForResources");
+ 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("Pause --> Pause");
+ 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("Pause --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",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");
+ }
+ /* Requesting transition from WaitForResources to WaitForResources */
+ else if (eState == OMX_StateWaitForResources) {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
+ 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");
+ 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");
+ 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");
+ 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)",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");
+ 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: %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("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: %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");
+ 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("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");
+ 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: %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("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)",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("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("Initiate Output Flush");
+ while (m_ftb_q.m_size) {
+ DEBUG_PRINT_LOW("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("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_LOW("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_LOW("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("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("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("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("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("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;
+}
+
+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",
+ 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",
+ 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_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", 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_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", 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_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ return eRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::GetParameter
+
+ DESCRIPTION
+ OMX Get Parameter method implementation
+
+ PARAMETERS
+ <TBD>.
+
+ 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");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL) {
+ DEBUG_PRINT_LOW("Get Param in Invalid paramData");
+ 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");
+ 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");
+
+ 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");
+
+ 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");
+ 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");
+ eRet = OMX_ErrorNoMore;
+ }
+ DEBUG_PRINT_LOW("returning %d", portFmt->eColorFormat);
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
+ (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");
+ 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");
+ 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",
+ 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",
+ 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");
+ 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");
+
+ 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",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg2:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", 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");
+ 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_UNCACHED;
+#endif
+ DEBUG_PRINT_HIGH("nativeBuffersUsage->nUsage %x", (unsigned int)nativeBuffersUsage->nUsage);
+ }
+ } else {
+ DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ break;
+#endif
+
+ default:
+ {
+ DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", 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<android_native_buffer_t> 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
+ <TBD>.
+
+ 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");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL) {
+ DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
+ 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");
+ 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",
+ (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("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)",
+ 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");
+ 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) {
+ 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("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",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("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)",
+ 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",
+ 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("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("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",
+ 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",
+ 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: out pmem set");
+ 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");
+ 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", 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", 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", 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", 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", 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", 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", 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", comp_role->cRole);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+ break;
+ }
+
+ case OMX_IndexParamPriorityMgmt:
+ {
+ if (m_state != OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d",
+ priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d",
+ 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",
+ 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",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg2:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
+ 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",
+ 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("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("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("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("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("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");
+ 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");
+ 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("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("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");
+ 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", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ return eRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::GetConfig
+
+ DESCRIPTION
+ OMX Get Config Method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ 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");
+ 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");
+ eRet = OMX_ErrorNoMore;
+ }
+
+ } else {
+ DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
+ (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",configIndex);
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ }
+
+ return eRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::SetConfig
+
+ DESCRIPTION
+ OMX Set Config method implementation
+
+ PARAMETERS
+ <TBD>.
+
+ 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");
+ 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");
+ return ret;
+ }
+
+ if (configIndex == (OMX_INDEXTYPE)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 (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");
+ 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");
+ 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");
+ 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");
+ }
+ }
+ 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. <TBD>
+
+ PARAMETERS
+ <TBD>.
+
+ 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");
+ 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", 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", paramName);
+ return OMX_ErrorNotImplemented;
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::GetState
+
+ DESCRIPTION
+ Returns the state information back to the caller.<TBD>
+
+ PARAMETERS
+ <TBD>.
+
+ 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. <TBD>
+
+ 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");
+ 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", 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");
+ 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");
+ 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", 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<android_native_buffer_t> 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", 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", 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", 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", 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("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");
+ 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("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("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("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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+ buf.m.planes = plane;
+ buf.length = drv_ctx.num_planes;
+
+ DEBUG_PRINT_LOW("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");
+ /*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("STREAMON Successful");
+ }
+ }
+
+ (*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
+ <TBD>.
+
+ 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],
+ (unsigned)NULL, (unsigned)NULL)) {
+ DEBUG_PRINT_ERROR("ERROR: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
+ <TBD>.
+
+ 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");
+ 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",(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_setbuffer_cmd setbuffers;
+ setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
+ memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
+ sizeof (vdec_bufferpayload));
+ 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) {
+ 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_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("unmap the output buffer fd = %d",
+ drv_ctx.ptr_outputbuffer[0].pmem_fd);
+ DEBUG_PRINT_LOW("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("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;
+ 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],
+ (unsigned)NULL, (unsigned)NULL)) {
+ DEBUG_PRINT_ERROR("ERROR: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("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) {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc;
+
+#ifdef USE_ION
+ DEBUG_PRINT_HIGH("Allocate input Buffer size %d", 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("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("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("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("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("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");
+ /*TODO: How to handle this case */
+ 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;
+ 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("ERROR:Input Buffer Index not found");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::AllocateOutputBuffer
+
+ DESCRIPTION
+ Helper fn for AllocateBuffer in the output pin
+
+ PARAMETERS
+ <TBD>.
+
+ 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("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)",
+ 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);
+#ifdef USE_ION
+ DEBUG_PRINT_HIGH("allocate outputBuffer size %d",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("ERROR: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("ERROR: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("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("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",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 = 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",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("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]",\
+ 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;
+ }
+ 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("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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+ buf.m.planes = plane;
+ buf.length = drv_ctx.num_planes;
+ DEBUG_PRINT_LOW("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("STREAMON Successful");
+ }
+ }
+
+ (*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");
+ 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");
+ 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",(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 ((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", port);
+ } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
+ DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
+ 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");
+ 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");
+ 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");
+ 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__);
+ }
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL) {
+ DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_inp_bEnabled) {
+ DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ 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("ERROR: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("ERROR: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("ERROR: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;
+ }
+
+
+ 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 %lu frame number %u",
+ 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;
+ }
+ }
+ }
+
+ if (input_flush_progress == true
+
+ || not_coded_vop
+
+ ) {
+ 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;
+ }
+ 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_QCOM_BUF_FLAG_EOS;
+ DEBUG_PRINT_HIGH("INPUT EOS reached") ;
+ }
+ 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");
+ return OMX_ErrorHardware;
+ }
+ codec_config_flag = false;
+ DEBUG_PRINT_LOW("%s: codec_config cleared", __FUNCTION__);
+
+ 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");
+ ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
+ if (!ret) {
+ DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
+ streaming[OUTPUT_PORT] = true;
+ } else {
+ /*TODO: How to handle this case */
+ DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
+ 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)
+{
+ unsigned nPortIndex = buffer - client_buffers.get_il_buf_hdr();
+
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("FTB in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (!m_out_bEnabled) {
+ DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (buffer == NULL ||
+ (nPortIndex >= drv_ctx.op_buf.actualcount)) {
+ DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
+ nPortIndex, drv_ctx.op_buf.actualcount);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("ERROR: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) {
+ DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
+ nPortIndex, 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;
+ }
+
+ 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", 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");
+ }
+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
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if everything successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+
+ unsigned i = 0;
+ if (OMX_StateLoaded != m_state) {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
+ m_state);
+ DEBUG_PRINT_ERROR("Playback Ended - FAILED");
+ } else {
+ DEBUG_PRINT_HIGH("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");
+ for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
+ free_output_buffer (&m_out_mem_ptr[i]);
+ }
+#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; i<drv_ctx.ip_buf.actualcount; i++ ) {
+ if (m_inp_mem_ptr)
+ free_input_buffer (i,&m_inp_mem_ptr[i]);
+ else
+ free_input_buffer (i,NULL);
+ }
+ }
+ free_input_buffer_header();
+ free_output_buffer_header();
+ if (h264_scratch.pBuffer) {
+ free(h264_scratch.pBuffer);
+ h264_scratch.pBuffer = NULL;
+ }
+
+ if (h264_parser) {
+ delete h264_parser;
+ h264_parser = NULL;
+ }
+
+ if (m_platform_list) {
+ free(m_platform_list);
+ m_platform_list = NULL;
+ }
+ if (m_vendor_config.pData) {
+ free(m_vendor_config.pData);
+ m_vendor_config.pData = NULL;
+ }
+
+ // Reset counters in mesg queues
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+#ifdef _ANDROID_
+ if (m_debug_timestamp) {
+ m_timestamp_list.reset_ts_list();
+ }
+#endif
+
+ DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
+ //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
+ // NULL);
+ DEBUG_PRINT_HIGH("Close the driver instance");
+
+#ifdef INPUT_BUFFER_LOG
+ fclose (inputBufferFile1);
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+ if (outputBufferFile1)
+ fclose (outputBufferFile1);
+#endif
+#ifdef OUTPUT_EXTRADATA_LOG
+ fclose (outputExtradataFile);
+#endif
+ DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::UseEGLImage
+
+ DESCRIPTION
+ OMX Use EGL Image method implementation <TBD>.
+
+ PARAMETERS
+ <TBD>.
+
+ 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("");
+ }
+#ifdef USE_EGL_IMAGE_GPU
+ if (m_display_id == NULL) {
+ DEBUG_PRINT_ERROR("Display ID is not set by IL client");
+ 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",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");
+ return OMX_ErrorInsufficientResources;
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ComponentRoleEnum
+
+ DESCRIPTION
+ OMX Component Role Enum method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ 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;
+ }
+ }
+
+ 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",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.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",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 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",role);
+ } else {
+ DEBUG_PRINT_LOW("No more roles");
+ eRet = OMX_ErrorNoMore;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: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.ip_buf.actualcount; i++) {
+ if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
+ break;
+ }
+ }
+ }
+ if (i == drv_ctx.ip_buf.actualcount) {
+ bRet = true;
+ DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
+ }
+ if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
+ m_inp_bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+/* ======================================================================
+ FUNCTION
+ omx_vdec::AllocateOutputDone
+
+ DESCRIPTION
+ Checks if entire O/P buffer pool is allocated by IL Client or not.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false.
+
+ ========================================================================== */
+bool omx_vdec::allocate_output_done(void)
+{
+ bool bRet = false;
+ unsigned j=0;
+
+ if (m_out_mem_ptr == NULL) {
+ return bRet;
+ }
+
+ if (m_out_mem_ptr) {
+ for (; j < drv_ctx.op_buf.actualcount; j++) {
+ if (BITMASK_ABSENT(&m_out_bm_count,j)) {
+ break;
+ }
+ }
+ }
+
+ if (j == drv_ctx.op_buf.actualcount) {
+ bRet = true;
+ DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
+ if (m_out_bEnabled)
+ m_out_bPopulated = OMX_TRUE;
+ }
+
+ return bRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ReleaseDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_vdec::release_done(void)
+{
+ bool bRet = false;
+
+ if (release_input_done()) {
+ if (release_output_done()) {
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ReleaseOutputDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_vdec::release_output_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
+ if (m_out_mem_ptr) {
+ for (; j < drv_ctx.op_buf.actualcount ; j++) {
+ if (BITMASK_PRESENT(&m_out_bm_count,j)) {
+ break;
+ }
+ }
+ if (j == drv_ctx.op_buf.actualcount) {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ } else {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ return bRet;
+}
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ReleaseInputDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_vdec::release_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
+ if (m_inp_mem_ptr) {
+ for (; j<drv_ctx.ip_buf.actualcount; j++) {
+ if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
+ break;
+ }
+ }
+ if (j==drv_ctx.ip_buf.actualcount) {
+ bRet = true;
+ }
+ } else {
+ bRet = true;
+ }
+ return bRet;
+}
+
+OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
+ if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("[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("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((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("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("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
+ buffer->nTimeStamp, expected_ts);
+
+ if (buffer->nTimeStamp != expected_ts) {
+ DEBUG_PRINT_ERROR("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("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);
+ 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("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,
+ (unsigned)NULL, (unsigned)NULL)) {
+ DEBUG_PRINT_ERROR("ERROR: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("FATAL ERROR in omx_vdec::async_message_process NULL Check");
+ return -1;
+ }
+ vdec_msg = (struct vdec_msginfo *)message;
+
+ omx = reinterpret_cast<omx_vdec*>(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("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:
+
+ 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_QCOM_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("Crop information has changed");
+ 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("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("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("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, (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("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_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("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("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 ");
+
+ 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("Zero 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("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("ERROR: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("ERROR: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("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("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("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_LOW("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("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("ERROR: 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("ERROR: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("pdest_frame->nFilledLen =%d TimeStamp = %x",
+ pdest_frame->nFilledLen,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 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 = 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");
+ 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("ERROR: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",
+ 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("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("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) {
+ 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",
+ 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");
+ 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",
+ 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",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",
+ 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("ERROR: 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");
+ 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",
+ 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("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",
+ 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("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("Invalid 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("Destination 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("Error In Parsing VC1 AP start code");
+ return OMX_ErrorBadParameter;
+ }
+ break;
+
+ case VC1_SP_MP_RCV:
+ default:
+ DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
+ 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("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");
+ 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", 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_id_mask = ION_HEAP(ION_ADSP_HEAP_ID);
+#else
+ alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
+#endif
+ if (secure_mode) {
+ alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
+ }
+ rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
+ if (rc || !alloc_data->handle) {
+ DEBUG_PRINT_ERROR("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("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;
+ fd = -ENOMEM;
+ }
+
+ return fd;
+}
+
+void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
+{
+
+ if (!buf_ion_info) {
+ DEBUG_PRINT_ERROR("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("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
+}
+
+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", 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",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",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", 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",
+ 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)",
+ 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");
+ 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");
+ 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("client_buffers.update_buffer_req Failed");
+ return OMX_ErrorHardware;
+ }
+ if (!client_buffers.get_buffer_req(buf_size)) {
+ DEBUG_PRINT_ERROR("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("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_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
+ " SliceHeight = %lu", 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("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%p][0x%p]",\
+ 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("ERROR: empty_buffer_done() failed!");
+ omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FBD:
+ if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
+ DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
+ 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)MSM_VIDC_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 MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
+ struct msm_vidc_interlace_payload *payload;
+ payload = (struct msm_vidc_interlace_payload *)data->data;
+ if (payload->format != MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
+ int enable = 1;
+ OMX_U32 mbaff = 0;
+ mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
+ if ((payload->format == MSM_VIDC_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 MSM_VIDC_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 MSM_VIDC_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 MSM_VIDC_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 MSM_VIDC_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 MSM_VIDC_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 != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
+ p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+ DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received");
+ }
+ break;
+ case MSM_VIDC_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_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d",
+ 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.");
+ }
+ } 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");
+ }
+ 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");
+ }
+ 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");
+ }
+ 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");
+ }
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set panscan extradata");
+ }
+ } 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");
+ }
+ }
+ }
+ 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",
+ 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 ===========",
+ 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",
+ 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",
+ 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 == MSM_VIDC_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",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("ERROR: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("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("desc 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_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<omx_vdec*>(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("Invalid client in color convert");
+ return false;
+ }
+ if (!enabled) {
+ DEBUG_PRINT_HIGH("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("update_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("ERROR: 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("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("Incorrect color format");
+ status = false;
+ }
+ if (status && (drv_color_format != dest_color_format)) {
+ DEBUG_PRINT_LOW("Enabling C2D");
+ if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
+ DEBUG_PRINT_ERROR("Unsupported color format for c2d");
+ status = false;
+ } else {
+ ColorFormat = OMX_COLOR_FormatYUV420Planar;
+ if (enabled)
+ c2d.destroy();
+ enabled = false;
+ if (!c2d.init()) {
+ DEBUG_PRINT_ERROR("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("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("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("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("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("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("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("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("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("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("Notin color convert mode secure_mode %d",
+ omx->is_component_secure());
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (!bufferHdr || bytes > buffer_size_req) {
+ DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
+ DEBUG_PRINT_ERROR("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("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("Buffer allocation failed color_convert");
+ return eRet;
+ }
+ if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
+ omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("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("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("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("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/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp
new file mode 100644
index 0000000..4f73bed
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc_swvdec.cpp
@@ -0,0 +1,10961 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013-2015, 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 <string.h>
+#include <pthread.h>
+#include <sys/prctl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include "omx_vdec_hevc_swvdec.h"
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/msm_media_info.h>
+
+#ifndef _ANDROID_
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#endif //_ANDROID_
+
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#undef USE_EGL_IMAGE_GPU
+#endif
+
+#include <qdMetaData.h>
+
+#ifdef USE_EGL_IMAGE_GPU
+#include <EGL/egl.h>
+#include <EGL/eglQCOM.h>
+#define EGL_BUFFER_HANDLE_QCOM 0x4F00
+#define EGL_BUFFER_OFFSET_QCOM 0x4F01
+#endif
+
+#define BUFFER_LOG_LOC "/data/misc/media"
+
+#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 DEFAULT_WIDTH_ALIGNMENT 128
+#define DEFAULT_HEIGHT_ALIGNMENT 32
+
+#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<utils/Log.h>
+}
+#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) ? (__num_planes) - 1 : 0)
+
+#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
+
+static OMX_U32 maxSmoothStreamingWidth = 1920;
+static OMX_U32 maxSmoothStreamingHeight = 1088;
+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<omx_vdec*>(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");
+ 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");
+ break;
+ } else if (rc < 0) {
+ DEBUG_PRINT_ERROR("Error while polling: %d", rc);
+ break;
+ }
+ if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
+ struct vdec_msginfo vdec_msg;
+ memset(&vdec_msg, 0, sizeof(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("async_message_thread Exited");
+ 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("async_message_thread Exited");
+ 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("VIDC Port Reconfig recieved insufficient");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ 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 ");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ 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 ");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
+ DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
+ 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("SYS Error Recieved");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
+ unsigned char *tmp = dqevent.u.data;
+ unsigned int *ptr = (unsigned int *)tmp;
+ DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
+ omx->buf_ref_remove(ptr[0], ptr[1]);
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
+ unsigned char *tmp = dqevent.u.data;
+ unsigned int *ptr = (unsigned int *)tmp;
+
+ struct vdec_msginfo vdec_msg;
+
+ DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
+
+ 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;
+ v4l2_buf.index = ptr[5];
+ v4l2_buf.flags = 0;
+
+ 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 = 0;
+ vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
+ vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
+ (uint64_t)ptr[4];
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited ");
+ break;
+ }
+ } else {
+ DEBUG_PRINT_HIGH("VIDC Some Event recieved");
+ continue;
+ }
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
+ return NULL;
+}
+
+void* message_thread(void *input)
+{
+ omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
+ unsigned char id;
+ int n;
+ if (omx == NULL)
+ {
+ DEBUG_PRINT_ERROR("message thread null pointer rxd");
+ return NULL;
+ }
+
+ 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("ERROR: read from pipe failed, ret %d errno %d", n, errno);
+ break;
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
+ 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");
+ return;
+ }
+ 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(m_q));
+}
+
+// omx cmd queue insert
+bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long 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", __func__);
+ }
+ return ret;
+}
+
+// omx cmd queue pop
+bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long*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,
+ion_user_handle_t handle, int ionMapfd)
+{
+ (void) devicefd;
+ (void) size;
+ (void) base;
+ (void) handle;
+ (void) 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),
+ m_pSwVdec(NULL),
+ m_pSwVdecIpBuffer(NULL),
+ m_pSwVdecOpBuffer(NULL),
+ m_nInputBuffer(0),
+ m_nOutputBuffer(0),
+ m_interm_mem_ptr(NULL),
+ m_interm_flush_dsp_progress(OMX_FALSE),
+ m_interm_flush_swvdec_progress(OMX_FALSE),
+ m_interm_bPopulated(OMX_FALSE),
+ m_interm_bEnabled(OMX_TRUE),
+ m_swvdec_mode(-1),
+ m_fill_internal_bufers(OMX_TRUE),
+ 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),
+#endif
+ m_desc_buffer_ptr(NULL),
+ secure_mode(false),
+ codec_config_flag(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.debug.level", property_value, "1");
+ debug_level = atoi(property_value);
+
+ DEBUG_PRINT_HIGH("In OMX vdec Constructor");
+
+ property_value[0] = '\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);
+ }
+ memset(&m_debug, 0, sizeof(m_debug));
+ 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);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.log.in", property_value, "0");
+ m_debug.in_buffer_log = atoi(property_value);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.log.out", property_value, "0");
+ m_debug.out_buffer_log = atoi(property_value);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.log.imb", property_value, "0");
+ m_debug.im_buffer_log = atoi(property_value);
+
+ sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
+ property_value[0] = '\0';
+ property_get("vidc.log.loc", property_value, "");
+ if (*property_value)
+ strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.debug.dyn.disabled", property_value, "0");
+ m_disable_dynamic_buf_mode = atoi(property_value);
+#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;
+ 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_mutexattr_t attr;
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&m_lock, &attr);
+ pthread_mutex_init(&c_lock, &attr);
+ 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);
+
+ dynamic_buf_mode = false;
+ out_dynamic_list = NULL;
+ m_smoothstreaming_mode = false;
+ m_smoothstreaming_width = 0;
+ m_smoothstreaming_height = 0;
+}
+
+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_RELEASE_BUFFER_REFERENCE,
+ V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
+ 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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", 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)
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", 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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", 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);
+ if ((!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) &&
+ (m_swvdec_mode != SWVDEC_MODE_PARSE_DECODE))
+ {
+ DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit driver id %d", drv_ctx.video_driver_fd);
+ dec.cmd = V4L2_DEC_CMD_STOP;
+ if (drv_ctx.video_driver_fd >=0 )
+ {
+ DEBUG_PRINT_HIGH("Stop decoder driver instance");
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
+ {
+ DEBUG_PRINT_ERROR("STOP Command failed");
+ }
+ }
+
+ if (async_thread_created)
+ pthread_join(async_thread_id,NULL);
+
+ unsubscribe_to_events(drv_ctx.video_driver_fd);
+ close(drv_ctx.video_driver_fd);
+ }
+
+ if (m_pSwVdec)
+ {
+ DEBUG_PRINT_HIGH("SwVdec_Stop");
+ if (SWVDEC_S_SUCCESS != SwVdec_Stop(m_pSwVdec))
+ {
+ DEBUG_PRINT_ERROR("SwVdec_Stop Command failed in vdec destructor");
+ SwVdec_DeInit(m_pSwVdec);
+ m_pSwVdec = NULL;
+ }
+ }
+
+ 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);
+ } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = 0;
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_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)
+{
+ unsigned long p1; // Parameter - 1
+ unsigned long p2; // Parameter - 2
+ unsigned long ident;
+ unsigned int qsize=0; // qsize
+ omx_vdec *pThis = (omx_vdec *) ctxt;
+
+ if(!pThis)
+ {
+ DEBUG_PRINT_ERROR("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_ftb_q_dsp.m_size;
+ if (qsize)
+ {
+ pThis->m_ftb_q_dsp.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);
+ }
+ }
+
+ if (qsize == 0 && pThis->m_state != OMX_StatePause)
+ {
+ qsize = pThis->m_etb_q_swvdec.m_size;
+ if (qsize)
+ {
+ pThis->m_etb_q_swvdec.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 == (unsigned long)OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("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 == (unsigned long)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("OMX_CommandPortDisable complete for port [%lu]", 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;
+ if (!pThis->m_pSwVdec || pThis->m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
+ if(release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
+ DEBUG_PRINT_HIGH("Failed to release output buffers");
+ }
+
+ if (pThis->m_pSwVdec)
+ {
+ SWVDEC_STATUS SwStatus;
+ DEBUG_PRINT_HIGH("In port reconfig, SwVdec_Stop");
+ SwStatus = SwVdec_Stop(pThis->m_pSwVdec);
+ if (SWVDEC_S_SUCCESS != SwStatus)
+ {
+ DEBUG_PRINT_ERROR("SwVdec_Stop failed (%d)",SwStatus);
+ pThis->omx_report_error();
+ break;
+ }
+ }
+
+ OMX_ERRORTYPE eRet1 = pThis->get_buffer_req_swvdec();
+ pThis->in_reconfig = false;
+ if(eRet != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("get_buffer_req_swvdec 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);
+ if (p2 == OMX_CORE_OUTPUT_PORT_INDEX &&
+ pThis->m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ DEBUG_PRINT_LOW("send all interm buffers to dsp after port enabled");
+ pThis->fill_all_buffers_proxy_dsp(&pThis->m_cmp);
+ }
+ 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", __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("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("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("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("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("empty_buffer_done failure");
+ pThis->omx_report_error ();
+ }
+ if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
+ {
+ DEBUG_PRINT_ERROR("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("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("fill_buffer_done failure");
+ pThis->omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
+ if (!pThis->input_flush_progress)
+ {
+ DEBUG_PRINT_ERROR("WARNING: Unexpected INPUT_FLUSH from driver");
+ }
+ else
+ {
+ pThis->execute_input_flush();
+ if (pThis->m_cb.EventHandler)
+ {
+ if (p2 != VDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("OMX_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->m_pSwVdec || pThis->m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
+ pThis->omx_report_error ();
+ } else {
+ pThis->streaming[OUTPUT_PORT] = false;
+ }
+ }
+ }
+ }
+ }
+ 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("WARNING: Unexpected OUTPUT_FLUSH from driver");
+ }
+ else
+ {
+ pThis->execute_output_flush();
+ if (pThis->m_interm_flush_dsp_progress)
+ {
+ pThis->execute_output_flush_dsp();
+ }
+ if (pThis->m_interm_flush_swvdec_progress)
+ {
+ pThis->execute_input_flush_swvdec();
+ }
+ if (pThis->m_cb.EventHandler)
+ {
+ if (p2 != VDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("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))
+ {
+ if (pThis->release_interm_done() == false)
+ {
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_OUTPUT_FLUSH failed not all interm buffers are returned");
+ pThis->omx_report_error ();
+ break;
+ }
+ pThis->m_fill_internal_bufers = OMX_TRUE;
+ DEBUG_PRINT_HIGH("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((unsigned long)OMX_CommandPortDisable,
+ (unsigned long)OMX_CORE_OUTPUT_PORT_INDEX,
+ (unsigned long)OMX_COMPONENT_GENERATE_EVENT);
+ BITMASK_CLEAR (&pThis->m_flags,
+ OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
+ BITMASK_CLEAR (&pThis->m_flags,
+ OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
+
+ }
+ }
+
+ if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
+ {
+ if (!pThis->m_pSwVdec || pThis->m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
+ pThis->omx_report_error ();
+ break;
+ }
+ pThis->streaming[CAPTURE_PORT] = false;
+ }
+ if (!pThis->input_flush_progress)
+ {
+ DEBUG_PRINT_LOW("Output flush done hence issue stop");
+ pThis->post_event ((unsigned long)NULL, (unsigned long)VDEC_S_SUCCESS,\
+ (unsigned long)OMX_COMPONENT_GENERATE_STOP_DONE);
+ }
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH_DSP:
+ DEBUG_PRINT_HIGH("Dsp Driver flush o/p Port complete");
+ if (!pThis->m_interm_flush_dsp_progress)
+ {
+ DEBUG_PRINT_ERROR("WARNING: Unexpected OUTPUT_FLUSH_DSP from driver");
+ }
+ else
+ {
+ // check if we need to flush swvdec
+ bool bFlushSwVdec = false;
+ SWVDEC_BUFFER_FLUSH_TYPE aFlushType = SWVDEC_FLUSH_ALL;
+ if (pThis->m_interm_flush_swvdec_progress)
+ {
+ aFlushType = SWVDEC_FLUSH_ALL;
+ bFlushSwVdec = true;
+ }
+ else if (pThis->output_flush_progress)
+ {
+ DEBUG_PRINT_HIGH("Flush swvdec output only ");
+ aFlushType = SWVDEC_FLUSH_OUTPUT;
+ bFlushSwVdec = true;
+ }
+
+ DEBUG_PRINT_HIGH("Flush swvdec %d, interm flush %d output flush %d swvdec flushType %d",
+ bFlushSwVdec, pThis->m_interm_flush_swvdec_progress, pThis->output_flush_progress, aFlushType);
+
+ if (bFlushSwVdec)
+ {
+ if (SwVdec_Flush(pThis->m_pSwVdec, aFlushType) != SWVDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("Flush swvdec Failed ");
+ }
+ }
+ else
+ {
+ pThis->execute_output_flush_dsp();
+ }
+ }
+ 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("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("VDEC_IOCTL_CMD_PAUSE failed");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("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("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;
+ if (pThis->m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ pThis->fill_all_buffers_proxy_dsp(&pThis->m_cmp);
+ }
+ 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("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 (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("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("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
+ pThis->omx_report_error ();
+ break;
+
+ case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
+ pThis->omx_report_unsupported_setting();
+ 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__);
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_ETB_SWVDEC:
+ {
+ DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_ETB_SWVDEC");
+ if (pThis->empty_this_buffer_proxy_swvdec((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("empty_this_buffer_proxy_swvdec failure");
+ pThis->omx_report_error ();
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_EBD_SWVDEC:
+ {
+ DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EBD_SWVDEC");
+ if (p2 != VDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD_SWVDEC failure");
+ pThis->omx_report_error ();
+ }
+ else if ( pThis->empty_buffer_done_swvdec(&pThis->m_cmp,
+ (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("empty_buffer_done_swvdec failure");
+ pThis->omx_report_error ();
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FTB_DSP:
+ {
+ DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_FTB_DSP");
+ if ( pThis->fill_this_buffer_proxy_dsp((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("fill_this_buffer_proxy_dsp failure");
+ pThis->omx_report_error ();
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FBD_DSP:
+ {
+ DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_FBD_DSP");
+ if (p2 != VDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD_DSP failure");
+ pThis->omx_report_error ();
+ }
+ else if ( pThis->fill_buffer_done_dsp(&pThis->m_cmp,
+ (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
+ {
+ DEBUG_PRINT_ERROR("fill_buffer_done failure");
+ pThis->omx_report_error ();
+ }
+
+
+ }
+ break;
+
+ 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 +
+ pThis->m_ftb_q_dsp.m_size + pThis->m_etb_q_swvdec.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 != (int)drv_ctx.video_resolution.frame_height) ||
+ (width != (int)drv_ctx.video_resolution.frame_width)) {
+ DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
+ 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()
+{
+ 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("video session supported");
+ return OMX_ErrorNone;
+}
+
+int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
+{
+ if (m_debug.in_buffer_log && !m_debug.infile) {
+ if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.hevchybrid", OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.hevcswvdec", OMX_MAX_STRINGNAME_SIZE)) {
+ sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.hevc",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ }
+ m_debug.infile = fopen (m_debug.infile_name, "ab");
+ if (!m_debug.infile) {
+ DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
+ m_debug.infile_name[0] = '\0';
+ return -1;
+ }
+ }
+ if (m_debug.infile && buffer_addr && buffer_len) {
+ fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
+ }
+ return 0;
+}
+
+int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer)
+{
+ if (m_debug.out_buffer_log && !m_debug.outfile) {
+ sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ m_debug.outfile = fopen (m_debug.outfile_name, "ab");
+ if (!m_debug.outfile) {
+ DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
+ m_debug.outfile_name[0] = '\0';
+ return -1;
+ }
+ }
+ if (m_debug.outfile && buffer && 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;
+ if (m_smoothstreaming_mode) {
+ stride = drv_ctx.video_resolution.frame_width;
+ scanlines = drv_ctx.video_resolution.frame_height;
+ stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
+ scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
+ }
+ char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
+ unsigned i;
+ int bytes_written = 0;
+ DEBUG_PRINT_LOW("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
+ drv_ctx.video_resolution.frame_width,
+ drv_ctx.video_resolution.frame_height, stride, scanlines);
+ for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
+ bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
+ 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, m_debug.outfile);
+ temp += stride_c;
+ }
+ }
+ return 0;
+}
+
+int omx_vdec::log_im_buffer(OMX_BUFFERHEADERTYPE * buffer)
+{
+ if (m_debug.im_buffer_log && !m_debug.imbfile) {
+ sprintf(m_debug.imbfile_name, "%s/imb_%d_%d_%p.bin",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ m_debug.imbfile = fopen (m_debug.imbfile_name, "ab");
+ if (!m_debug.imbfile) {
+ DEBUG_PRINT_HIGH("Failed to open intermediate file: %s for logging", m_debug.log_loc);
+ m_debug.imbfile_name[0] = '\0';
+ return -1;
+ }
+ }
+
+ if (buffer && buffer->nFilledLen)
+ {
+ fwrite(&buffer->nFilledLen, sizeof(buffer->nFilledLen), 1, m_debug.imbfile);
+ fwrite(buffer->pBuffer, sizeof(uint8), buffer->nFilledLen, m_debug.imbfile);
+ }
+ return 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 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;
+
+ m_decoder_capability.min_width = 16;
+ m_decoder_capability.min_height = 16;
+ m_decoder_capability.max_width = 1920;
+ m_decoder_capability.max_height = 1080;
+ strlcpy(drv_ctx.kind,role,128);
+ OMX_STRING device_name = (OMX_STRING)"/dev/video/q6_dec";
+ if((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",
+ OMX_MAX_STRINGNAME_SIZE)) ||
+ (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevchybrid",
+ OMX_MAX_STRINGNAME_SIZE)))
+ {
+ drv_ctx.video_driver_fd = open(device_name, O_RDWR);
+ 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", errno);
+ return OMX_ErrorInsufficientResources;
+ }
+ DEBUG_PRINT_HIGH("omx_vdec::component_init(%s): Open device %s returned fd %d",
+ role, device_name, drv_ctx.video_driver_fd);
+ }
+ else
+ DEBUG_PRINT_HIGH("Omx_vdec::Comp Init for full SW hence skip Q6 open");
+
+ // Copy the role information which provides the decoder kind
+ strlcpy(drv_ctx.kind,role,128);
+ strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
+ if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevchybrid",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.width = 320;
+ fmt.fmt.pix_mp.height = 240;
+ fmt.fmt.pix_mp.pixelformat = V4L2_PIX_FMT_HEVC_HYBRID;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ if (ret) {
+ DEBUG_PRINT_HIGH("Failed to set format(V4L2_PIX_FMT_HEVC_HYBRID)");
+ DEBUG_PRINT_HIGH("Switch to HEVC fullDSP as HYBRID is not supported");
+ strlcpy(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", 128);
+ }
+ else {
+ DEBUG_PRINT_HIGH("HEVC HYBRID is supported");
+ }
+ }
+
+ if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevchybrid",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ DEBUG_PRINT_ERROR("HEVC Hybrid mode");
+ m_swvdec_mode = SWVDEC_MODE_DECODE_ONLY;
+ }
+ else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevcswvdec",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ DEBUG_PRINT_ERROR("HEVC Full SW mode");
+ maxSmoothStreamingWidth = 1280;
+ maxSmoothStreamingHeight = 720;
+ m_decoder_capability.max_width = 1280;
+ m_decoder_capability.max_height = 720;
+ m_swvdec_mode = SWVDEC_MODE_PARSE_DECODE;
+ }
+ else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ DEBUG_PRINT_ERROR("Full DSP mode");
+ maxSmoothStreamingWidth = 1280;
+ maxSmoothStreamingHeight = 720;
+ m_decoder_capability.max_width = 1280;
+ m_decoder_capability.max_height = 720;
+ m_swvdec_mode = -1;
+ }
+ else {
+ DEBUG_PRINT_ERROR("ERROR:Unknown Component");
+ return OMX_ErrorInvalidComponentName;
+ }
+
+ drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
+ eCompressionFormat = OMX_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);
+
+ update_resolution(1280, 720, 1280, 720);
+ 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("Setting color format failed");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
+ drv_ctx.frame_rate.fps_denominator = 1;
+ drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
+ drv_ctx.interm_op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
+ drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
+ if (secure_mode) {
+ drv_ctx.interm_op_buf.alignment=SZ_1M;
+ drv_ctx.op_buf.alignment=SZ_1M;
+ drv_ctx.ip_buf.alignment=SZ_1M;
+ } else {
+ drv_ctx.op_buf.alignment=SZ_4K;
+ drv_ctx.interm_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;
+
+ if (m_swvdec_mode >= 0)
+ {
+ // Init for SWCodec
+ DEBUG_PRINT_HIGH(":Initializing SwVdec mode %d", m_swvdec_mode);
+ memset(&sSwVdecParameter, 0, sizeof(SWVDEC_INITPARAMS));
+ sSwVdecParameter.sDimensions.nWidth = 1280;
+ sSwVdecParameter.sDimensions.nHeight = 720;
+ sSwVdecParameter.eDecType = SWVDEC_DECODER_HEVC;
+ sSwVdecParameter.eColorFormat = SWVDEC_FORMAT_NV12;
+ sSwVdecParameter.uProfile.eHevcProfile = SWVDEC_HEVC_MAIN_PROFILE;
+ sSwVdecParameter.sMode.eMode = (SWVDEC_MODE_TYPE)m_swvdec_mode;
+
+ //SWVDEC_CALLBACK m_callBackInfo;
+ m_callBackInfo.FillBufferDone = swvdec_fill_buffer_done_cb;
+ m_callBackInfo.EmptyBufferDone = swvdec_input_buffer_done_cb;
+ m_callBackInfo.HandleEvent = swvdec_handle_event_cb;
+ m_callBackInfo.pClientHandle = this;
+ SWVDEC_STATUS sRet = SwVdec_Init(&sSwVdecParameter, &m_callBackInfo, &m_pSwVdec);
+ if (sRet != SWVDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("SwVdec_Init returned %d, ret insufficient resources", sRet);
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ ret = pthread_create(&async_thread_id,0,async_message_thread,this);
+ if(ret < 0) {
+ close(drv_ctx.video_driver_fd);
+ DEBUG_PRINT_ERROR("Failed to create async_message_thread");
+ return OMX_ErrorInsufficientResources;
+ }
+ async_thread_created = true;
+
+ capture_capability= V4L2_PIX_FMT_NV12;
+ ret = subscribe_to_events(drv_ctx.video_driver_fd);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Subscribe Event Failed");
+ 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");
+ /*TODO: How to handle this case */
+ } else {
+ DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
+ " version = %d, capabilities = %x", 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", 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", fdesc.description,
+ fdesc.pixelformat, fdesc.flags);
+ fdesc.index++;
+ }
+
+ output_capability = V4L2_PIX_FMT_HEVC;
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ output_capability = V4L2_PIX_FMT_HEVC_HYBRID;
+ }
+ DEBUG_PRINT_HIGH("output_capability %d, V4L2_PIX_FMT_HEVC_HYBRID %d", output_capability, V4L2_PIX_FMT_HEVC_HYBRID);
+
+ 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");
+ return OMX_ErrorInsufficientResources;
+ }
+ DEBUG_PRINT_HIGH("Set Format was successful");
+ //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");
+ 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");
+ }
+ DEBUG_PRINT_HIGH("Set Format was successful");
+ 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", 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", ret);
+ close(drv_ctx.video_driver_fd);
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+
+ /*Get the Buffer requirements for input(input buffer) and output ports(intermediate buffer) from Q6*/
+ 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;
+ eRet=get_buffer_req(&drv_ctx.ip_buf);
+ DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
+ }
+ else if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ SWVDEC_PROP prop_dimen, prop_attr;
+
+ capture_capability = V4L2_PIX_FMT_NV12;
+ output_capability = V4L2_PIX_FMT_HEVC;
+
+ prop_dimen.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ prop_dimen.uProperty.sDimensions.nWidth = drv_ctx.video_resolution.frame_width;
+ prop_dimen.uProperty.sDimensions.nHeight = drv_ctx.video_resolution.frame_height;
+ ret = SwVdec_SetProperty(m_pSwVdec,&prop_dimen);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set dimensions to SwVdec in full SW");
+ return OMX_ErrorInsufficientResources;
+ }
+ DEBUG_PRINT_LOW("Set dimensions to SwVdec in full SW successful");
+ prop_attr.ePropId = SWVDEC_PROP_ID_FRAME_ATTR;
+ prop_attr.uProperty.sFrameAttr.eColorFormat = SWVDEC_FORMAT_NV12;
+ ret = SwVdec_SetProperty(m_pSwVdec,&prop_attr);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set color fmt to SwVdec in full SW");
+ return OMX_ErrorInsufficientResources;
+ }
+ DEBUG_PRINT_HIGH("Set dimensions and color format successful");
+
+ //TODO: Get the supported min/max dimensions of full SW solution
+
+ 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
+
+ get_buffer_req_swvdec();
+ DEBUG_PRINT_HIGH("Input Buffer Size %d Interm Buffer Size %d Output Buffer Size =%d",
+ drv_ctx.ip_buf.buffer_size, drv_ctx.interm_op_buf.buffer_size,
+ drv_ctx.op_buf.buffer_size);
+
+ 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("h264_scratch.pBuffer Allocation failed ");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ if(pipe(fds))
+ {
+ DEBUG_PRINT_ERROR("pipe creation failed");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ if(fds[0] == 0 || fds[1] == 0)
+ {
+ if (pipe (fds))
+ {
+ DEBUG_PRINT_ERROR("pipe creation failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ 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("component_init(): message_thread creation failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ msg_thread_created = true;
+ }
+
+ if (eRet != OMX_ErrorNone && ( (!m_pSwVdec) || (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) ))
+ {
+ DEBUG_PRINT_ERROR("Component Init Failed eRet %d m_pSwVdec %p m_swvdec_mode %d", eRet, m_pSwVdec, m_swvdec_mode);
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH("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
+ )
+{
+ (void) hComp;
+ (void) componentName;
+ (void) componentVersion;
+ (void) componentUUID;
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("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
+ )
+{
+ (void) hComp;
+ (void) cmdData;
+ DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("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("send_command(): ERROR OMX_CommandFlush "
+ "to invalid port: %lu", param1);
+ return OMX_ErrorBadPortIndex;
+ }
+ post_event((unsigned long)cmd,(unsigned long)param1,(unsigned long)OMX_COMPONENT_GENERATE_COMMAND);
+ sem_wait(&m_cmd_lock);
+ DEBUG_PRINT_LOW("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
+ )
+{
+ (void) hComp;
+ (void) cmdData;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_STATETYPE eState = (OMX_STATETYPE) param1;
+ int bFlag = 1,sem_posted = 0,ret=0;
+
+ DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
+ DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
+ 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))
+ {
+ if (m_pSwVdec && SWVDEC_S_SUCCESS != SwVdec_Start(m_pSwVdec))
+ {
+ DEBUG_PRINT_ERROR("SWVDEC failed to start in allocate_done");
+ return OMX_ErrorInvalidState;
+ }
+ DEBUG_PRINT_LOW("SwVdec start successful: 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("ERROR::send_command_proxy(): Loaded-->Loaded");
+ post_event((unsigned long)OMX_EventError,(unsigned long)OMX_ErrorSameState,\
+ (unsigned long)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");
+ post_event((unsigned long)OMX_EventError,(unsigned long)OMX_ErrorIncorrectStateTransition,\
+ (unsigned long)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");
+ post_event((unsigned long)OMX_EventError,(unsigned long)OMX_ErrorIncorrectStateTransition,\
+ (unsigned long)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");
+ post_event((unsigned long)OMX_EventError,(unsigned long)eState,(unsigned long)OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
+ 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
+ */
+ if (m_pSwVdec)
+ {
+ SwVdec_Stop(m_pSwVdec);
+ }
+ DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("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_LOW("send_command_proxy(): Idle-->Executing");
+ //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
+ bFlag = 1;
+ DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
+ m_state=OMX_StateExecuting;
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ fill_all_buffers_proxy_dsp(hComp);
+ }
+ DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
+ }
+ /* Requesting transition from Idle to Idle */
+ else if(eState == OMX_StateIdle)
+ {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
+ post_event((unsigned long)OMX_EventError,(unsigned long)OMX_ErrorSameState,\
+ (unsigned long)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");
+ post_event((unsigned long)OMX_EventError,(unsigned long)OMX_ErrorIncorrectStateTransition,\
+ (unsigned long)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("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");
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Idle to Invalid */
+ else if(eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
+ post_event((unsigned long)OMX_EventError,(unsigned long)eState,(unsigned long)OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ /******************************/
+ /* Current State is Executing */
+ /******************************/
+ else if(m_state == OMX_StateExecuting)
+ {
+ DEBUG_PRINT_LOW("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("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_LOW("PAUSE Command Issued");
+ m_state = OMX_StatePause;
+ bFlag = 1;
+ }
+ /* Requesting transition from Executing to Loaded */
+ else if(eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
+ 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("send_command_proxy(): Executing --> WaitForResources");
+ 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("send_command_proxy(): Executing --> Executing");
+ 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("send_command_proxy(): Executing --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",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("Pause --> Executing");
+ m_state = OMX_StateExecuting;
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ fill_all_buffers_proxy_dsp(hComp);
+ }
+ 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("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("Pause --> loaded");
+ 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("Pause --> WaitForResources");
+ 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("Pause --> Pause");
+ 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("Pause --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",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");
+ }
+ /* Requesting transition from WaitForResources to WaitForResources */
+ else if (eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
+ 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");
+ 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");
+ 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");
+ 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)",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");
+ 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: %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("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: %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");
+ 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("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");
+ 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: %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("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)",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 flushType %d", __func__, (int)flushType);
+ 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;
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ m_interm_flush_swvdec_progress = true;
+ m_interm_flush_dsp_progress = true;
+ }
+ break;
+ default:
+ input_flush_progress = true;
+ output_flush_progress = true;
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ m_interm_flush_swvdec_progress = true;
+ m_interm_flush_dsp_progress = true;
+ }
+ dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT |
+ V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
+ }
+
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ DEBUG_PRINT_LOW("flush dsp %d %d %d", 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("Flush dsp Failed ");
+ bRet = false;
+ }
+ }
+ if (flushType == OMX_CORE_INPUT_PORT_INDEX)
+ {
+ // no input flush independently, wait for output flush
+ return bRet;
+ }
+ if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ // for hybrid mode, swvdec flush will hapeen when dsp flush done is received
+ SWVDEC_BUFFER_FLUSH_TYPE aFlushType = SWVDEC_FLUSH_OUTPUT;
+ if (m_interm_flush_swvdec_progress || input_flush_progress)
+ {
+ aFlushType = SWVDEC_FLUSH_ALL;
+ }
+ DEBUG_PRINT_HIGH("Flush swvdec type %d", aFlushType);
+ if (SwVdec_Flush(m_pSwVdec, aFlushType) != SWVDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("Flush swvdec Failed ");
+ }
+ DEBUG_PRINT_LOW("Flush swvdec type %d successful", aFlushType);
+ }
+ 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 long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ /*Generate FBD for all Buffers in the FTBq*/
+ pthread_mutex_lock(&m_lock);
+ DEBUG_PRINT_LOW("Initiate Output Flush");
+ while (m_ftb_q.m_size)
+ {
+ DEBUG_PRINT_LOW("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("ID(%lx) P1(%lx) P2(%lx)", 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 int i =0;
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ /*Generate EBD for all Buffers in the ETBq*/
+ DEBUG_PRINT_LOW("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_LOW("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("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("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("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("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 long) pdest_frame, (unsigned long)NULL,
+ (unsigned long)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 long p1,
+ unsigned long p2,
+ unsigned long id)
+{
+ bool bRet = false;
+ OMX_BUFFERHEADERTYPE* bufHdr = NULL;
+
+ pthread_mutex_lock(&m_lock);
+
+ if (id == OMX_COMPONENT_GENERATE_FTB ||
+ 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 if (id == OMX_COMPONENT_GENERATE_FTB_DSP)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p2;
+ m_ftb_q_dsp.insert_entry(p1,p2,id);
+ }
+ else if (id == OMX_COMPONENT_GENERATE_ETB_SWVDEC)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p2;
+ m_etb_q_swvdec.insert_entry(p1,p2,id);
+ }
+ else if (id == OMX_COMPONENT_GENERATE_FBD_DSP)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p1;
+ m_ftb_q_dsp.insert_entry(p1,p2,id);
+ }
+ else if (id == OMX_COMPONENT_GENERATE_EBD_SWVDEC)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p1;
+ m_etb_q_swvdec.insert_entry(p1,p2,id);
+ }
+ else
+ {
+ m_cmd_q.insert_entry(p1,p2,id);
+ }
+
+ bRet = true;
+ 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.hevchybrid",OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevcswvdec",OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",OMX_MAX_STRINGNAME_SIZE) )
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
+ (int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu", profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu", profileLevelType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+omx_vdec::GetParameter
+
+DESCRIPTION
+OMX Get Parameter method implementation
+
+PARAMETERS
+<TBD>.
+
+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)
+{
+ (void) hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ DEBUG_PRINT_LOW("get_parameter:");
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Param in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+ if(paramData == NULL)
+ {
+ DEBUG_PRINT_LOW("Get Param in Invalid paramData");
+ 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");
+ 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");
+
+ 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");
+
+ 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");
+ 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");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
+ (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");
+ 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");
+ 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",
+ 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",
+ 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");
+ 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");
+
+ 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",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg2:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", 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");
+ 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 {
+ if (!m_pSwVdec) {
+#ifdef _HEVC_USE_ADSP_HEAP_
+ nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED);
+#else
+ nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
+#endif
+ }
+ else {
+ // for swvdec use cached buffer
+ DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage using output buffer cached");
+ // nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
+ nativeBuffersUsage->nUsage = (GRALLOC_USAGE_SW_READ_OFTEN |
+ GRALLOC_USAGE_SW_WRITE_OFTEN);
+ }
+ DEBUG_PRINT_HIGH("nativeBuffersUsage->nUsage %x", (unsigned int)nativeBuffersUsage->nUsage);
+ }
+ } else {
+ DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ break;
+#endif
+
+ default:
+ {
+ DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", 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<android_native_buffer_t> 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
+
+OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ 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.");
+ return OMX_ErrorHardware;
+ }
+ }
+ else if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ /* Full SW solution */
+ SWVDEC_PROP prop;
+ prop.ePropId = SWVDEC_PROP_ID_SMOOTH_STREAMING;
+ prop.uProperty.sSmoothStreaming.bEnableSmoothStreaming = TRUE;
+ if (SwVdec_SetProperty(m_pSwVdec, &prop))
+ {
+ DEBUG_PRINT_ERROR(
+ "OMX_QcomIndexParamVideoAdaptivePlaybackMode not supported");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+ DEBUG_PRINT_LOW("Smooth Streaming enabled.");
+ m_smoothstreaming_mode = true;
+ return OMX_ErrorNone;
+}
+
+
+/* ======================================================================
+FUNCTION
+omx_vdec::Setparameter
+
+DESCRIPTION
+OMX Set Parameter method implementation.
+
+PARAMETERS
+<TBD>.
+
+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");
+ return OMX_ErrorInvalidState;
+ }
+ if(paramData == NULL)
+ {
+ DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
+ 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");
+ 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",
+ (int)portDefn->format.video.nFrameHeight,
+ (int)portDefn->format.video.nFrameWidth);
+
+ // for pure dsp mode, if the dimension exceeds 720p, reject it
+ // so that the stagefright can try the hybrid component
+ if (!m_pSwVdec &&
+ (portDefn->format.video.nFrameHeight > 720 ||
+ portDefn->format.video.nFrameWidth > 1280))
+ {
+ DEBUG_PRINT_ERROR("Full DSP mode only support up to 720p");
+ return OMX_ErrorBadParameter;
+ }
+
+ 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 (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE) {
+ SWVDEC_PROP prop;
+ SWVDEC_STATUS sRet;
+ prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ prop.uProperty.sDimensions.nWidth =
+ portDefn->format.video.nFrameWidth;
+ prop.uProperty.sDimensions.nHeight =
+ portDefn->format.video.nFrameHeight;
+ sRet = SwVdec_SetProperty(m_pSwVdec,&prop);
+ if(sRet!=SWVDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("set_parameter: SwVdec_SetProperty():Failed to set dimensions to SwVdec in full SW");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+ if (!client_buffers.get_buffer_req(buffer_size)) {
+ DEBUG_PRINT_ERROR("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_swvdec(&drv_ctx.op_buf);
+ if (eRet == OMX_ErrorNone)
+ m_port_def = *portDefn;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)",
+ drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
+ portDefn->nBufferCountActual, portDefn->nBufferSize);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ }
+ else if(OMX_DirInput == portDefn->eDir)
+ {
+ bool port_format_changed = false;
+ 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)",
+ (unsigned int)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)",
+ (int)portDefn->format.video.nFrameWidth,
+ (int)portDefn->format.video.nFrameHeight);
+ port_format_changed = true;
+ OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
+ OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
+ if (frameHeight != 0x0 && frameWidth != 0x0)
+ {
+ if (m_smoothstreaming_mode &&
+ ((frameWidth * frameHeight) <
+ (m_smoothstreaming_width * m_smoothstreaming_height))) {
+ frameWidth = m_smoothstreaming_width;
+ frameHeight = m_smoothstreaming_height;
+ DEBUG_PRINT_LOW("NOTE: Setting resolution %lu x %lu for adaptive-playback/smooth-streaming",
+ frameWidth, frameHeight);
+ }
+ update_resolution(frameWidth, frameHeight,
+ frameWidth, frameHeight);
+ if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ /* update the stride info */
+ drv_ctx.video_resolution.stride =
+ (frameWidth + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
+ drv_ctx.video_resolution.scan_lines =
+ (frameHeight + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
+ }
+
+ eRet = is_video_session_supported();
+ if (eRet)
+ break;
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ 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("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
+ 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("Set Resolution failed h %d w %d", fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+ }
+ if (m_pSwVdec)
+ {
+ SWVDEC_PROP prop;
+ prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ prop.uProperty.sDimensions.nWidth = drv_ctx.video_resolution.frame_width;
+ prop.uProperty.sDimensions.nHeight= drv_ctx.video_resolution.frame_height;
+ SwVdec_SetProperty(m_pSwVdec,&prop);
+ prop.ePropId = SWVDEC_PROP_ID_FRAME_ATTR;
+ prop.uProperty.sFrameAttr.eColorFormat = SWVDEC_FORMAT_NV12;
+ ret = SwVdec_SetProperty(m_pSwVdec,&prop);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set color fmt to SwVdec in full SW");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ eRet = get_buffer_req_swvdec();
+ }
+ }
+ else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
+ || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)
+ {
+ port_format_changed = true;
+ 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));
+ DEBUG_PRINT_LOW("IP Requirements(#%d: %u) Requested(#%lu: %lu)",
+ drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
+ portDefn->nBufferCountActual, portDefn->nBufferSize);
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ eRet = set_buffer_req(buffer_prop);
+ }
+ if (!port_format_changed)
+ {
+ DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)",
+ 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",
+ 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;
+ if (!m_pSwVdec)
+ {
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ }
+ else if ((m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE) ||
+ (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY))
+ {
+ SWVDEC_PROP prop;
+ prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ prop.uProperty.sDimensions.nWidth = fmt.fmt.pix_mp.width;
+ prop.uProperty.sDimensions.nHeight= fmt.fmt.pix_mp.height;
+ SwVdec_SetProperty(m_pSwVdec,&prop);
+ prop.ePropId = SWVDEC_PROP_ID_FRAME_ATTR;
+ prop.uProperty.sFrameAttr.eColorFormat = SWVDEC_FORMAT_NV12;
+ SwVdec_SetProperty(m_pSwVdec,&prop);
+ }
+ // need to set output format to swvdec
+ if(ret)
+ {
+ DEBUG_PRINT_ERROR("Set output format failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ /*TODO: How to handle this case */
+ }
+ else
+ {
+ eRet = get_buffer_req_swvdec();
+ }
+ }
+ if (eRet == OMX_ErrorNone){
+ if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
+ DEBUG_PRINT_ERROR("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",
+ (int)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",
+ 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: out pmem set");
+ 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");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevchybrid",OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevcswvdec",OMX_MAX_STRINGNAME_SIZE) ||
+ !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", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+ break;
+ }
+
+ case OMX_IndexParamPriorityMgmt:
+ {
+ if(m_state != OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d",
+ (int)priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d",
+ (int)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",
+ bufferSupplierType->eBufferSupplier);
+ if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
+ m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
+
+ else
+
+ eRet = OMX_ErrorBadPortIndex;
+
+ break;
+
+ }
+ case OMX_IndexParamVideoAvc:
+ case OMX_IndexParamVideoH263:
+ case OMX_IndexParamVideoMpeg4:
+ case OMX_IndexParamVideoMpeg2:
+ {
+ eRet = OMX_ErrorUnsupportedSetting;
+ 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",
+ 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)
+ {
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) {
+ 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("Set picture order failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ // if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ // TODO
+ }
+ }
+ break;
+ }
+ case OMX_QcomIndexParamConcealMBMapExtraData:
+ if(!secure_mode)
+ eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ else {
+ DEBUG_PRINT_ERROR("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("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("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("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");
+ 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");
+ m_use_output_pmem = OMX_TRUE;
+ }
+ }
+
+ }
+ break;
+ case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
+ {
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) {
+ 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("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("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("Sync frame setting failed: falied to get buffer i/p requirements");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ if (!m_pSwVdec) { // for full dsp mode
+ if (get_buffer_req(&drv_ctx.op_buf)) {
+ DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else if (get_buffer_req(&drv_ctx.interm_op_buf)) { // for hybrid
+ DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p 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");
+ eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
+
+ }
+ }
+ }
+ break;
+ case OMX_QcomIndexParamEnableSmoothStreaming:
+ {
+#ifndef SMOOTH_STREAMING_DISABLED
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) {
+ eRet = enable_smoothstreaming();
+ }
+#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_QcomIndexParamVideoMetaBufferMode:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoMetaBufferMode");
+ if (m_disable_dynamic_buf_mode) {
+ DEBUG_PRINT_HIGH("Dynamic buffer mode disabled by setprop");
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+ StoreMetaDataInBuffersParams *metabuffer =
+ (StoreMetaDataInBuffersParams *)paramData;
+ if (!metabuffer) {
+ DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
+ if (m_pSwVdec == NULL) {
+ //set property dynamic buffer mode to driver.
+ struct v4l2_control control;
+ struct v4l2_format fmt;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
+ if (metabuffer->bStoreMetaData == true) {
+ control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
+ } else {
+ control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
+ }
+ int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
+ if (!rc) {
+ DEBUG_PRINT_HIGH(" %s buffer mode",
+ (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
+ dynamic_buf_mode = metabuffer->bStoreMetaData;
+ } else {
+ DEBUG_PRINT_ERROR("Failed to %s buffer mode",
+ (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
+ dynamic_buf_mode = false;
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else { // for hybrid codec
+ DEBUG_PRINT_HIGH(" %s buffer mode",
+ (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
+ dynamic_buf_mode = metabuffer->bStoreMetaData;
+ if (dynamic_buf_mode) {
+ SWVDEC_PROP prop;
+ prop.ePropId = SWVDEC_PROP_ID_BUFFER_ALLOC_MODE;
+ prop.uProperty.sBufAllocMode.eBufAllocMode = SWVDEC_BUF_ALLOC_MODE_DYNAMIC;
+ if (SwVdec_SetProperty(m_pSwVdec, &prop))
+ {
+ DEBUG_PRINT_ERROR(
+ "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
+ metabuffer->nPortIndex);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW(
+ "OMX_QcomIndexParamVideoMetaBufferMode supported for port: %lu",
+ metabuffer->nPortIndex);
+ }
+ }
+ }
+ } else {
+ DEBUG_PRINT_ERROR(
+ "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %lu",
+ metabuffer->nPortIndex);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ break;
+#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
+ case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
+ PrepareForAdaptivePlaybackParams* pParams =
+ (PrepareForAdaptivePlaybackParams *) paramData;
+ if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
+ if (!pParams->bEnable) {
+ return OMX_ErrorNone;
+ }
+ if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
+ || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
+ DEBUG_PRINT_ERROR(
+ "Adaptive playback request exceeds max supported resolution : [%lu x %lu] vs [%lu x %lu]",
+ pParams->nMaxFrameWidth, pParams->nMaxFrameHeight,
+ maxSmoothStreamingWidth, maxSmoothStreamingHeight);
+ eRet = OMX_ErrorBadParameter;
+ } else
+ {
+ eRet = enable_smoothstreaming();
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
+ eRet = OMX_ErrorHardware;
+ } else {
+ DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
+ pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
+ m_smoothstreaming_mode = true;
+ m_smoothstreaming_width = pParams->nMaxFrameWidth;
+ m_smoothstreaming_height = pParams->nMaxFrameHeight;
+ }
+ struct v4l2_format fmt;
+ update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
+ m_smoothstreaming_width, m_smoothstreaming_height);
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ 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("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
+ 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("Set Resolution failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ } else
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+ }
+ else if (SWVDEC_MODE_PARSE_DECODE == m_swvdec_mode)
+ {
+ SWVDEC_PROP prop;
+ SWVDEC_STATUS sRet;
+ /* set QCIF resolution to get UpperLimit_bufferCount */
+ prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ prop.uProperty.sDimensions.nWidth = 176;
+ prop.uProperty.sDimensions.nHeight= 144;
+ sRet = SwVdec_SetProperty(m_pSwVdec,&prop);
+ if (SWVDEC_S_SUCCESS != sRet)
+ {
+ DEBUG_PRINT_ERROR("SwVdec_SetProperty failed (%d)", sRet);
+ eRet = OMX_ErrorUndefined;
+ break;
+ }
+
+ prop.ePropId = SWVDEC_PROP_ID_OPBUFFREQ;
+ sRet = SwVdec_GetProperty(m_pSwVdec, &prop);
+ if (SWVDEC_S_SUCCESS == sRet)
+ {
+ drv_ctx.op_buf.actualcount = prop.uProperty.sOpBuffReq.nMinCount;
+ drv_ctx.op_buf.mincount = prop.uProperty.sOpBuffReq.nMinCount;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("SwVdec_GetProperty failed (%d)", sRet);
+ eRet = OMX_ErrorUndefined;
+ break;
+ }
+
+ /* set the max smooth-streaming resolution to get the buffer size */
+ prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ prop.uProperty.sDimensions.nWidth = m_smoothstreaming_width;
+ prop.uProperty.sDimensions.nHeight= m_smoothstreaming_height;
+ SwVdec_SetProperty(m_pSwVdec,&prop);
+ if (SWVDEC_S_SUCCESS != sRet)
+ {
+ DEBUG_PRINT_ERROR("SwVdec_SetProperty failed (%d)", sRet);
+ eRet = OMX_ErrorUndefined;
+ break;
+ }
+
+ prop.ePropId = SWVDEC_PROP_ID_OPBUFFREQ;
+ sRet = SwVdec_GetProperty(m_pSwVdec, &prop);
+ if (SWVDEC_S_SUCCESS == sRet)
+ {
+ int client_extra_data_size = 0;
+ 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)
+ {
+ DEBUG_PRINT_HIGH("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",
+ client_extra_data_size);
+ }
+ if (client_extra_data_size)
+ {
+ client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
+ }
+ drv_ctx.op_buf.buffer_size = prop.uProperty.sOpBuffReq.nSize + client_extra_data_size;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("SwVdec_GetProperty failed (%d)", sRet);
+ eRet = OMX_ErrorUndefined;
+ break;
+ }
+
+ /* set the buffer requirement to sw vdec */
+ prop.uProperty.sOpBuffReq.nSize = drv_ctx.op_buf.buffer_size;
+ prop.uProperty.sOpBuffReq.nMaxCount = drv_ctx.op_buf.actualcount;
+ prop.uProperty.sOpBuffReq.nMinCount = drv_ctx.op_buf.mincount;
+
+ prop.ePropId = SWVDEC_PROP_ID_OPBUFFREQ;
+ sRet = SwVdec_SetProperty(m_pSwVdec, &prop);
+ if (SWVDEC_S_SUCCESS != sRet)
+ {
+ DEBUG_PRINT_ERROR("SwVdec_SetProperty failed (%d)", sRet);
+ eRet = OMX_ErrorUndefined;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR(
+ "Prepare for adaptive playback supported only on output port");
+ eRet = OMX_ErrorBadParameter;
+ }
+ break;
+ }
+#endif
+ default:
+ {
+ DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+omx_vdec::GetConfig
+
+DESCRIPTION
+OMX Get Config Method implementation.
+
+PARAMETERS
+<TBD>.
+
+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)
+{
+ (void) hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Config in Invalid State");
+ 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");
+ eRet = OMX_ErrorNoMore;
+ }
+
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
+ (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:
+ {
+ 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",configIndex);
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ }
+
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+omx_vdec::SetConfig
+
+DESCRIPTION
+OMX Set Config method implementation
+
+PARAMETERS
+<TBD>.
+
+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)
+{
+ (void) hComp;
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Config in Invalid State");
+ 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");
+ return ret;
+ }
+
+ if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData)
+ {
+ OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
+ DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
+ 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. <TBD>
+
+PARAMETERS
+<TBD>.
+
+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)
+{
+ (void) hComp;
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
+ 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", 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 if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
+ }
+#if ADAPTIVE_PLAYBACK_SUPPORTED
+ else if (!strncmp(paramName, "OMX.google.android.index.prepareForAdaptivePlayback", sizeof("OMX.google.android.index.prepareForAdaptivePlayback") -1)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
+ }
+#endif
+ else {
+ DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
+ return OMX_ErrorNotImplemented;
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+omx_vdec::GetState
+
+DESCRIPTION
+Returns the state information back to the caller.<TBD>
+
+PARAMETERS
+<TBD>.
+
+RETURN VALUE
+Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STATETYPE* state)
+{
+ (void) hComp;
+ *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. <TBD>
+
+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)
+{
+ (void) hComp;
+ (void) port;
+ (void) peerComponent;
+ (void) peerPort;
+ (void) tunnelSetup;
+ DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
+ 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", drv_ctx.extradata_info.size);
+ int heap = 0;
+#ifdef _HEVC_USE_ADSP_HEAP_
+ heap = ION_ADSP_HEAP_ID;
+#else
+ heap = ION_IOMMU_HEAP_ID;
+#endif
+ 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, heap);
+ if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
+ DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
+ 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");
+ 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;
+ (void) hComp;
+ (void) port;
+
+ if (!m_out_mem_ptr) {
+ DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
+ eRet = allocate_output_headers();
+ if (!m_pSwVdec && 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", drv_ctx.op_buf.actualcount);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ if (dynamic_buf_mode) {
+ if (m_pSwVdec && !m_pSwVdecOpBuffer)
+ {
+ SWVDEC_PROP prop;
+ DEBUG_PRINT_HIGH("allocating m_pSwVdecOpBuffer %d", drv_ctx.op_buf.actualcount);
+ m_pSwVdecOpBuffer = (SWVDEC_OPBUFFER*)calloc(sizeof(SWVDEC_OPBUFFER), drv_ctx.op_buf.actualcount);
+ }
+
+ *bufferHdr = (m_out_mem_ptr + i );
+ (*bufferHdr)->pBuffer = NULL;
+ // for full dsp mode
+ if (!m_pSwVdec && i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
+ enum v4l2_buf_type buf_type;
+ int rr = 0;
+ buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
+ DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
+ return OMX_ErrorInsufficientResources;
+ } else {
+ streaming[CAPTURE_PORT] = true;
+ DEBUG_PRINT_LOW("STREAMON Successful");
+ }
+ }
+ BITMASK_SET(&m_out_bm_count,i);
+ (*bufferHdr)->pAppPrivate = appData;
+ (*bufferHdr)->pBuffer = buffer;
+ (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
+
+ // SWVdec memory allocation and set the output buffer
+ if (m_pSwVdecOpBuffer) {
+ m_pSwVdecOpBuffer[i].nSize = sizeof(struct VideoDecoderOutputMetaData);
+ m_pSwVdecOpBuffer[i].pBuffer = buffer;
+ m_pSwVdecOpBuffer[i].pClientBufferData = (void*)(unsigned long)i;
+ }
+
+ return eRet;
+ }
+
+ 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<android_native_buffer_t> 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;
+ drv_ctx.op_buf_ion_info[i].fd_ion_data.fd = handle->fd;
+ //drv_ctx.op_buf_ion_info[i].fd_ion_data.handle = (ion_user_handle_t)handle;
+ DEBUG_PRINT_HIGH("Native Buffer vaddr %p, idx %d fd %d len %d", buff,i, handle->fd , 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", 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", 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", 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", 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("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");
+ 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("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("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",
+ (unsigned int)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("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 );
+
+ if (m_pSwVdec)
+ {
+ if (m_pSwVdecOpBuffer == NULL)
+ {
+ DEBUG_PRINT_HIGH("allocating m_pSwVdecOpBuffer %d", drv_ctx.op_buf.actualcount);
+ m_pSwVdecOpBuffer = (SWVDEC_OPBUFFER*)calloc(sizeof(SWVDEC_OPBUFFER), drv_ctx.op_buf.actualcount);
+ }
+
+ // SWVdec memory allocation and set the output buffer
+ m_pSwVdecOpBuffer[i].nSize = drv_ctx.ptr_outputbuffer[i].mmaped_size;
+ m_pSwVdecOpBuffer[i].pBuffer = (uint8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
+ m_pSwVdecOpBuffer[i].pClientBufferData = (void*)(unsigned long)i;
+ if (SWVDEC_S_SUCCESS !=SwVdec_SetOutputBuffer(m_pSwVdec, &m_pSwVdecOpBuffer[i]))
+ {
+ DEBUG_PRINT_HIGH("SwVdec_SetOutputBuffer failed in use_output_buffer");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ int extra_idx = 0;
+ 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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+ buf.m.planes = plane;
+ buf.length = drv_ctx.num_planes;
+
+ DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
+
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
+ DEBUG_PRINT_ERROR("Failed to prepare bufs");
+ /*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("STREAMON Successful");
+ }
+ }
+ }
+
+ (*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
+<TBD>.
+
+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 long)m_phdr_pmem_ptr[m_in_alloc_cnt],
+ (unsigned long)NULL, (unsigned long)NULL))
+ {
+ DEBUG_PRINT_ERROR("ERROR: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
+<TBD>.
+
+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");
+ 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",(int)port);
+ error = OMX_ErrorBadPortIndex;
+ }
+ DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
+ if(error == OMX_ErrorNone)
+ {
+ if(allocate_done())
+ {
+ DEBUG_PRINT_LOW("Use Buffer: 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 (m_pSwVdec)
+ {
+ DEBUG_PRINT_LOW("Use Buffer: SwVdec_Start");
+ SwVdec_Start(m_pSwVdec);
+ }
+ }
+ 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_setbuffer_cmd setbuffers;
+ setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
+ memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
+ sizeof (vdec_bufferpayload));
+ 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 = %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("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 = %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(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("unmap the output buffer fd = %d",
+ drv_ctx.ptr_outputbuffer[0].pmem_fd);
+ DEBUG_PRINT_LOW("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("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;
+ 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 long)m_phdr_pmem_ptr[i],
+ (unsigned long)NULL, (unsigned long)NULL))
+ {
+ DEBUG_PRINT_ERROR("ERROR: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;
+ (void) hComp;
+ (void) port;
+
+ if(bytes != drv_ctx.ip_buf.buffer_size)
+ {
+ DEBUG_PRINT_LOW("Requested Size is wrong %d epected is %d",
+ (int)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
+ }
+
+ if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ // allocate swvdec input buffers
+ m_pSwVdecIpBuffer = (SWVDEC_IPBUFFER *)calloc(sizeof(SWVDEC_IPBUFFER), drv_ctx.ip_buf.actualcount);
+ if (m_pSwVdecIpBuffer == NULL) {
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ }
+
+ 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)
+ {
+#ifdef USE_ION
+ int heap = 0;
+#ifdef _HEVC_USE_ADSP_HEAP_
+ heap = ION_ADSP_HEAP_ID;
+#else
+ heap = ION_IOMMU_HEAP_ID;
+#endif
+ DEBUG_PRINT_HIGH("Allocate ion input Buffer size %d", 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, heap);
+ 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("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("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("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("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;
+
+ if (!m_pSwVdec || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc;
+ 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("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");
+ /*TODO: How to handle this case */
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ m_pSwVdecIpBuffer[i].pBuffer = buf_addr;
+ m_pSwVdecIpBuffer[i].pClientBufferData = (void*)(unsigned long)i;
+ }
+
+ input = *bufferHdr;
+ BITMASK_SET(&m_inp_bm_count,i);
+ DEBUG_PRINT_LOW("Buffer address %p of pmem idx %d",*bufferHdr, i);
+ if (secure_mode)
+ input->pBuffer = (OMX_U8 *)(unsigned long)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("ERROR:Input Buffer Index not found");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+omx_vdec::AllocateOutputBuffer
+
+DESCRIPTION
+Helper fn for AllocateBuffer in the output pin
+
+PARAMETERS
+<TBD>.
+
+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)
+{
+ (void)hComp;
+ (void)port;
+ 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("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)",
+ 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);
+#ifdef USE_ION
+ DEBUG_PRINT_HIGH("allocate outputBuffer size %d",drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount);
+ int heap_id = 0;
+ int flags = secure_mode ? ION_SECURE : 0;
+ if (!m_pSwVdec) {
+#ifdef _HEVC_USE_ADSP_HEAP_
+ heap_id = ION_ADSP_HEAP_ID;
+#else
+ heap_id = ION_IOMMU_HEAP_ID;
+#endif
+ }
+ 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,flags, heap_id);
+ 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("ERROR: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("ERROR: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("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("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_pSwVdec && m_pSwVdecOpBuffer == NULL)
+ {
+ m_pSwVdecOpBuffer = (SWVDEC_OPBUFFER*)calloc(sizeof(SWVDEC_OPBUFFER), drv_ctx.op_buf.actualcount);
+ }
+ if(m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer && drv_ctx.ptr_respbuffer
+ && ((m_pSwVdec && m_pSwVdecOpBuffer) || (!m_pSwVdec)) )
+ {
+ 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 = 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",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("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]",\
+ 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;
+ }
+ if ( (!m_pSwVdec) && (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("Found a Free Output Buffer %d",i);
+ break;
+ }
+ }
+
+ if (eRet == OMX_ErrorNone)
+ {
+ if(i < drv_ctx.op_buf.actualcount)
+ {
+ 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;
+
+ if (m_pSwVdec)
+ {
+ (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
+ (*bufferHdr)->pAppPrivate = appData;
+ m_pSwVdecOpBuffer[i].nSize = drv_ctx.ptr_outputbuffer[i].mmaped_size;
+ m_pSwVdecOpBuffer[i].pBuffer = (*bufferHdr)->pBuffer;
+ m_pSwVdecOpBuffer[i].pClientBufferData = (void*)(unsigned long)i;
+ SwVdec_SetOutputBuffer(m_pSwVdec, &m_pSwVdecOpBuffer[i]);
+ }
+ else
+ {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ 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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+ buf.m.planes = plane;
+ buf.length = drv_ctx.num_planes;
+ DEBUG_PRINT_LOW("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("STREAMON Successful");
+ }
+ }
+ }
+ (*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");
+ 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");
+ 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",(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 (m_pSwVdec)
+ {
+ DEBUG_PRINT_LOW("allocate_buffer: SwVdec_Start");
+ SwVdec_Start(m_pSwVdec);
+ }
+ }
+ 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;
+ (void) hComp;
+
+ 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", (int)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", (int)port);
+ }
+ else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
+ {
+ DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
+ post_event(OMX_EventError,
+ OMX_ErrorPortUnpopulated,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ else if (m_state != OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Invalid state %d to free buffer,port %d lost Buffers", m_state, (int)port);
+ 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");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
+ && release_input_done())
+ {
+ DEBUG_PRINT_LOW("MOVING TO INPUT 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();
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ DEBUG_PRINT_LOW("release_output_done: start free_interm_buffers");
+ free_interm_buffers();
+ }
+ else if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ DEBUG_PRINT_LOW("free m_pSwVdecOpBuffer");
+ if (m_pSwVdecOpBuffer)
+ {
+ free(m_pSwVdecOpBuffer);
+ m_pSwVdecOpBuffer = NULL;
+ }
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
+ && release_output_done())
+ {
+ DEBUG_PRINT_LOW("MOVING TO OUTPUT 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);
+ if (m_pSwVdec)
+ {
+ SwVdec_Stop(m_pSwVdec);
+ }
+ 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");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_inp_bEnabled)
+ {
+ DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
+ {
+ DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)
+ {
+ codec_config_flag = true;
+ DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
+ }
+
+ 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("ERROR:ETB nBufferIndex is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu) nFlags(%lu)",
+ buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen, buffer->nFlags);
+ if (arbitrary_bytes)
+ {
+ post_event ((unsigned long)hComp,(unsigned long)buffer,
+ (unsigned long)OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
+ }
+ else
+ {
+ if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
+ set_frame_rate(buffer->nTimeStamp);
+ post_event ((unsigned long)hComp,(unsigned long)buffer,
+ (unsigned long)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("ERROR: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("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
+ nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY && m_fill_internal_bufers)
+ {
+ fill_all_buffers_proxy_dsp(hComp);
+ }
+
+ 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 long)buffer,(unsigned long)VDEC_S_SUCCESS,
+ (unsigned long)OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorNone;
+ }
+
+ if(input_flush_progress == true
+
+ || not_coded_vop
+
+ )
+ {
+ DEBUG_PRINT_LOW("Flush in progress return buffer ");
+ post_event ((unsigned long)buffer, (unsigned long)VDEC_S_SUCCESS,
+ (unsigned long)OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorNone;
+ }
+
+ temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
+
+ if ((temp_buffer - drv_ctx.ptr_inputbuffer) > (int)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", (int)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
+
+ if (m_debug.in_buffer_log)
+ {
+ log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
+ }
+
+ 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;
+ }
+
+ if ( (!m_pSwVdec) || (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) )
+ {
+ 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_QCOM_BUF_FLAG_EOS;
+ DEBUG_PRINT_HIGH("INPUT EOS reached") ;
+ }
+ 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");
+ return OMX_ErrorHardware;
+ }
+ codec_config_flag = false;
+ DEBUG_PRINT_LOW("%s: codec_config cleared", __FUNCTION__);
+ 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");
+ ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
+ if(!ret) {
+ DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
+ streaming[OUTPUT_PORT] = true;
+ } else {
+ /*TODO: How to handle this case */
+ DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
+ DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
+ post_event ((unsigned long)buffer,(unsigned long)VDEC_S_SUCCESS,
+ (unsigned long)OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorBadParameter;
+ }
+ }
+ }
+ else if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ // send this to the swvdec
+ DEBUG_PRINT_HIGH("empty_this_buffer_proxy bufHdr %p pBuffer %p nFilledLen %lu m_pSwVdecIpBuffer %p, idx %d",
+ buffer, buffer->pBuffer, buffer->nFilledLen, m_pSwVdecIpBuffer, nPortIndex);
+ m_pSwVdecIpBuffer[nPortIndex].nFlags = buffer->nFlags;
+ m_pSwVdecIpBuffer[nPortIndex].nFilledLen = buffer->nFilledLen;
+ m_pSwVdecIpBuffer[nPortIndex].nIpTimestamp = buffer->nTimeStamp;
+
+ if (SwVdec_EmptyThisBuffer(m_pSwVdec, &m_pSwVdecIpBuffer[nPortIndex]) != SWVDEC_S_SUCCESS) {
+ ret = OMX_ErrorBadParameter;
+ }
+ codec_config_flag = false;
+ DEBUG_PRINT_LOW("%s: codec_config cleared", __FUNCTION__);
+ }
+
+ 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)
+{
+ unsigned int nPortIndex = (unsigned int)(buffer - client_buffers.get_il_buf_hdr());
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("FTB in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (!m_out_bEnabled)
+ {
+ DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (!buffer || !buffer->pBuffer || nPortIndex >= drv_ctx.op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("ERROR:FTB invalid bufHdr %p, nPortIndex %u", buffer, nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
+ {
+ DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (dynamic_buf_mode) {
+ private_handle_t *handle = NULL;
+ struct VideoDecoderOutputMetaData *meta;
+ OMX_U8 *buff = NULL;
+
+ //get the buffer type and fd info
+ meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
+ handle = (private_handle_t *)meta->pHandle;
+ DEBUG_PRINT_LOW("FTB: buftype: %d bufhndl: %p", meta->eType, meta->pHandle);
+
+ pthread_mutex_lock(&m_lock);
+ if (out_dynamic_list[nPortIndex].ref_count == 0) {
+
+ //map the buffer handle based on the size set on output port definition.
+ if (!secure_mode) {
+ buff = (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
+ PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
+ } else {
+ buff = (OMX_U8*) buffer;
+ }
+
+ drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
+ drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
+ drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = buff;
+ drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
+ drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
+ DEBUG_PRINT_LOW("fill_this_buffer: bufHdr %p idx %d mapped pBuffer %p size %u", buffer, nPortIndex, buff, drv_ctx.op_buf.buffer_size);
+ if (m_pSwVdecOpBuffer) {
+ m_pSwVdecOpBuffer[nPortIndex].nSize = drv_ctx.op_buf.buffer_size;
+ m_pSwVdecOpBuffer[nPortIndex].pBuffer = buff;
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+ buf_ref_add(nPortIndex, drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
+ drv_ctx.ptr_outputbuffer[nPortIndex].offset);
+ }
+
+ DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
+ post_event((unsigned long) hComp, (unsigned long)buffer, (unsigned long)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)
+{
+ (void)hComp;
+ 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)
+ {
+ DEBUG_PRINT_ERROR("FTBProxy: bufhdr = %p, il = %p, nPortIndex %u bufCount %u",
+ bufferAdd, ((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr()),nPortIndex, 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;
+ }
+
+ if (m_pSwVdec)
+ {
+ DEBUG_PRINT_HIGH("SwVdec_FillThisBuffer idx %d, bufHdr %p pBuffer %p", nPortIndex,
+ bufferAdd, m_pSwVdecOpBuffer[nPortIndex].pBuffer);
+ if (SWVDEC_S_SUCCESS != SwVdec_FillThisBuffer(m_pSwVdec, &m_pSwVdecOpBuffer[nPortIndex]))
+ {
+ DEBUG_PRINT_ERROR("SwVdec_FillThisBuffer failed");
+ }
+ }
+ else
+ {
+ 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", 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");
+ }
+ }
+ 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)
+{
+ (void)hComp;
+ 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
+<TBD>.
+
+RETURN VALUE
+OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ (void)hComp;
+
+ unsigned i = 0;
+ if (OMX_StateLoaded != m_state)
+ {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
+ m_state);
+ DEBUG_PRINT_ERROR("Playback Ended - FAILED");
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH("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");
+ for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
+ {
+ free_output_buffer (&m_out_mem_ptr[i]);
+ }
+#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; i<drv_ctx.ip_buf.actualcount; i++ )
+ {
+ if (m_inp_mem_ptr)
+ free_input_buffer (i,&m_inp_mem_ptr[i]);
+ else
+ free_input_buffer (i,NULL);
+ }
+ }
+ free_input_buffer_header();
+ free_output_buffer_header();
+ if(h264_scratch.pBuffer)
+ {
+ free(h264_scratch.pBuffer);
+ h264_scratch.pBuffer = NULL;
+ }
+
+ if (h264_parser)
+ {
+ delete h264_parser;
+ h264_parser = NULL;
+ }
+
+ if(m_platform_list)
+ {
+ free(m_platform_list);
+ m_platform_list = NULL;
+ }
+ if(m_vendor_config.pData)
+ {
+ free(m_vendor_config.pData);
+ m_vendor_config.pData = NULL;
+ }
+
+ // Reset counters in mesg queues
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+ m_ftb_q_dsp.m_size=0;
+ m_etb_q_swvdec.m_size=0;
+ m_ftb_q_dsp.m_read = m_ftb_q_dsp.m_write =0;
+ m_etb_q_swvdec.m_read = m_etb_q_swvdec.m_write =0;
+#ifdef _ANDROID_
+ if (m_debug_timestamp)
+ {
+ m_timestamp_list.reset_ts_list();
+ }
+#endif
+
+ if (m_debug.infile) {
+ fclose(m_debug.infile);
+ m_debug.infile = NULL;
+ }
+ if (m_debug.outfile) {
+ fclose(m_debug.outfile);
+ m_debug.outfile = NULL;
+ }
+ if (m_debug.imbfile) {
+ fclose(m_debug.imbfile);
+ m_debug.imbfile = NULL;
+ }
+
+ if (m_pSwVdec)
+ {
+ SwVdec_DeInit(m_pSwVdec);
+ m_pSwVdec = NULL;
+ }
+ DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+omx_vdec::UseEGLImage
+
+DESCRIPTION
+OMX Use EGL Image method implementation <TBD>.
+
+PARAMETERS
+<TBD>.
+
+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;
+ (void)appData;
+
+#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("use_EGL_image: Invalid param");
+ }
+#ifdef USE_EGL_IMAGE_GPU
+ if(m_display_id == NULL) {
+ DEBUG_PRINT_ERROR("Display ID is not set by IL client");
+ 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",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");
+ return OMX_ErrorInsufficientResources;
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+omx_vdec::ComponentRoleEnum
+
+DESCRIPTION
+OMX Component Role Enum method implementation.
+
+PARAMETERS
+<TBD>.
+
+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;
+ (void)hComp;
+
+ if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevchybrid",OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevcswvdec",OMX_MAX_STRINGNAME_SIZE) ||
+ !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",role);
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("No more roles");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: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;
+ if (m_pSwVdec && m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ if (allocate_interm_buffer(drv_ctx.interm_op_buf.buffer_size) != OMX_ErrorNone)
+ {
+ omx_report_error();
+ bRet = false;
+ }
+ }
+ }
+
+ 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.ip_buf.actualcount;i++)
+ {
+ if(BITMASK_ABSENT(&m_inp_bm_count,i))
+ {
+ break;
+ }
+ }
+ }
+ if(i == drv_ctx.ip_buf.actualcount)
+ {
+ bRet = true;
+ DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
+ }
+ if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
+ {
+ m_inp_bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+omx_vdec::AllocateOutputDone
+
+DESCRIPTION
+Checks if entire O/P buffer pool is allocated by IL Client or not.
+
+PARAMETERS
+None.
+
+RETURN VALUE
+true/false.
+
+========================================================================== */
+bool omx_vdec::allocate_output_done(void)
+{
+ bool bRet = false;
+ unsigned j=0;
+
+ if (m_out_mem_ptr == NULL)
+ {
+ return bRet;
+ }
+
+ if (m_out_mem_ptr)
+ {
+ for(;j < drv_ctx.op_buf.actualcount;j++)
+ {
+ if(BITMASK_ABSENT(&m_out_bm_count,j))
+ {
+ break;
+ }
+ }
+ }
+
+ if(j == drv_ctx.op_buf.actualcount)
+ {
+ bRet = true;
+ DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
+ if(m_out_bEnabled)
+ m_out_bPopulated = OMX_TRUE;
+ }
+
+ return bRet;
+}
+
+/* ======================================================================
+FUNCTION
+omx_vdec::ReleaseDone
+
+DESCRIPTION
+Checks if IL client has released all the buffers.
+
+PARAMETERS
+None.
+
+RETURN VALUE
+true/false
+
+========================================================================== */
+bool omx_vdec::release_done(void)
+{
+ bool bRet = false;
+
+ if(release_input_done())
+ {
+ if(release_output_done())
+ {
+ bRet = true;
+ }
+ }
+
+ if (bRet && m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ bRet = release_interm_done();
+ }
+ return bRet;
+}
+
+bool omx_vdec::release_interm_done(void)
+{
+ bool bRet = true;
+ unsigned int i=0;
+
+ if (!drv_ctx.ptr_interm_outputbuffer) return bRet;
+
+ pthread_mutex_lock(&m_lock);
+ for(; (i<drv_ctx.interm_op_buf.actualcount) && drv_ctx.ptr_interm_outputbuffer[i].pmem_fd ; i++)
+ {
+ if(m_interm_buf_state[i] != WITH_COMPONENT)
+ {
+ bRet = false;
+ DEBUG_PRINT_ERROR("interm buffer i %d state %d",i, m_interm_buf_state[i]);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+
+ DEBUG_PRINT_LOW("release_interm_done %d",bRet);
+ return bRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+omx_vdec::ReleaseOutputDone
+
+DESCRIPTION
+Checks if IL client has released all the buffers.
+
+PARAMETERS
+None.
+
+RETURN VALUE
+true/false
+
+========================================================================== */
+bool omx_vdec::release_output_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_out_mem_ptr);
+ if(m_out_mem_ptr)
+ {
+ for(;j < drv_ctx.op_buf.actualcount ; j++)
+ {
+ if(BITMASK_PRESENT(&m_out_bm_count,j))
+ {
+ break;
+ }
+ }
+ if(j == drv_ctx.op_buf.actualcount)
+ {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ }
+ else
+ {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+omx_vdec::ReleaseInputDone
+
+DESCRIPTION
+Checks if IL client has released all the buffers.
+
+PARAMETERS
+None.
+
+RETURN VALUE
+true/false
+
+========================================================================== */
+bool omx_vdec::release_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
+ if(m_inp_mem_ptr)
+ {
+ for(;j<drv_ctx.ip_buf.actualcount;j++)
+ {
+ if( BITMASK_PRESENT(&m_inp_bm_count,j))
+ {
+ break;
+ }
+ }
+ if(j==drv_ctx.ip_buf.actualcount)
+ {
+ bRet = true;
+ }
+ }
+ else
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+
+OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ if (!buffer)
+ {
+ DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
+ return OMX_ErrorBadParameter;
+ }
+ unsigned long int nPortIndex = buffer - m_out_mem_ptr;
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
+ if (nPortIndex >= drv_ctx.op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("[FBD] ERROR in port idx(%ld), act cnt(%d)",
+ nPortIndex, (int)drv_ctx.op_buf.actualcount);
+ 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("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p idx %d, TS %lld nFlags %lu",
+ buffer, buffer->pBuffer, buffer - m_out_mem_ptr, buffer->nTimeStamp, buffer->nFlags );
+ pending_output_buffers --;
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ DEBUG_PRINT_HIGH("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 long) pdest_frame,(unsigned long)NULL,
+ (unsigned long)NULL);
+ pdest_frame = NULL;
+ }
+ }
+
+ if (m_debug.out_buffer_log)
+ {
+ log_output_buffers(buffer);
+ }
+
+ /* 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("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
+ buffer->nTimeStamp, expected_ts);
+
+ if (buffer->nTimeStamp != expected_ts)
+ {
+ DEBUG_PRINT_ERROR("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("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 %lu", pPMEMInfo->pmem_fd);
+ OMX_BUFFERHEADERTYPE *il_buffer;
+ il_buffer = client_buffers.get_il_buf_hdr(buffer);
+
+ if (dynamic_buf_mode && !secure_mode &&
+ !(buffer->nFlags & OMX_BUFFERFLAG_READONLY))
+ {
+ DEBUG_PRINT_LOW("swvdec_fill_buffer_done rmd ref frame");
+ buf_ref_remove(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
+ drv_ctx.ptr_outputbuffer[nPortIndex].offset);
+ }
+ 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 %lu",pPMEMInfo->pmem_fd);
+ }
+ else
+ {
+ return OMX_ErrorBadParameter;
+ }
+#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
+ if (m_swvdec_mode != SWVDEC_MODE_PARSE_DECODE)
+ {
+ /* in full sw solution stride doesn't get change with change of
+ resolution, so don't update geomatry in case of full sw */
+ if (m_smoothstreaming_mode && m_out_mem_ptr) {
+ OMX_U32 buf_index = buffer - m_out_mem_ptr;
+ BufferDim_t dim;
+ private_handle_t *private_handle = NULL;
+ dim.sliceWidth = drv_ctx.video_resolution.frame_width;
+ dim.sliceHeight = drv_ctx.video_resolution.frame_height;
+ if (native_buffer[buf_index].privatehandle)
+ private_handle = native_buffer[buf_index].privatehandle;
+ if (private_handle) {
+ DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
+ dim.sliceWidth, dim.sliceHeight);
+ setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
+ }
+ }
+ }
+#endif
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer)
+{
+
+ if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount))
+ {
+ DEBUG_PRINT_ERROR("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 long)buffer,
+ (unsigned long)NULL, (unsigned long)NULL))
+ {
+ DEBUG_PRINT_ERROR("ERROR: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;
+}
+
+
+void dump_buffer(FILE* pFile, char* buffer, int stride, int scanlines, int width, int height)
+{
+ if (buffer)
+ {
+ char *temp = (char *)buffer;
+ int i;
+ int bytes_written = 0;
+ int bytes = 0;
+
+ for (i = 0; i < height; i++) {
+ bytes_written = fwrite(temp, width, 1, pFile);
+ temp += stride;
+ if (bytes_written >0)
+ bytes += bytes_written * width;
+ }
+ temp = (char *)buffer + stride * scanlines;
+ int stride_c = stride;
+ for(i = 0; i < height/2; i++) {
+ bytes_written = fwrite(temp, width, 1, pFile);
+ temp += stride_c;
+ if (bytes_written >0)
+ bytes += bytes_written * width;
+ }
+
+ DEBUG_PRINT_ERROR("stride %d, scanlines %d, frame_height %d bytes_written %d",
+ stride, scanlines, height, bytes);
+ }
+}
+
+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("FATAL ERROR in omx_vdec::async_message_process NULL Check");
+ return -1;
+ }
+ vdec_msg = (struct vdec_msginfo *)message;
+
+ omx = reinterpret_cast<omx_vdec*>(context);
+
+ switch (vdec_msg->msgcode)
+ {
+
+ case VDEC_MSG_EVT_HW_ERROR:
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+ break;
+
+ case VDEC_MSG_RESP_START_DONE:
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_START_DONE);
+ break;
+
+ case VDEC_MSG_RESP_STOP_DONE:
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_STOP_DONE);
+ break;
+
+ case VDEC_MSG_RESP_RESUME_DONE:
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_RESUME_DONE);
+ break;
+
+ case VDEC_MSG_RESP_PAUSE_DONE:
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_PAUSE_DONE);
+ break;
+
+ case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
+ break;
+ case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
+ if (!omx->m_pSwVdec)
+ {
+ omx->post_event ((unsigned)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
+ }
+ else
+ {
+ omx->post_event ((unsigned)NULL, (unsigned long)vdec_msg->status_code,\
+ (unsigned long)OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH_DSP);
+ }
+ 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) > (int)omx->drv_ctx.ip_buf.actualcount) )
+ {
+ omxhdr = NULL;
+ vdec_msg->status_code = VDEC_S_EFATAL;
+ }
+ if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
+ DEBUG_PRINT_HIGH("Unsupported input");
+ omx->omx_report_error ();
+ }
+ if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
+ vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
+ }
+ omx->post_event ((unsigned long)omxhdr, (unsigned long)vdec_msg->status_code,
+ (unsigned long)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 long)timestamp, (unsigned long)vdec_msg->status_code,
+ (unsigned long)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:
+ {
+ int actualcount = omx->drv_ctx.op_buf.actualcount;
+ OMX_BUFFERHEADERTYPE* p_mem_ptr = omx->m_out_mem_ptr;
+ vdec_output_frameinfo* ptr_respbuffer = omx->drv_ctx.ptr_respbuffer;
+ if (omx->m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ actualcount = omx->drv_ctx.interm_op_buf.actualcount;
+ p_mem_ptr = omx->m_interm_mem_ptr;
+ ptr_respbuffer = omx->drv_ctx.ptr_interm_respbuffer;
+ }
+ v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
+ omxhdr=p_mem_ptr+v4l2_buf_ptr->index;
+ DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) pBuffer (%p) idx %d Ts(%lld) Pic_type(%u) frame.len(%d)",
+ omxhdr, omxhdr->pBuffer, v4l2_buf_ptr->index, vdec_msg->msgdata.output_frame.time_stamp,
+ vdec_msg->msgdata.output_frame.pic_type, vdec_msg->msgdata.output_frame.len);
+
+ if (omxhdr && omxhdr->pOutputPortPrivate &&
+ ((omxhdr - p_mem_ptr) < actualcount) &&
+ (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
+ - ptr_respbuffer) < actualcount))
+ {
+ if ((omx->m_pSwVdec == NULL) &&
+ omx->dynamic_buf_mode &&
+ vdec_msg->msgdata.output_frame.len)
+ {
+ vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
+ }
+ 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_QCOM_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 (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)
+ {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
+ }
+ 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_QCOM_BUF_FLAG_EOS)) {
+ omx->time_stamp_dts.remove_time_stamp(
+ omxhdr->nTimeStamp,
+ (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
+ ?true:false);
+ omx->post_event ((unsigned long)NULL,(unsigned long)omxhdr,
+ (unsigned long)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 != (unsigned)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("Height/Width information has changed");
+ 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("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
+ 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("Crop information changed. W: %lu --> %d, H: %lu -> %d",
+ 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.left + vdec_msg->msgdata.output_frame.framesize.right >=
+ omx->drv_ctx.video_resolution.frame_width) {
+ vdec_msg->msgdata.output_frame.framesize.left = 0;
+ if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
+ vdec_msg->msgdata.output_frame.framesize.right = omx->drv_ctx.video_resolution.frame_width;
+ }
+ }
+ if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
+ omx->drv_ctx.video_resolution.frame_height) {
+ vdec_msg->msgdata.output_frame.framesize.top = 0;
+ if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
+ vdec_msg->msgdata.output_frame.framesize.bottom = omx->drv_ctx.video_resolution.frame_height;
+ }
+ }
+ DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d",
+ vdec_msg->msgdata.output_frame.framesize.left,
+ vdec_msg->msgdata.output_frame.framesize.top,
+ vdec_msg->msgdata.output_frame.framesize.right,
+ vdec_msg->msgdata.output_frame.framesize.bottom,
+ omx->drv_ctx.video_resolution.frame_width,
+ omx->drv_ctx.video_resolution.frame_height);
+ 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;
+ }
+ DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
+ vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
+ vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
+ if (format_notably_changed) {
+ if (omx->is_video_session_supported()) {
+ omx->post_event ((unsigned long)0, (unsigned long)vdec_msg->status_code,
+ (unsigned long)OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
+ } else {
+ if (!omx->client_buffers.update_buffer_req()) {
+ DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
+ }
+ omx->post_event ((unsigned long)OMX_CORE_OUTPUT_PORT_INDEX, (unsigned long)OMX_IndexConfigCommonOutputCrop,
+ (unsigned long)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;
+ if (!omx->m_pSwVdec)
+ {
+ omx->post_event ((unsigned long)omxhdr, (unsigned long)vdec_msg->status_code,
+ (unsigned long)OMX_COMPONENT_GENERATE_FBD);
+ }
+ else
+ {
+ omx->post_event ((unsigned long)omxhdr, (unsigned long)vdec_msg->status_code,
+ (unsigned long)OMX_COMPONENT_GENERATE_FBD_DSP);
+ }
+ }
+ else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,
+ OMX_COMPONENT_GENERATE_EOS_DONE);
+ else
+ omx->post_event ((unsigned long)NULL, (unsigned long)vdec_msg->status_code,
+ (unsigned long)OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+ }
+ break;
+ case VDEC_MSG_EVT_CONFIG_CHANGED:
+ if (!omx->m_pSwVdec)
+ {
+ DEBUG_PRINT_HIGH("Port settings changed");
+ omx->post_event ((unsigned long)OMX_CORE_OUTPUT_PORT_INDEX, (unsigned long)OMX_IndexParamPortDefinition,
+ (unsigned long)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("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 %lu, flags %lu, 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 %lld",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 long)buffer, (unsigned long)NULL,
+ (unsigned long)NULL))
+ {
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
+{
+ unsigned long 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 %lld",psource_frame,
+ psource_frame->nTimeStamp);
+ DEBUG_PRINT_LOW("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_HEVC:
+ ret = push_input_hevc(hComp);
+ break;
+ default:
+ break;
+ }
+ if (ret != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
+ omx_report_error ();
+ break;
+ }
+ }
+
+ return ret;
+}
+
+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 = 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");
+ rc = OMX_ErrorBadParameter;
+ }
+ return rc;
+}
+
+OMX_ERRORTYPE omx_vdec::push_input_hevc (OMX_HANDLETYPE hComp)
+{
+ OMX_U32 partial_frame = 1;
+ unsigned long 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("ERROR:Hevc Scratch Buffer not allocated");
+ return OMX_ErrorBadParameter;
+ }
+
+
+ DEBUG_PRINT_LOW("h264_scratch.nFilledLen %lu has look_ahead_nal %d pdest_frame nFilledLen %lu nTimeStamp %lld",
+ 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("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("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 = %lu",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 %lu nTimestamp %lld, pdest_frame nFilledLen %lu nTimestamp %lld",
+ 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");
+ 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 %lu nTimeStamp %lld, look_ahead_nal in h264_scratch nFilledLen %lu nTimeStamp %lld",
+ 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",pdest_frame);
+ pdest_frame->nFilledLen = 0;
+ pdest_frame->nFlags = 0;
+ pdest_frame->nTimeStamp = LLONG_MAX;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %lu nTimeStamp %lld, pdest_frame nFilledLen %lu nTimeStamp %lld, h264_scratch nFilledLen %lu nTimeStamp %lld",
+ 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("ERROR: 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");
+ 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_ERROR("Push EOS frame number:%d nFilledLen =%lu TimeStamp = %lld nFlags %lu",
+ frame_count++, pdest_frame->nFilledLen,pdest_frame->nTimeStamp, pdest_frame->nFlags);
+
+ /*Push the frame to the Decoder*/
+ if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
+ {
+ return OMX_ErrorBadParameter;
+ }
+ pdest_frame = NULL;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("Last frame in else dest addr %p size %lu frame_count %d",
+ pdest_frame,h264_scratch.nFilledLen, frame_count);
+ 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 %lu nFilledLen %lu, nTimeStamp %lld",
+ psource_frame->nFlags,psource_frame->nFilledLen, psource_frame->nTimeStamp);
+ }
+ }
+ 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("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 heap_id)
+{
+ 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");
+ 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", 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_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
+ if (!secure_mode && heap_id)
+ alloc_data->heap_id_mask = ION_HEAP(heap_id);
+
+ DEBUG_PRINT_LOW("ION ALLOC memory heap_id %d mask %0xx size %d align %d",
+ heap_id, (unsigned int)alloc_data->heap_id_mask, alloc_data->len, alloc_data->align);
+ rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
+ if (rc || !alloc_data->handle) {
+ DEBUG_PRINT_ERROR("ION ALLOC memory failed ");
+ alloc_data->handle = 0;
+ 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("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("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("ION: free failed" );
+ }
+
+ close(buf_ion_info->ion_device_fd);
+ buf_ion_info->ion_device_fd = -1;
+ buf_ion_info->ion_alloc_data.handle = 0;
+ 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
+ if (out_dynamic_list) {
+ free(out_dynamic_list);
+ out_dynamic_list = NULL;
+ }
+}
+
+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;
+ }
+ while (m_input_free_q.m_size) {
+ unsigned long address, p2, id;
+ m_input_free_q.pop_entry(&address, &p2, &id);
+ }
+ 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
+}
+
+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", 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",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,
+ 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 (plane[0].sizeimage) = %d",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", 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",
+ 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), extradata size %d",
+ buffer_prop->actualcount, buffer_prop->buffer_size, buf_size, buffer_prop->buffer_type, client_extra_data_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_HIGH("GetBufReq OUT: ActCnt(%d) Size(%d), BufType(%d)",
+ 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 (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
+ if (!client_buffers.update_buffer_req()) {
+ DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ }
+ if (!eRet && !m_pSwVdec && buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT)
+ {
+ // need to update extradata buffers also in pure dsp mode
+ 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");
+ 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");
+ 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("client_buffers.update_buffer_req Failed");
+ return OMX_ErrorHardware;
+ }
+ if (!client_buffers.get_buffer_req(buf_size)) {
+ DEBUG_PRINT_ERROR("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("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_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
+ " SliceHeight = %lu", 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("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 (dynamic_buf_mode) {
+ out_dynamic_list = (struct dynamic_buf_list *) \
+ calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
+ }
+ 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%p][0x%p]",\
+ 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 long p1;
+ unsigned long p2;
+ unsigned long 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("ERROR: empty_buffer_done() failed!");
+ omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FBD:
+ if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
+ {
+ DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
+ 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(%lu) 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 long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
+ if (!client_extradata)
+ p_extra = NULL;
+ 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)MSM_VIDC_EXTRADATA_NONE)) {
+ if ((consumed_len + data->nSize) > (OMX_U32)drv_ctx.extradata_info.buffer_size) {
+ DEBUG_PRINT_LOW("Invalid extra data size");
+ break;
+ }
+ unsigned char* tmp = data->data;
+ switch((unsigned long)data->eType) {
+case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
+ struct msm_vidc_interlace_payload *payload;
+ payload = (struct msm_vidc_interlace_payload *)tmp;
+ if (payload->format != MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
+ int enable = 1;
+ OMX_U32 mbaff = 0;
+ mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
+ if ((payload->format == MSM_VIDC_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 MSM_VIDC_EXTRADATA_FRAME_RATE:
+ struct msm_vidc_framerate_payload *frame_rate_payload;
+ frame_rate_payload = (struct msm_vidc_framerate_payload *)tmp;
+ frame_rate = frame_rate_payload->frame_rate;
+ break;
+case MSM_VIDC_EXTRADATA_TIMESTAMP:
+ struct msm_vidc_ts_payload *time_stamp_payload;
+ time_stamp_payload = (struct msm_vidc_ts_payload *)tmp;
+ p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
+ p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
+ break;
+case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
+ struct msm_vidc_concealmb_payload *conceal_mb_payload;
+ conceal_mb_payload = (struct msm_vidc_concealmb_payload *)tmp;
+ 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 MSM_VIDC_EXTRADATA_ASPECT_RATIO:
+ struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
+ aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)tmp;
+ ((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 MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
+ struct msm_vidc_recoverysei_payload *recovery_sei_payload;
+ recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)tmp;
+ recovery_sei_flags = recovery_sei_payload->flags;
+ if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
+ p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+ DEBUG_PRINT_HIGH("Extradata: OMX_BUFFERFLAG_DATACORRUPT Received");
+ }
+ break;
+case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
+ panscan_payload = (struct msm_vidc_panscan_window_payload *)tmp;
+ 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[%lx] requested[%lx] enable[%d], is_internal: %d swvdec mode %d",
+ client_extradata, requested_extradata, enable, is_internal, m_swvdec_mode);
+
+ if (!is_internal) {
+ if (enable)
+ client_extradata |= requested_extradata;
+ else
+ client_extradata = client_extradata & ~requested_extradata;
+ }
+
+ if (enable) {
+ if (m_pSwVdec == NULL || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) {
+ 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.");
+ }
+ } 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");
+ }
+ 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");
+ }
+ 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");
+ }
+ 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");
+ }
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
+ if(ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set panscan extradata");
+ }
+ } 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");
+ }
+ }
+ }
+ }
+ 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;
+
+ unsigned char* tmp = extra->data;
+
+ DEBUG_PRINT_HIGH(
+ "============== Extra Data ==============\n"
+ " Size: %lu\n"
+ " Version: %lu\n"
+ " PortIndex: %lu\n"
+ " Type: %x\n"
+ " DataSize: %lu",
+ extra->nSize, extra->nVersion.nVersion,
+ extra->nPortIndex, extra->eType, extra->nDataSize);
+
+ if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat)
+ {
+ OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)tmp;
+ 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 ===========",
+ 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 *)tmp;
+
+ 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",
+ 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",
+ 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) || !extra) {
+ 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);
+ unsigned char* tmp = extra->data;
+ interlace_format = (OMX_STREAMINTERLACEFORMAT *)tmp;
+ 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 == MSM_VIDC_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) || !extra) {
+ 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);
+ unsigned char* tmp = extra->data;
+ frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)tmp;
+ 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)
+{
+ if (!client_extradata || !extra) {
+ return;
+ }
+
+ 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);
+ unsigned char* tmp = extra->data;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)tmp;
+ *portDefn = m_port_def;
+ DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu stride = %lu"
+ "sliceheight = %lu",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 || !extra) {
+ 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("ERROR: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("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("desc 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(%d), suffix_byte(0x%x),nal_size(%lu),demux_index(%lu)",
+ start_addr,
+ (unsigned int)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_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<omx_vdec*>(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("Invalid client in color convert");
+ return false;
+ }
+ if (!enabled){
+ DEBUG_PRINT_ERROR("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("update_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("ERROR: 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("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("Incorrect color format");
+ status = false;
+ }
+ if (status && (drv_color_format != dest_color_format)) {
+ DEBUG_PRINT_LOW("Enabling C2D");
+ if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
+ DEBUG_PRINT_ERROR("Unsupported color format for c2d");
+ status = false;
+ } else {
+ ColorFormat = OMX_COLOR_FormatYUV420Planar;
+ if (enabled)
+ c2d.destroy();
+ enabled = false;
+ if (!c2d.init()) {
+ DEBUG_PRINT_ERROR("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("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("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("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("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("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("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("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("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("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("Notin color convert mode secure_mode %d",
+ omx->is_component_secure());
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (!bufferHdr || bytes > buffer_size_req) {
+ DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
+ DEBUG_PRINT_ERROR("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("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("Buffer allocation failed color_convert");
+ return eRet;
+ }
+ if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
+ (int)omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("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("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("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 = (unsigned long)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("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;
+}
+
+void omx_vdec::buf_ref_add(int index, OMX_U32 fd, OMX_U32 offset)
+{
+ int i = 0;
+ bool buf_present = false;
+
+ pthread_mutex_lock(&m_lock);
+ if (out_dynamic_list[index].dup_fd &&
+ (out_dynamic_list[index].fd != fd) &&
+ (out_dynamic_list[index].offset != offset))
+ {
+ DEBUG_PRINT_LOW("buf_ref_add error: index %d taken by fd = %lu offset = %lu, new fd %lu offset %lu",
+ index, out_dynamic_list[index].fd, out_dynamic_list[index].offset, fd, offset);
+ pthread_mutex_unlock(&m_lock);
+ return;
+ }
+
+ if (out_dynamic_list[index].dup_fd == 0)
+ {
+ out_dynamic_list[index].fd = fd;
+ out_dynamic_list[index].offset = offset;
+ out_dynamic_list[index].dup_fd = dup(fd);
+ }
+ out_dynamic_list[index].ref_count++;
+ DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %lu ref_count = %lu",
+ out_dynamic_list[index].fd, out_dynamic_list[index].ref_count);
+ pthread_mutex_unlock(&m_lock);
+}
+
+void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
+{
+ unsigned long i = 0;
+ pthread_mutex_lock(&m_lock);
+ for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
+ //check the buffer fd, offset, uv addr with list contents
+ //If present decrement reference.
+ if ((out_dynamic_list[i].fd == fd) &&
+ (out_dynamic_list[i].offset == offset)) {
+ out_dynamic_list[i].ref_count--;
+ if (out_dynamic_list[i].ref_count == 0) {
+ close(out_dynamic_list[i].dup_fd);
+ DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %lu ref_count = %lu",
+ out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
+ out_dynamic_list[i].dup_fd = 0;
+ out_dynamic_list[i].fd = 0;
+ out_dynamic_list[i].offset = 0;
+
+ munmap(drv_ctx.ptr_outputbuffer[i].bufferaddr,
+ drv_ctx.ptr_outputbuffer[i].mmaped_size);
+ DEBUG_PRINT_LOW("unmapped dynamic buffer idx %lu pBuffer %p",
+ i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
+
+ drv_ctx.ptr_outputbuffer[i].bufferaddr = NULL;
+ drv_ctx.ptr_outputbuffer[i].offset = 0;
+ drv_ctx.ptr_outputbuffer[i].mmaped_size = 0;
+ if (m_pSwVdecOpBuffer)
+ {
+ m_pSwVdecOpBuffer[i].pBuffer = NULL;
+ m_pSwVdecOpBuffer[i].nSize = 0;
+ }
+ }
+ break;
+ }
+ }
+ if (i >= drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
+ }
+ pthread_mutex_unlock(&m_lock);
+}
+
+OMX_ERRORTYPE omx_vdec::get_buffer_req_swvdec()
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if (!m_pSwVdec)
+ {
+ eRet=get_buffer_req(&drv_ctx.ip_buf);
+ eRet=get_buffer_req(&drv_ctx.op_buf);
+ return eRet;
+ }
+
+ SWVDEC_PROP property;
+ if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ property.ePropId = SWVDEC_PROP_ID_IPBUFFREQ;
+ SWVDEC_STATUS sRet = SwVdec_GetProperty(m_pSwVdec, &property);
+ if (sRet != SWVDEC_S_SUCCESS)
+ {
+ return OMX_ErrorUndefined;
+ }
+ else
+ {
+ drv_ctx.ip_buf.buffer_size = property.uProperty.sIpBuffReq.nSize;
+ drv_ctx.ip_buf.mincount = property.uProperty.sIpBuffReq.nMinCount;
+ drv_ctx.ip_buf.actualcount = property.uProperty.sIpBuffReq.nMinCount;
+ DEBUG_PRINT_ERROR("swvdec input buf size %d count %d",drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.actualcount);
+ }
+ }
+
+ /* buffer requirement for out*/
+ if ( (false == m_smoothstreaming_mode) ||
+ ((drv_ctx.video_resolution.frame_height > m_smoothstreaming_width) &&
+ (drv_ctx.video_resolution.frame_width > m_smoothstreaming_height))
+ )
+ {
+ property.ePropId = SWVDEC_PROP_ID_OPBUFFREQ;
+ SWVDEC_STATUS sRet = SwVdec_GetProperty(m_pSwVdec, &property);
+ if (sRet != SWVDEC_S_SUCCESS)
+ {
+ return OMX_ErrorUndefined;
+ }
+ else
+ {
+ int client_extra_data_size = 0;
+ 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)
+ {
+ DEBUG_PRINT_HIGH("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",
+ client_extra_data_size);
+ }
+ if (client_extra_data_size)
+ {
+ client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
+ }
+ drv_ctx.op_buf.buffer_size = property.uProperty.sOpBuffReq.nSize + client_extra_data_size;
+ drv_ctx.op_buf.mincount = property.uProperty.sOpBuffReq.nMinCount;
+ drv_ctx.op_buf.actualcount = property.uProperty.sOpBuffReq.nMinCount;
+ DEBUG_PRINT_HIGH("swvdec opbuf size %lu extradata size %d total size %d count %d",
+ property.uProperty.sOpBuffReq.nSize, client_extra_data_size,
+ drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.actualcount);
+ }
+ }
+
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ return get_buffer_req(&drv_ctx.interm_op_buf);
+ }
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::set_buffer_req_swvdec(vdec_allocatorproperty *buffer_prop)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if (!m_pSwVdec)
+ {
+ eRet = set_buffer_req(buffer_prop);
+ return eRet;
+ }
+
+ unsigned buf_size = 0;
+ SWVDEC_PROP property;
+ SWVDEC_STATUS sRet = SWVDEC_S_SUCCESS;
+
+ DEBUG_PRINT_HIGH("set_buffer_req_swvdec IN: ActCnt(%d) Size(%d), buffer type %d",
+ buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type);
+
+ 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
+ {
+ property.uProperty.sIpBuffReq.nSize = buffer_prop->buffer_size;
+ property.uProperty.sIpBuffReq.nMaxCount = buffer_prop->actualcount;
+ property.uProperty.sIpBuffReq.nMinCount = buffer_prop->actualcount;
+
+ if(buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT)
+ {
+ property.ePropId = SWVDEC_PROP_ID_IPBUFFREQ;
+ DEBUG_PRINT_HIGH("swvdec input Buffer Size = %lu Count = %d",property.uProperty.sIpBuffReq.nSize, buffer_prop->mincount);
+ }
+ else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT)
+ {
+ property.ePropId = SWVDEC_PROP_ID_OPBUFFREQ;
+ DEBUG_PRINT_HIGH("swvdec output Buffer Size = %lu and Count = %d",property.uProperty.sOpBuffReq.nSize, buffer_prop->actualcount);
+ }
+ else
+ {
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ if(eRet==OMX_ErrorNone)
+ {
+ sRet = SwVdec_SetProperty(m_pSwVdec, &property);
+ }
+
+ if (sRet != SWVDEC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("Set buffer requirements from ARM codec failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+
+ if ((m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY) &&
+ (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;
+ eRet = set_buffer_req(&drv_ctx.interm_op_buf);
+ }
+
+ return eRet;
+}
+
+/* ======================================================================
+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_swvdec(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ (void)hComp;
+ 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)
+ {
+ DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_interm_mem_ptr);
+
+ if (nPortIndex > drv_ctx.interm_op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy_swvdec invalid nPortIndex[%u]",
+ nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ /* return zero length and not an EOS buffer */
+ if ( (buffer->nFilledLen == 0) &&
+ ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
+ {
+ DEBUG_PRINT_HIGH("return zero legth buffer");
+ pthread_mutex_lock(&m_lock);
+ m_interm_buf_state[nPortIndex] = WITH_SWVDEC;
+ pthread_mutex_unlock(&m_lock);
+ post_event ((unsigned long)buffer,(unsigned long)VDEC_S_SUCCESS,
+ (unsigned long)OMX_COMPONENT_GENERATE_EBD_SWVDEC);
+ return OMX_ErrorNone;
+ }
+
+ if(m_interm_bEnabled != OMX_TRUE || m_interm_flush_swvdec_progress == true)
+ {
+ DEBUG_PRINT_ERROR("empty_this_buffer_proxy_swvdec called when swvdec flush is in progress");
+ return OMX_ErrorNone;
+ }
+
+ // send this buffer to swvdec
+ DEBUG_PRINT_LOW("empty_this_buffer_proxy_swvdec bufHdr %p pBuffer %p nFilledLen %lu m_pSwVdecIpBuffer %p, idx %d nFlags %x",
+ buffer, buffer->pBuffer, buffer->nFilledLen, m_pSwVdecIpBuffer, nPortIndex, (unsigned int)buffer->nFlags);
+ m_pSwVdecIpBuffer[nPortIndex].nFlags = buffer->nFlags;
+ m_pSwVdecIpBuffer[nPortIndex].nFilledLen = buffer->nFilledLen;
+ m_pSwVdecIpBuffer[nPortIndex].nIpTimestamp = buffer->nTimeStamp;
+ if (SwVdec_EmptyThisBuffer(m_pSwVdec, &m_pSwVdecIpBuffer[nPortIndex]) != SWVDEC_S_SUCCESS) {
+ ret = OMX_ErrorBadParameter;
+ }
+ pthread_mutex_lock(&m_lock);
+ m_interm_buf_state[nPortIndex] = WITH_SWVDEC;
+ pthread_mutex_unlock(&m_lock);
+ return ret;
+}
+
+OMX_ERRORTYPE omx_vdec::empty_buffer_done_swvdec(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer)
+{
+ (void)hComp;
+ int idx = buffer - m_interm_mem_ptr;
+ if (buffer == NULL || idx > (int)drv_ctx.interm_op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("empty_buffer_done_swvdec: ERROR bufhdr = %p", buffer);
+ return OMX_ErrorBadParameter;
+ }
+
+ DEBUG_PRINT_LOW("empty_buffer_done_swvdec: bufhdr = %p, bufhdr->pBuffer = %p idx %d",
+ buffer, buffer->pBuffer, idx);
+
+ buffer->nFilledLen = 0;
+ pthread_mutex_lock(&m_lock);
+ if (m_interm_buf_state[idx] != WITH_SWVDEC)
+ {
+ DEBUG_PRINT_ERROR("empty_buffer_done_swvdec error: bufhdr = %p, idx %d, buffer not with swvdec ",buffer, idx);
+ pthread_mutex_unlock(&m_lock);
+ return OMX_ErrorBadParameter;
+ }
+ m_interm_buf_state[idx] = WITH_COMPONENT;
+ pthread_mutex_unlock(&m_lock);
+
+ if(m_interm_bEnabled != OMX_TRUE ||
+ output_flush_progress == true ||
+ m_interm_flush_dsp_progress == true ||
+ m_interm_flush_swvdec_progress == true)
+ {
+ DEBUG_PRINT_HIGH("empty_buffer_done_swvdec: Buffer (%p) flushed idx %d", buffer, idx);
+ buffer->nFilledLen = 0;
+ buffer->nTimeStamp = 0;
+ buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
+ buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
+ buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
+ return OMX_ErrorNone;
+ }
+
+ // call DSP FTB for the intermediate buffer. post event to the command queue do it asynchrounously
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY && in_reconfig != true)
+ {
+ post_event((unsigned long)&m_cmp, (unsigned long)buffer, (unsigned long)OMX_COMPONENT_GENERATE_FTB_DSP);
+ }
+ else if (m_swvdec_mode == SWVDEC_MODE_PARSE_DECODE)
+ {
+ post_event((unsigned long)&m_cmp, (unsigned long)buffer, (unsigned long)OMX_COMPONENT_GENERATE_EBD);
+ }
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::fill_all_buffers_proxy_dsp(OMX_HANDLETYPE hComp)
+{
+ int idx = 0;
+ OMX_ERRORTYPE nRet = OMX_ErrorNone;
+ if (m_fill_internal_bufers == OMX_FALSE)
+ {
+ return nRet;
+ }
+
+ if (m_interm_mem_ptr == NULL)
+ {
+ DEBUG_PRINT_ERROR("fill_all_buffers_proxy_dsp called in bad state");
+ return nRet;
+ }
+ m_fill_internal_bufers = OMX_FALSE;
+
+ for (idx=0; idx < (int)drv_ctx.interm_op_buf.actualcount; idx++)
+ {
+ pthread_mutex_lock(&m_lock);
+ if (m_interm_buf_state[idx] == WITH_COMPONENT)
+ {
+ OMX_BUFFERHEADERTYPE* bufHdr = m_interm_mem_ptr + idx;
+ nRet = fill_this_buffer_proxy_dsp(hComp, bufHdr);
+ if (nRet != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR("fill_this_buffer_proxy_dsp failed for buff %d bufHdr %p pBuffer %p",
+ idx, bufHdr, bufHdr->pBuffer);
+ break;
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+ }
+ return nRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+omx_vdec::fill_this_buffer_proxy_dsp
+
+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_dsp(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
+{
+ (void)hComp;
+ 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;
+ int rc = 0;
+
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("FTB in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_interm_mem_ptr);
+
+ if (bufferAdd == NULL || nPortIndex > drv_ctx.interm_op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("FTBProxyDSP: bufhdr = %p, nPortIndex %u bufCount %u",
+ bufferAdd, nPortIndex, drv_ctx.interm_op_buf.actualcount);
+ return OMX_ErrorBadParameter;
+ }
+
+ DEBUG_PRINT_LOW("fill_this_buffer_proxy_dsp: bufhdr = %p,pBuffer = %p, idx %d, state %d",
+ bufferAdd, bufferAdd->pBuffer, nPortIndex, m_interm_buf_state[nPortIndex]);
+
+ pthread_mutex_lock(&m_lock);
+ if (m_interm_buf_state[nPortIndex] == WITH_DSP)
+ {
+ DEBUG_PRINT_HIGH("fill_this_buffer_proxy_dsp: buffer is with dsp");
+ pthread_mutex_unlock(&m_lock);
+ return OMX_ErrorNone;
+ }
+ pthread_mutex_unlock(&m_lock);
+
+ 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;
+ return OMX_ErrorBadParameter;
+ }
+
+ if(m_interm_bEnabled != OMX_TRUE || m_interm_flush_dsp_progress == true)
+ {
+ DEBUG_PRINT_ERROR("fill_this_buffer_proxy_dsp called when dsp flush in progress");
+ buffer->nFilledLen = 0;
+ return OMX_ErrorNone;
+ }
+
+ memcpy (&fillbuffer.buffer,ptr_outputbuffer,
+ sizeof(struct vdec_bufferpayload));
+ fillbuffer.client_data = bufferAdd;
+
+ 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.interm_op_buf.buffer_size;
+ plane[0].m.userptr =
+ (unsigned long)drv_ctx.ptr_interm_outputbuffer[nPortIndex].bufferaddr -
+ (unsigned long)drv_ctx.ptr_interm_outputbuffer[nPortIndex].offset;
+
+ plane[0].reserved[0] = drv_ctx.ptr_interm_outputbuffer[nPortIndex].pmem_fd;
+ plane[0].reserved[1] = drv_ctx.ptr_interm_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);
+ plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
+ 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", 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) {
+ DEBUG_PRINT_ERROR("Failed to qbuf to driver");
+ return OMX_ErrorBadParameter;
+ }
+
+ pthread_mutex_lock(&m_lock);
+ m_interm_buf_state[nPortIndex] = WITH_DSP;
+ pthread_mutex_unlock(&m_lock);
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::fill_buffer_done_dsp(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ (void)hComp;
+ int idx = buffer - m_interm_mem_ptr;
+ if (!buffer || idx >= (int)drv_ctx.interm_op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p), m_interm_mem_ptr(%p) idx %d", buffer, m_interm_mem_ptr, idx);
+ return OMX_ErrorBadParameter;
+ }
+
+ DEBUG_PRINT_LOW("fill_buffer_done_dsp: bufhdr = %p, bufhdr->pBuffer = %p, idx %d nFilledLen %lu nFlags %x",
+ buffer, buffer->pBuffer, idx, buffer->nFilledLen, (unsigned int)buffer->nFlags);
+
+ pthread_mutex_lock(&m_lock);
+ if (m_interm_buf_state[idx] != WITH_DSP)
+ {
+ DEBUG_PRINT_ERROR("fill_buffer_done_dsp error: bufhdr = %p, idx %d, buffer not with dsp", buffer, idx);
+ pthread_mutex_unlock(&m_lock);
+ return OMX_ErrorBadParameter;
+ }
+ m_interm_buf_state[idx] = WITH_COMPONENT;
+ pthread_mutex_unlock(&m_lock);
+
+ if (m_interm_bEnabled != OMX_TRUE ||
+ output_flush_progress == true ||
+ m_interm_flush_dsp_progress == true ||
+ m_interm_flush_swvdec_progress == true)
+ {
+ DEBUG_PRINT_HIGH("fill_buffer_done_dsp: Buffer (%p) flushed idx %d", buffer, idx);
+ buffer->nFilledLen = 0;
+ buffer->nTimeStamp = 0;
+ buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
+ buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
+ buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
+ return OMX_ErrorNone;
+ }
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ DEBUG_PRINT_HIGH("interm EOS has been reached");
+
+ 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 long) pdest_frame,(unsigned long)NULL,
+ (unsigned long)NULL);
+ pdest_frame = NULL;
+ }
+ }
+
+ if (m_debug.im_buffer_log)
+ {
+ log_im_buffer(buffer);
+ }
+
+ post_event((unsigned long)&m_cmp, (unsigned long)buffer, (unsigned long)OMX_COMPONENT_GENERATE_ETB_SWVDEC);
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::allocate_interm_buffer(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;
+ int heap_id = 0;
+
+ int ion_device_fd =-1;
+ struct ion_allocation_data ion_alloc_data;
+ struct ion_fd_data fd_ion_data;
+
+#ifdef _HEVC_USE_ADSP_HEAP_
+ heap_id = ION_ADSP_HEAP_ID;
+#else
+ heap_id = ION_IOMMU_HEAP_ID;
+#endif
+
+ if(!m_interm_mem_ptr)
+ {
+ DEBUG_PRINT_HIGH("Allocate interm buffer Header: Cnt(%d) Sz(%d)",
+ drv_ctx.interm_op_buf.actualcount, drv_ctx.interm_op_buf.buffer_size);
+
+ int nBufHdrSize = drv_ctx.interm_op_buf.actualcount * sizeof(OMX_BUFFERHEADERTYPE);
+ m_interm_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
+
+ drv_ctx.ptr_interm_outputbuffer = (struct vdec_bufferpayload *)
+ calloc (sizeof(struct vdec_bufferpayload), drv_ctx.interm_op_buf.actualcount);
+ drv_ctx.ptr_interm_respbuffer = (struct vdec_output_frameinfo *)
+ calloc (sizeof (struct vdec_output_frameinfo), drv_ctx.interm_op_buf.actualcount);
+ drv_ctx.interm_op_buf_ion_info = (struct vdec_ion *)
+ calloc (sizeof(struct vdec_ion), drv_ctx.interm_op_buf.actualcount);
+ m_pSwVdecIpBuffer = (SWVDEC_IPBUFFER *)calloc(sizeof(SWVDEC_IPBUFFER), drv_ctx.interm_op_buf.actualcount);
+
+ if (m_interm_mem_ptr == NULL ||
+ drv_ctx.ptr_interm_outputbuffer == NULL ||
+ drv_ctx.ptr_interm_respbuffer == NULL ||
+ drv_ctx.interm_op_buf_ion_info == NULL ||
+ m_pSwVdecIpBuffer == NULL)
+ {
+ goto clean_up;
+ }
+ }
+
+ bufHdr = m_interm_mem_ptr;
+ for (unsigned long i = 0; i < drv_ctx.interm_op_buf.actualcount; i++)
+ {
+ int pmem_fd = -1;
+ unsigned char *pmem_baseaddress = NULL;
+ int flags = secure_mode ? ION_SECURE : 0;
+ if (m_pSwVdec)
+ {
+ DEBUG_PRINT_HIGH("Allocate cached interm buffers");
+ flags = ION_FLAG_CACHED;
+ }
+
+ DEBUG_PRINT_HIGH("allocate interm output buffer size %d idx %lu",
+ drv_ctx.interm_op_buf.buffer_size, i);
+ ion_device_fd = alloc_map_ion_memory(
+ drv_ctx.interm_op_buf.buffer_size,
+ drv_ctx.interm_op_buf.alignment,
+ &ion_alloc_data, &fd_ion_data, flags, heap_id);
+ if (ion_device_fd < 0) {
+ eRet = OMX_ErrorInsufficientResources;
+ goto clean_up;
+ }
+ pmem_fd = fd_ion_data.fd;
+
+ drv_ctx.ptr_interm_outputbuffer[i].pmem_fd = pmem_fd;
+ drv_ctx.interm_op_buf_ion_info[i].ion_device_fd = ion_device_fd;
+ drv_ctx.interm_op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
+ drv_ctx.interm_op_buf_ion_info[i].fd_ion_data = fd_ion_data;
+
+ if (!secure_mode) {
+ pmem_baseaddress = (unsigned char *)mmap(NULL,
+ drv_ctx.interm_op_buf.buffer_size,
+ PROT_READ|PROT_WRITE,MAP_SHARED, pmem_fd, 0);
+ if (pmem_baseaddress == MAP_FAILED)
+ {
+ DEBUG_PRINT_ERROR("MMAP failed for Size %d",
+ drv_ctx.interm_op_buf.buffer_size);
+ eRet = OMX_ErrorInsufficientResources;
+ goto clean_up;
+ }
+ }
+
+ bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+ bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ bufHdr->nAllocLen = bytes;
+ bufHdr->nFilledLen = 0;
+ bufHdr->pAppPrivate = this;
+ bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ bufHdr->pBuffer = pmem_baseaddress;
+ bufHdr->nOffset = 0;
+
+ bufHdr->pOutputPortPrivate = &drv_ctx.ptr_interm_respbuffer[i];
+ drv_ctx.ptr_interm_respbuffer[i].client_data = (void *)&drv_ctx.ptr_interm_outputbuffer[i];
+ drv_ctx.ptr_interm_outputbuffer[i].offset = 0;
+ drv_ctx.ptr_interm_outputbuffer[i].bufferaddr = pmem_baseaddress;
+ drv_ctx.ptr_interm_outputbuffer[i].mmaped_size = drv_ctx.interm_op_buf.buffer_size;
+ drv_ctx.ptr_interm_outputbuffer[i].buffer_len = drv_ctx.interm_op_buf.buffer_size;
+
+ DEBUG_PRINT_LOW("interm pmem_fd = %d offset = %d address = %p, bufHdr %p",
+ pmem_fd, drv_ctx.ptr_interm_outputbuffer[i].offset,
+ drv_ctx.ptr_interm_outputbuffer[i].bufferaddr, bufHdr);
+
+ m_interm_buf_state[i] = WITH_COMPONENT;
+ m_pSwVdecIpBuffer[i].pBuffer = bufHdr->pBuffer;
+ m_pSwVdecIpBuffer[i].pClientBufferData = (void*)i;
+
+ // Move the buffer and buffer header pointers
+ bufHdr++;
+ }
+
+ eRet = allocate_extradata();
+ if (eRet != OMX_ErrorNone)
+ {
+ goto clean_up;
+ }
+
+ for(i=0; i<drv_ctx.interm_op_buf.actualcount; i++)
+ {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ int rc;
+
+ bufHdr = (m_interm_mem_ptr + i );
+ if (secure_mode) {
+ drv_ctx.ptr_interm_outputbuffer[i].bufferaddr = bufHdr;
+ }
+
+ buf.index = i;
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ plane[0].length = drv_ctx.interm_op_buf.buffer_size;
+ plane[0].m.userptr = (unsigned long)drv_ctx.ptr_interm_outputbuffer[i].bufferaddr -
+ (unsigned long)drv_ctx.ptr_interm_outputbuffer[i].offset;
+ plane[0].reserved[0] = drv_ctx.interm_op_buf_ion_info[i].fd_ion_data.fd;
+ plane[0].reserved[1] = drv_ctx.ptr_interm_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);
+ plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
+ 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", extra_idx);
+ goto clean_up;
+ }
+ buf.m.planes = plane;
+ buf.length = drv_ctx.num_planes;
+ DEBUG_PRINT_LOW("Set interm Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_interm_outputbuffer[i].bufferaddr);
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
+ if (rc) {
+ DEBUG_PRINT_ERROR("VIDIOC_PREPARE_BUF failed");
+ goto clean_up;
+ }
+
+ if (i == (drv_ctx.interm_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("STREAMON Successful");
+ }
+ }
+
+ bufHdr->pAppPrivate = this;
+ }
+
+ m_interm_bEnabled = OMX_TRUE;
+ m_interm_bPopulated = OMX_TRUE;
+
+ return OMX_ErrorNone;
+
+clean_up:
+
+ if (drv_ctx.interm_op_buf_ion_info)
+ {
+ for(i=0; i< drv_ctx.interm_op_buf.actualcount; i++)
+ {
+ if(drv_ctx.ptr_interm_outputbuffer)
+ {
+ close(drv_ctx.ptr_interm_outputbuffer[i].pmem_fd);
+ drv_ctx.ptr_interm_outputbuffer[i].pmem_fd = 0;
+ }
+ free_ion_memory(&drv_ctx.interm_op_buf_ion_info[i]);
+ }
+ }
+
+ if(m_interm_mem_ptr)
+ {
+ free(m_interm_mem_ptr);
+ m_interm_mem_ptr = NULL;
+ }
+ if(drv_ctx.ptr_interm_outputbuffer)
+ {
+ free(drv_ctx.ptr_interm_outputbuffer);
+ drv_ctx.ptr_interm_outputbuffer = NULL;
+ }
+ if(drv_ctx.ptr_interm_respbuffer)
+ {
+ free(drv_ctx.ptr_interm_respbuffer);
+ drv_ctx.ptr_interm_respbuffer = NULL;
+ }
+ if (drv_ctx.interm_op_buf_ion_info) {
+ DEBUG_PRINT_LOW("Free o/p ion context");
+ free(drv_ctx.interm_op_buf_ion_info);
+ drv_ctx.interm_op_buf_ion_info = NULL;
+ }
+ return OMX_ErrorInsufficientResources;
+}
+
+//callback function used by SWVdec
+
+SWVDEC_STATUS omx_vdec::swvdec_input_buffer_done_cb
+(
+ SWVDEC_HANDLE pSwDec,
+ SWVDEC_IPBUFFER *m_pSwVdecIpBuffer,
+ void *pClientHandle
+ )
+{
+ (void)pSwDec;
+ SWVDEC_STATUS eRet = SWVDEC_S_SUCCESS;
+ omx_vdec *omx = reinterpret_cast<omx_vdec*>(pClientHandle);
+
+ if (m_pSwVdecIpBuffer == NULL)
+ {
+ eRet = SWVDEC_S_EFAIL;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("%s invoked", __func__);
+ omx->swvdec_input_buffer_done(m_pSwVdecIpBuffer);
+ }
+
+ return eRet;
+}
+
+void omx_vdec::swvdec_input_buffer_done(SWVDEC_IPBUFFER *m_pSwVdecIpBuffer)
+{
+ unsigned long index = (unsigned long)m_pSwVdecIpBuffer->pClientBufferData;
+
+ if (m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ post_event((unsigned long)(m_interm_mem_ptr + index),
+ (unsigned long)VDEC_S_SUCCESS, (unsigned long)OMX_COMPONENT_GENERATE_EBD_SWVDEC);
+ }
+ else
+ {
+ post_event((unsigned long)(m_inp_mem_ptr + index),
+ (unsigned long)VDEC_S_SUCCESS, (unsigned long)OMX_COMPONENT_GENERATE_EBD);
+ }
+}
+
+SWVDEC_STATUS omx_vdec::swvdec_fill_buffer_done_cb
+(
+ SWVDEC_HANDLE pSwDec,
+ SWVDEC_OPBUFFER *m_pSwVdecOpBuffer,
+ void *pClientHandle
+)
+{
+ (void)pSwDec;
+ SWVDEC_STATUS eRet = SWVDEC_S_SUCCESS;
+ omx_vdec *omx = reinterpret_cast<omx_vdec*>(pClientHandle);
+
+ if (m_pSwVdecOpBuffer == NULL)
+ {
+ eRet = SWVDEC_S_EFAIL;
+ }
+ else
+ {
+ omx->swvdec_fill_buffer_done(m_pSwVdecOpBuffer);
+ }
+ return eRet;
+}
+
+void omx_vdec::swvdec_fill_buffer_done(SWVDEC_OPBUFFER *m_pSwVdecOpBuffer)
+{
+ unsigned long index = (unsigned long)m_pSwVdecOpBuffer->pClientBufferData;
+ OMX_BUFFERHEADERTYPE *bufHdr = m_out_mem_ptr + index;
+ bufHdr->nFilledLen = m_pSwVdecOpBuffer->nFilledLen;
+ bufHdr->nFlags = m_pSwVdecOpBuffer->nFlags;
+ bufHdr->nTimeStamp = m_pSwVdecOpBuffer->nOpTimestamp;
+
+ if (m_pSwVdecOpBuffer->nFilledLen != 0)
+ {
+ if ((m_pSwVdecOpBuffer->nHeight != rectangle.nHeight) ||
+ (m_pSwVdecOpBuffer->nWidth != rectangle.nWidth))
+ {
+ drv_ctx.video_resolution.frame_height = m_pSwVdecOpBuffer->nHeight;
+ drv_ctx.video_resolution.frame_width = m_pSwVdecOpBuffer->nWidth;
+
+ rectangle.nLeft = 0;
+ rectangle.nTop = 0;
+ rectangle.nWidth = m_pSwVdecOpBuffer->nWidth;
+ rectangle.nHeight = m_pSwVdecOpBuffer->nHeight;
+
+ DEBUG_PRINT_HIGH("swvdec_fill_buffer_done rectangle.WxH: %lu %lu",
+ rectangle.nWidth, rectangle.nHeight);
+
+ post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
+ OMX_COMPONENT_GENERATE_PORT_RECONFIG);
+ }
+ }
+
+ if (dynamic_buf_mode && m_pSwVdecOpBuffer->nFilledLen)
+ {
+ bufHdr->nFilledLen = bufHdr->nAllocLen;
+ }
+ if (bufHdr->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ DEBUG_PRINT_HIGH("swvdec output EOS reached");
+ }
+ DEBUG_PRINT_LOW("swvdec_fill_buffer_done bufHdr %p pBuffer %p SwvdecOpBuffer %p idx %lu nFilledLen %lu nAllocLen %lu nFlags %lx",
+ bufHdr, bufHdr->pBuffer, m_pSwVdecOpBuffer->pBuffer, index, m_pSwVdecOpBuffer->nFilledLen, bufHdr->nAllocLen, m_pSwVdecOpBuffer->nFlags);
+ post_event((unsigned long)bufHdr, (unsigned long)VDEC_S_SUCCESS, (unsigned long)OMX_COMPONENT_GENERATE_FBD);
+}
+
+SWVDEC_STATUS omx_vdec::swvdec_handle_event_cb
+(
+ SWVDEC_HANDLE pSwDec,
+ SWVDEC_EVENTHANDLER* pEventHandler,
+ void *pClientHandle
+)
+{
+ (void)pSwDec;
+ omx_vdec *omx = reinterpret_cast<omx_vdec*>(pClientHandle);
+ omx->swvdec_handle_event(pEventHandler);
+ return SWVDEC_S_SUCCESS;
+}
+
+void omx_vdec::swvdec_handle_event(SWVDEC_EVENTHANDLER *pEvent)
+{
+ switch(pEvent->eEvent)
+ {
+ case SWVDEC_FLUSH_DONE:
+ DEBUG_PRINT_ERROR("SWVDEC_FLUSH_DONE input_flush_progress %d output_flush_progress %d",
+ input_flush_progress, output_flush_progress);
+ if (input_flush_progress)
+ {
+ post_event ((unsigned long)NULL, (unsigned long)VDEC_S_SUCCESS, (unsigned long)OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
+ }
+ if (output_flush_progress)
+ {
+ post_event ((unsigned long)NULL, (unsigned long)VDEC_S_SUCCESS, (unsigned long)OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
+ }
+ break;
+
+ case SWVDEC_RECONFIG_SUFFICIENT_RESOURCES:
+ {
+ DEBUG_PRINT_HIGH("swvdec port settings changed info");
+ if (false == m_smoothstreaming_mode)
+ {
+ // get_buffer_req and populate port defn structure
+ SWVDEC_PROP prop;
+ prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ SwVdec_GetProperty(m_pSwVdec, &prop);
+
+ update_resolution(prop.uProperty.sDimensions.nWidth,
+ prop.uProperty.sDimensions.nHeight,
+ prop.uProperty.sDimensions.nWidth,
+ prop.uProperty.sDimensions.nHeight);
+ drv_ctx.video_resolution.stride = (prop.uProperty.sDimensions.nWidth + 127) & (~127);
+ drv_ctx.video_resolution.scan_lines = (prop.uProperty.sDimensions.nHeight + 31) & (~31);
+
+ m_port_def.nPortIndex = 1;
+ update_portdef(&m_port_def);
+ post_event ((unsigned)NULL, VDEC_S_SUCCESS, OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
+ }
+ }
+ break;
+
+ case SWVDEC_RECONFIG_INSUFFICIENT_RESOURCES:
+ {
+ SWVDEC_PROP prop;
+ DEBUG_PRINT_HIGH("swvdec port settings changed");
+ in_reconfig = true;
+ // get_buffer_req and populate port defn structure
+ prop.ePropId = SWVDEC_PROP_ID_DIMENSIONS;
+ SwVdec_GetProperty(m_pSwVdec, &prop);
+
+ update_resolution(prop.uProperty.sDimensions.nWidth,
+ prop.uProperty.sDimensions.nHeight,
+ prop.uProperty.sDimensions.nWidth,
+ prop.uProperty.sDimensions.nHeight);
+ drv_ctx.video_resolution.stride =
+ (prop.uProperty.sDimensions.nWidth + 127) & (~127);
+ drv_ctx.video_resolution.scan_lines =
+ (prop.uProperty.sDimensions.nHeight + 31) & (~31);
+
+ m_port_def.nPortIndex = 1;
+ update_portdef(&m_port_def);
+
+ //Set property for dimensions and attrb to SwVdec
+ SwVdec_SetProperty(m_pSwVdec,&prop);
+ prop.ePropId = SWVDEC_PROP_ID_FRAME_ATTR;
+ prop.uProperty.sFrameAttr.eColorFormat = SWVDEC_FORMAT_NV12;
+ SwVdec_SetProperty(m_pSwVdec,&prop);
+
+ post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
+ OMX_COMPONENT_GENERATE_PORT_RECONFIG);
+ }
+ break;
+
+ case SWVDEC_ERROR:
+ {
+ DEBUG_PRINT_ERROR("swvdec fatal error");
+ post_event ((unsigned)NULL, VDEC_S_SUCCESS,\
+ OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+ }
+ break;
+
+ case SWVDEC_RELEASE_BUFFER_REFERENCE:
+ {
+ SWVDEC_OPBUFFER* pOpBuffer = (SWVDEC_OPBUFFER *)pEvent->pEventData;
+ if (pOpBuffer == NULL)
+ {
+ DEBUG_PRINT_ERROR("swvdec release buffer reference for null buffer");
+ }
+ unsigned long idx = (unsigned long)pOpBuffer->pClientBufferData;
+ DEBUG_PRINT_HIGH("swvdec release buffer reference idx %lu", idx);
+
+ if (idx < drv_ctx.op_buf.actualcount)
+ {
+ DEBUG_PRINT_LOW("swvdec REFERENCE RELEASE EVENT fd = %d offset = %u buf idx %lu pBuffer %p",
+ drv_ctx.ptr_outputbuffer[idx].pmem_fd, drv_ctx.ptr_outputbuffer[idx].offset,
+ idx, drv_ctx.ptr_outputbuffer[idx].bufferaddr);
+ buf_ref_remove(drv_ctx.ptr_outputbuffer[idx].pmem_fd,
+ drv_ctx.ptr_outputbuffer[idx].offset);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ // put into the event command q
+ // m_cmd_q.insert_entry((unsigned int)NULL,
+ // SWVDEC_S_SUCCESS,
+ // OMX_COMPONENT_GENERATE_STOP_DONE_SWVDEC);
+ // post_message(this, OMX_COMPONENT_GENERATE_STOP_DONE_SWVDEC);
+}
+
+bool omx_vdec::execute_input_flush_swvdec()
+{
+ int idx =0;
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ DEBUG_PRINT_LOW("execute_input_flush_swvdec qsize %d, actual %d",
+ m_etb_q_swvdec.m_size, drv_ctx.interm_op_buf.actualcount);
+
+ pthread_mutex_lock(&m_lock);
+ while (m_etb_q_swvdec.m_size)
+ {
+ OMX_BUFFERHEADERTYPE* bufHdr = NULL;
+ m_etb_q_swvdec.pop_entry(&p1,&p2,&ident);
+ if (ident == OMX_COMPONENT_GENERATE_ETB_SWVDEC)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p2;
+ }
+ else if (ident == OMX_COMPONENT_GENERATE_EBD_SWVDEC)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p1;
+ }
+ idx = (bufHdr - m_interm_mem_ptr);
+ if (idx >= 0 && idx < (int)drv_ctx.interm_op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("execute_input_flush_swvdec flushed buffer idx %d", idx);
+ m_interm_buf_state[idx] = WITH_COMPONENT;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("execute_input_flush_swvdec issue: invalid idx %d", idx);
+ }
+ }
+ m_interm_flush_swvdec_progress = false;
+ pthread_mutex_unlock(&m_lock);
+
+ for (idx = 0; idx < (int)drv_ctx.interm_op_buf.actualcount; idx++)
+ {
+ DEBUG_PRINT_LOW("Flush swvdec interm bufq idx %d, state %d", idx, m_interm_buf_state[idx]);
+ // m_interm_buf_state[idx] = WITH_COMPONENT;
+ }
+
+ return true;
+}
+
+
+bool omx_vdec::execute_output_flush_dsp()
+{
+ int idx =0;
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ DEBUG_PRINT_LOW("execute_output_flush_dsp qsize %d, actual %d",
+ m_ftb_q_dsp.m_size, drv_ctx.interm_op_buf.actualcount);
+
+ pthread_mutex_lock(&m_lock);
+ while (m_ftb_q_dsp.m_size)
+ {
+ OMX_BUFFERHEADERTYPE* bufHdr = NULL;
+ m_ftb_q_dsp.pop_entry(&p1,&p2,&ident);
+ if (ident == OMX_COMPONENT_GENERATE_FTB_DSP)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p2;
+ }
+ else if (ident == OMX_COMPONENT_GENERATE_FBD_DSP)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE*)p1;
+ }
+ idx = (bufHdr - m_interm_mem_ptr);
+ if (idx >= 0 && idx < (int)drv_ctx.interm_op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("execute_output_flush_dsp flushed buffer idx %d", idx);
+ m_interm_buf_state[idx] = WITH_COMPONENT;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("execute_output_flush_dsp issue: invalid idx %d", idx);
+ }
+ }
+ m_interm_flush_dsp_progress = false;
+ m_fill_internal_bufers = OMX_TRUE;
+ pthread_mutex_unlock(&m_lock);
+
+ for (idx = 0; idx < (int)drv_ctx.interm_op_buf.actualcount; idx++)
+ {
+ DEBUG_PRINT_LOW("Flush dsp interm bufq idx %d, state %d", idx, m_interm_buf_state[idx]);
+ // m_interm_buf_state[idx] = WITH_COMPONENT;
+ }
+ return true;
+}
+
+OMX_ERRORTYPE omx_vdec::free_interm_buffers()
+{
+ free_extradata();
+
+ if (drv_ctx.ptr_interm_outputbuffer)
+ {
+ for(unsigned long i=0; i< drv_ctx.interm_op_buf.actualcount; i++)
+ {
+ if (drv_ctx.ptr_interm_outputbuffer[i].pmem_fd > 0)
+ {
+ DEBUG_PRINT_LOW("Free interm ouput Buffer index = %lu addr = %p", i,
+ drv_ctx.ptr_interm_outputbuffer[i].bufferaddr);
+
+ munmap (drv_ctx.ptr_interm_outputbuffer[i].bufferaddr,
+ drv_ctx.ptr_interm_outputbuffer[i].mmaped_size);
+ close(drv_ctx.ptr_interm_outputbuffer[i].pmem_fd);
+ drv_ctx.ptr_interm_outputbuffer[i].pmem_fd = 0;
+ free_ion_memory(&drv_ctx.interm_op_buf_ion_info[i]);
+ }
+ }
+ }
+
+ if (m_interm_mem_ptr)
+ {
+ free(m_interm_mem_ptr);
+ m_interm_mem_ptr = NULL;
+ }
+
+ if (drv_ctx.ptr_interm_respbuffer)
+ {
+ free (drv_ctx.ptr_interm_respbuffer);
+ drv_ctx.ptr_interm_respbuffer = NULL;
+ }
+
+ if (drv_ctx.ptr_interm_outputbuffer)
+ {
+ free (drv_ctx.ptr_interm_outputbuffer);
+ drv_ctx.ptr_interm_outputbuffer = NULL;
+ }
+
+ if (drv_ctx.interm_op_buf_ion_info) {
+ free(drv_ctx.interm_op_buf_ion_info);
+ drv_ctx.interm_op_buf_ion_info = NULL;
+ }
+
+ if (!in_reconfig || m_swvdec_mode == SWVDEC_MODE_DECODE_ONLY)
+ {
+ if (m_pSwVdecIpBuffer)
+ {
+ free(m_pSwVdecIpBuffer);
+ m_pSwVdecIpBuffer = NULL;
+ }
+ }
+
+ if (m_pSwVdecOpBuffer)
+ {
+ free(m_pSwVdecOpBuffer);
+ m_pSwVdecOpBuffer = NULL;
+ }
+
+ m_interm_bEnabled = OMX_FALSE;
+ m_interm_bPopulated = OMX_FALSE;
+ return OMX_ErrorNone;
+}
+
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
new file mode 100644
index 0000000..90b930a
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -0,0 +1,12700 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010 - 2016, 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
+
+ This module contains the implementation of the OpenMAX core & component.
+
+*//*========================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
+#include <string.h>
+#include <pthread.h>
+#include <sys/prctl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include "omx_vdec.h"
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <media/hardware/HardwareAPI.h>
+#include <media/msm_media_info.h>
+#include <sys/eventfd.h>
+
+#ifndef _ANDROID_
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#endif //_ANDROID_
+
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#undef USE_EGL_IMAGE_GPU
+#endif
+
+#include <qdMetaData.h>
+#include <gralloc_priv.h>
+
+#ifdef ANDROID_JELLYBEAN_MR2
+#include "QComOMXMetadata.h"
+#endif
+
+#ifdef USE_EGL_IMAGE_GPU
+#include <EGL/egl.h>
+#include <EGL/eglQCOM.h>
+#define EGL_BUFFER_HANDLE 0x4F00
+#define EGL_BUFFER_OFFSET 0x4F01
+#endif
+
+#define BUFFER_LOG_LOC "/data/misc/media"
+
+#ifdef OUTPUT_EXTRADATA_LOG
+FILE *outputExtradataFile;
+char output_extradata_filename [] = "/data/misc/media/extradata";
+#endif
+
+#define DEFAULT_FPS 30
+#define MAX_SUPPORTED_FPS 240
+#define DEFAULT_WIDTH_ALIGNMENT 128
+#define DEFAULT_HEIGHT_ALIGNMENT 32
+
+#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"
+
+#ifdef _ANDROID_
+extern "C" {
+#include<utils/Log.h>
+}
+#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) ? (__num_planes) - 1 : 0)
+#define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
+
+#define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_FRAMEPACK_EXTRADATA | OMX_OUTPUTCROP_EXTRADATA | OMX_DISPLAY_INFO_EXTRADATA)
+#define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default
+
+#ifndef ION_FLAG_CP_BITSTREAM
+#define ION_FLAG_CP_BITSTREAM 0
+#endif
+
+#ifndef ION_FLAG_CP_PIXEL
+#define ION_FLAG_CP_PIXEL 0
+#endif
+
+#ifdef MASTER_SIDE_CP
+#define MEM_HEAP_ID ION_SECURE_HEAP_ID
+#define SECURE_ALIGN SZ_4K
+#define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM)
+#define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL)
+#else //SLAVE_SIDE_CP
+#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
+#define SECURE_ALIGN SZ_1M
+#define SECURE_FLAGS_INPUT_BUFFER ION_SECURE
+#define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE
+#endif
+
+static OMX_U32 maxSmoothStreamingWidth = 1920;
+static OMX_U32 maxSmoothStreamingHeight = 1088;
+
+void* async_message_thread (void *input)
+{
+ OMX_BUFFERHEADERTYPE *buffer;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ struct pollfd pfds[2];
+ struct v4l2_buffer v4l2_buf;
+ memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
+ struct v4l2_event dqevent;
+ omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
+ pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
+ pfds[1].events = POLLIN | POLLERR;
+ pfds[0].fd = omx->drv_ctx.video_driver_fd;
+ pfds[1].fd = omx->m_poll_efd;
+ int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
+ DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
+ prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
+ while (!omx->async_thread_force_stop) {
+ rc = poll(pfds, 2, POLL_TIMEOUT);
+ if (!rc) {
+ DEBUG_PRINT_ERROR("Poll timedout");
+ break;
+ } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
+ DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
+ break;
+ }
+ if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
+ DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited");
+ break;
+ }
+ if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
+ struct vdec_msginfo vdec_msg;
+ memset(&vdec_msg, 0, sizeof(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(pfds[0].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 (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ }
+ }
+ if ((pfds[0].revents & POLLOUT) || (pfds[0].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(pfds[0].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("async_message_thread Exited");
+ break;
+ }
+ }
+ }
+ if (pfds[0].revents & POLLPRI) {
+ rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
+ if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
+ struct vdec_msginfo vdec_msg;
+ unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
+
+ vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
+ vdec_msg.status_code=VDEC_S_SUCCESS;
+ vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
+ vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
+ DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient");
+ if(ptr[2] & V4L2_EVENT_BITDEPTH_FLAG) {
+ omx->dpb_bit_depth = ptr[3];
+ DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth change - %d", ptr[3]);
+ }
+ if(ptr[2] & V4L2_EVENT_PICSTRUCT_FLAG) {
+ omx->m_progressive = ptr[4];
+ DEBUG_PRINT_HIGH("VIDC Port Reconfig PicStruct change - %d", ptr[4]);
+ }
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ 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");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ 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");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
+ struct vdec_msginfo vdec_msg;
+ vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
+ vdec_msg.status_code=VDEC_S_SUCCESS;
+ DEBUG_PRINT_ERROR("HW Overload received");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
+ struct vdec_msginfo vdec_msg;
+ vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
+ vdec_msg.status_code=VDEC_S_SUCCESS;
+ DEBUG_PRINT_ERROR("HW Unsupported received");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ 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("SYS Error Recieved");
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exited");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
+ unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
+
+ DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
+ unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
+ struct vdec_msginfo vdec_msg;
+
+ DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
+
+ 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;
+ v4l2_buf.index = ptr[5];
+ v4l2_buf.flags = 0;
+
+ 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 = 0;
+ vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
+ vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
+ (uint64_t)ptr[4];
+ if (omx->async_message_process(input,&vdec_msg) < 0) {
+ DEBUG_PRINT_HIGH("async_message_thread Exitedn");
+ break;
+ }
+ } else {
+ DEBUG_PRINT_HIGH("VIDC Some Event recieved");
+ continue;
+ }
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
+ return NULL;
+}
+
+void* message_thread_dec(void *input)
+{
+ omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
+ unsigned char id;
+ int n;
+
+ fd_set readFds;
+ int res = 0;
+ struct timeval tv;
+
+ DEBUG_PRINT_HIGH("omx_vdec: message thread start");
+ prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
+ while (!omx->message_thread_stop) {
+
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+
+ FD_ZERO(&readFds);
+ FD_SET(omx->m_pipe_in, &readFds);
+
+ res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv);
+ if (res < 0) {
+ DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno));
+ continue;
+ } else if (res == 0 /*timeout*/ || omx->message_thread_stop) {
+ continue;
+ }
+
+ 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_LOW("ERROR: 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);
+ if (ret_value <= 0) {
+ DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno));
+ } else {
+ 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 long p1, unsigned long p2, unsigned long 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", __func__);
+ }
+ return ret;
+}
+
+// omx cmd queue pop
+bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *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,
+ ion_user_handle_t handle, int ionMapfd)
+{
+ (void) devicefd;
+ (void) size;
+ (void) base;
+ (void) handle;
+ (void) 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),
+ 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),
+ h264_parser(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),
+ m_disp_hor_size(0),
+ m_disp_vert_size(0),
+ prev_ts(LLONG_MAX),
+ prev_ts_actual(LLONG_MAX),
+ rst_prev_ts(true),
+ frm_int(0),
+ in_reconfig(false),
+ m_display_id(NULL),
+ client_extradata(0),
+ m_reject_avc_1080p_mp (0),
+#ifdef _ANDROID_
+ m_enable_android_native_buffers(OMX_FALSE),
+ m_use_android_native_buffers(OMX_FALSE),
+#endif
+ m_desc_buffer_ptr(NULL),
+ secure_mode(false),
+ allocate_native_handle(false),
+ m_other_extradata(NULL),
+ m_profile(0),
+ client_set_fps(false),
+ stereo_output_mode(HAL_NO_3D),
+ m_last_rendered_TS(-1),
+ m_queued_codec_config_count(0),
+ current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL),
+ secure_scaling_to_non_secure_opb(false),
+ m_force_compressed_for_dpb(false),
+ m_is_display_session(false)
+{
+ m_pipe_in = -1;
+ m_pipe_out = -1;
+ m_poll_efd = -1;
+ drv_ctx.video_driver_fd = -1;
+ drv_ctx.extradata_info.ion.fd_ion_data.fd = -1;
+ /* Assumption is that , to begin with , we have all the frames with decoder */
+ DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
+ memset(&m_debug,0,sizeof(m_debug));
+#ifdef _ANDROID_
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+ property_get("vidc.debug.level", property_value, "1");
+ debug_level = atoi(property_value);
+ property_value[0] = '\0';
+
+ DEBUG_PRINT_HIGH("In OMX vdec Constructor");
+
+ 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);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.profile.check", property_value, "0");
+ m_reject_avc_1080p_mp = atoi(property_value);
+ DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.log.in", property_value, "0");
+ m_debug.in_buffer_log = atoi(property_value);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.log.out", property_value, "0");
+ m_debug.out_buffer_log = atoi(property_value);
+ snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.meta.log.out", property_value, "0");
+ m_debug.out_meta_buffer_log = atoi(property_value);
+ snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
+
+ property_value[0] = '\0';
+ property_get("vidc.log.loc", property_value, "");
+ if (*property_value)
+ strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.120fps.enabled", property_value, "0");
+
+ //if this feature is not enabled then reset this value -ve
+ if(atoi(property_value)) {
+ DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
+ m_last_rendered_TS = 0;
+ }
+
+ property_value[0] = '\0';
+ property_get("vidc.dec.debug.dyn.disabled", property_value, "0");
+ m_disable_dynamic_buf_mode = atoi(property_value);
+ DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode);
+
+#ifdef _UBWC_
+ property_value[0] = '\0';
+ property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
+ m_disable_ubwc_mode = atoi(property_value);
+ DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled");
+#else
+ m_disable_ubwc_mode = true;
+#endif
+#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) );
+ memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
+ memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams));
+ memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams));
+ m_demux_entries = 0;
+ msg_thread_id = 0;
+ async_thread_id = 0;
+ msg_thread_created = false;
+ async_thread_created = false;
+ async_thread_force_stop = false;
+ message_thread_stop = 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));
+
+ /* invalidate m_frame_pack_arrangement */
+ memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
+ m_frame_pack_arrangement.cancel_flag = 1;
+
+ drv_ctx.timestamp_adjust = false;
+ m_vendor_config.pData = NULL;
+ pthread_mutex_init(&m_lock, NULL);
+ pthread_mutex_init(&c_lock, NULL);
+ pthread_mutex_init(&buf_lock, NULL);
+ sem_init(&m_cmd_lock,0,0);
+ sem_init(&m_safe_flush, 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);
+ dynamic_buf_mode = false;
+ out_dynamic_list = NULL;
+ is_down_scalar_enabled = false;
+ m_downscalar_width = 0;
+ m_downscalar_height = 0;
+ m_force_down_scalar = 0;
+ m_reconfig_height = 0;
+ m_reconfig_width = 0;
+ m_smoothstreaming_mode = false;
+ m_smoothstreaming_width = 0;
+ m_smoothstreaming_height = 0;
+ is_q6_platform = false;
+ m_perf_control.send_hint_to_mpctl(true);
+ m_input_pass_buffer_fd = false;
+ memset(&m_extradata_info, 0, sizeof(m_extradata_info));
+ m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
+ m_client_color_space.sAspects.mRange = ColorAspects::RangeUnspecified;
+ m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
+ m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
+ m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
+
+ m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
+ m_internal_color_space.sAspects.mRange = ColorAspects::RangeUnspecified;
+ m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
+ m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
+ m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
+ m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams);
+}
+
+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_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT,
+ V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
+ V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
+ V4L2_EVENT_MSM_VIDC_SYS_ERROR,
+ V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
+ V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
+};
+
+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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", 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)
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", 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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", 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;
+ DEBUG_PRINT_HIGH("In OMX vdec Destructor");
+ if (msg_thread_created) {
+ DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread");
+ message_thread_stop = true;
+ post_message(this, OMX_COMPONENT_CLOSE_MSG);
+ DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
+ pthread_join(msg_thread_id,NULL);
+ }
+ close(m_pipe_in);
+ close(m_pipe_out);
+ m_pipe_in = -1;
+ m_pipe_out = -1;
+ DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
+ if(eventfd_write(m_poll_efd, 1)) {
+ DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
+ async_thread_force_stop = true;
+ }
+
+ if (async_thread_created)
+ pthread_join(async_thread_id,NULL);
+ unsubscribe_to_events(drv_ctx.video_driver_fd);
+ close(m_poll_efd);
+ close(drv_ctx.video_driver_fd);
+ pthread_mutex_destroy(&m_lock);
+ pthread_mutex_destroy(&c_lock);
+ pthread_mutex_destroy(&buf_lock);
+ sem_destroy(&m_cmd_lock);
+ if (perf_flag) {
+ DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
+ dec_time.end();
+ }
+ DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
+ m_perf_control.send_hint_to_mpctl(false);
+}
+
+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);
+ } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = 0;
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
+ }
+ return rc;
+}
+
+OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format)
+{
+ int rc = 0;
+ struct v4l2_ext_control ctrl[2];
+ struct v4l2_ext_controls controls;
+
+ DEBUG_PRINT_HIGH("DPB mode: %s DPB color format: %s OPB color format: %s",
+ is_split_mode ? "split" : "combined",
+ dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC ? "nv12_ubwc":
+ dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC ? "nv12_10bit_ubwc":
+ dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE ? "same as opb":
+ "unknown",
+ capture_capability == V4L2_PIX_FMT_NV12 ? "nv12":
+ capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc":
+ "unknown");
+
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
+ if (is_split_mode) {
+ ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
+ } else {
+ ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
+ }
+
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT;
+ ctrl[1].value = dpb_color_format;
+
+ controls.count = 2;
+ controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ controls.controls = ctrl;
+
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ return OMX_ErrorNone;
+}
+
+
+OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool force_split_mode)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ struct v4l2_format fmt;
+ int rc = 0;
+
+ if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
+ !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
+ DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
+ return eRet;
+ }
+
+ bool cpu_access = capture_capability != V4L2_PIX_FMT_NV12_UBWC;
+
+ if (cpu_access) {
+ if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
+ if ((m_force_compressed_for_dpb || (m_progressive && (eCompressionFormat != OMX_VIDEO_CodingVP9))) &&
+ !force_split_mode && !m_disable_split_mode && !drv_ctx.idr_only_decoding) {
+ /* Disabled split mode for VP9. In split mode the DPB buffers are part of the internal
+ * scratch buffers and the driver does not does the reference buffer management for
+ * scratch buffers. In case of VP9 with spatial scalability, when a sequence changed
+ * event is received with the new resolution, and when a flush is sent by the driver, it
+ * releases all the references of internal scratch buffers. However as per the VP9
+ * spatial scalability, even after the flush, the buffers which have not yet received
+ * release reference event should not be unmapped and freed. Currently in driver,
+ * reference buffer management of the internal scratch buffer is not implemented
+ * and hence the DPB buffers get unmapped. For other codecs it does not matter
+ * as with the new SPS/PPS, the DPB is flushed.
+ */
+ //split DPB-OPB
+ //DPB -> UBWC , OPB -> Linear
+ eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
+ } else if (force_split_mode) {
+ //DPB -> Linear, OPB -> Linear
+ eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
+ } else {
+ //DPB-OPB combined linear
+ eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
+ }
+ } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
+ //split DPB-OPB
+ //DPB -> UBWC, OPB -> Linear
+ eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
+ }
+ } else { //no cpu access
+ if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
+ if (force_split_mode) {
+ //split DPB-OPB
+ //DPB -> UBWC, OPB -> UBWC
+ eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
+ } else {
+ //DPB-OPB combined UBWC
+ eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
+ }
+ } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
+ //split DPB-OPB
+ //DPB -> UBWC, OPB -> UBWC
+ eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
+ }
+ }
+ if (eRet) {
+ DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
+ }
+
+ //Restore the capture format again here, because
+ //in switching between different DPB-OPB modes, the pixelformat
+ //on capture port may be changed. Don't change resolutions.
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ if (rc) {
+ DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ return eRet;
+}
+
+int omx_vdec::enable_downscalar()
+{
+ int rc = 0;
+ struct v4l2_control control;
+ struct v4l2_format fmt;
+
+ if (is_down_scalar_enabled) {
+ DEBUG_PRINT_LOW("%s: already enabled", __func__);
+ return 0;
+ }
+
+ DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
+ rc = decide_dpb_buffer_mode(true);
+ if (rc) {
+ DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
+ return rc;
+ }
+ is_down_scalar_enabled = true;
+
+ memset(&control, 0x0, sizeof(struct v4l2_control));
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
+ control.value = 1;
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__);
+ return rc;
+ }
+
+ return 0;
+}
+
+int omx_vdec::disable_downscalar()
+{
+ int rc = 0;
+ struct v4l2_control control;
+
+ if (!is_down_scalar_enabled) {
+ DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
+ return 0;
+ }
+
+ rc = decide_dpb_buffer_mode(false);
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
+ return rc;
+ }
+ is_down_scalar_enabled = false;
+
+ return rc;
+}
+
+int omx_vdec::decide_downscalar()
+{
+ int rc = 0;
+ struct v4l2_format fmt;
+ enum color_fmts color_format;
+ OMX_U32 width, height;
+
+ if (!m_downscalar_width || !m_downscalar_height) {
+ DEBUG_PRINT_LOW("%s: downscalar not supported", __func__);
+ return 0;
+ }
+
+ if (m_force_down_scalar) {
+ DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
+ return 0;
+ }
+
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
+ return rc;
+ }
+
+ height = fmt.fmt.pix_mp.height;
+ width = fmt.fmt.pix_mp.width;
+
+ DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__,
+ fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session);
+
+ if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height >= m_downscalar_width * m_downscalar_height) &&
+ m_is_display_session) {
+ rc = enable_downscalar();
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
+ return rc;
+ }
+
+ width = m_downscalar_width > fmt.fmt.pix_mp.width ?
+ fmt.fmt.pix_mp.width : m_downscalar_width;
+ height = m_downscalar_height > fmt.fmt.pix_mp.height ?
+ fmt.fmt.pix_mp.height : m_downscalar_height;
+ switch (capture_capability) {
+ case V4L2_PIX_FMT_NV12:
+ color_format = COLOR_FMT_NV12;
+ break;
+ case V4L2_PIX_FMT_NV12_UBWC:
+ color_format = COLOR_FMT_NV12_UBWC;
+ break;
+ case V4L2_PIX_FMT_NV12_TP10_UBWC:
+ color_format = COLOR_FMT_NV12_BPP10_UBWC;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("Color format not recognized\n");
+ rc = OMX_ErrorUndefined;
+ return rc;
+ }
+ } else {
+
+ rc = disable_downscalar();
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
+ return rc;
+ }
+ }
+
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = height;
+ fmt.fmt.pix_mp.width = width;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ if (rc) {
+ DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
+ return rc;
+ }
+
+ rc = get_buffer_req(&drv_ctx.op_buf);
+ if (rc) {
+ DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
+ return rc;
+ }
+
+ 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)
+{
+ unsigned long p1; // Parameter - 1
+ unsigned long p2; // Parameter - 2
+ unsigned long ident;
+ unsigned qsize=0; // qsize
+ omx_vdec *pThis = (omx_vdec *) ctxt;
+
+ if (!pThis) {
+ DEBUG_PRINT_ERROR("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("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 == (unsigned long)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("OMX_CommandPortDisable complete for port [%lu]", 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");
+ 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("OMX_CommandPortEnable complete for port [%lu]", 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", __func__);
+ }
+ break;
+ case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
+ if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
+ pThis->omx_report_error ();
+ }
+ break;
+ case OMX_COMPONENT_GENERATE_ETB: {
+ OMX_ERRORTYPE iret;
+ iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
+ if (iret == OMX_ErrorInsufficientResources) {
+ DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
+ pThis->omx_report_hw_overload ();
+ } else if (iret != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
+ pThis->omx_report_error ();
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FTB:
+ if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
+ (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("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("OMX_COMPONENT_GENERATE_EBD failure");
+ pThis->omx_report_error ();
+ } else {
+ if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
+ pThis->time_stamp_dts.remove_time_stamp(
+ ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
+ (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
+ ?true:false);
+ }
+
+ if ( pThis->empty_buffer_done(&pThis->m_cmp,
+ (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("empty_buffer_done failure");
+ pThis->omx_report_error ();
+ }
+ }
+ break;
+ case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
+ int64_t *timestamp = (int64_t *)(intptr_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("OMX_COMPONENT_GENERATE_FBD failure");
+ pThis->omx_report_error ();
+ } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
+ (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
+ DEBUG_PRINT_ERROR("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_HIGH("WARNING: Unexpected flush from driver");
+ } else {
+ pThis->execute_input_flush();
+ if (pThis->m_cb.EventHandler) {
+ if (p2 != VDEC_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("OMX_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->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
+ pThis->omx_report_error ();
+ } else {
+ pThis->streaming[OUTPUT_PORT] = false;
+ }
+ if (!pThis->output_flush_progress) {
+ DEBUG_PRINT_LOW("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("Driver flush o/p Port complete");
+ if (!pThis->output_flush_progress) {
+ DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
+ } else {
+ pThis->execute_output_flush();
+ if (pThis->m_cb.EventHandler) {
+ if (p2 != VDEC_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("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);
+ BITMASK_CLEAR (&pThis->m_flags,
+ OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
+
+ }
+ }
+
+ if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
+ if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
+ pThis->omx_report_error ();
+ break;
+ }
+ pThis->streaming[CAPTURE_PORT] = false;
+ if (!pThis->input_flush_progress) {
+ DEBUG_PRINT_LOW("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("Rxd OMX_COMPONENT_GENERATE_START_DONE");
+
+ if (pThis->m_cb.EventHandler) {
+ if (p2 != VDEC_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("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("VDEC_IOCTL_CMD_PAUSE failed");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ } else {
+ DEBUG_PRINT_LOW("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("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("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:
+ if (p2 == OMX_IndexParamPortDefinition) {
+ DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
+ pThis->in_reconfig = true;
+ } else if (p2 == OMX_IndexConfigCommonOutputCrop) {
+ DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
+
+ /* Check if resolution is changed in smooth streaming mode */
+ if (pThis->m_smoothstreaming_mode &&
+ (pThis->framesize.nWidth !=
+ pThis->drv_ctx.video_resolution.frame_width) ||
+ (pThis->framesize.nHeight !=
+ pThis->drv_ctx.video_resolution.frame_height)) {
+
+ DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
+ pThis->framesize.nWidth,
+ pThis->framesize.nHeight,
+ pThis->drv_ctx.video_resolution.frame_width,
+ pThis->drv_ctx.video_resolution.frame_height);
+
+ /* Update new resolution */
+ pThis->framesize.nWidth =
+ pThis->drv_ctx.video_resolution.frame_width;
+ pThis->framesize.nHeight =
+ pThis->drv_ctx.video_resolution.frame_height;
+
+ /* Update C2D with new resolution */
+ if (!pThis->client_buffers.update_buffer_req()) {
+ DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
+ }
+ }
+
+ /* Update new crop information */
+ pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
+ pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
+ pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
+ pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
+
+ /* Validate the new crop information */
+ if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
+ pThis->drv_ctx.video_resolution.frame_width) {
+
+ DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
+ pThis->rectangle.nLeft, pThis->rectangle.nWidth,
+ pThis->drv_ctx.video_resolution.frame_width);
+ pThis->rectangle.nLeft = 0;
+
+ if (pThis->rectangle.nWidth >
+ pThis->drv_ctx.video_resolution.frame_width) {
+
+ DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
+ pThis->rectangle.nWidth,
+ pThis->drv_ctx.video_resolution.frame_width);
+ pThis->rectangle.nWidth =
+ pThis->drv_ctx.video_resolution.frame_width;
+ }
+ }
+ if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
+ pThis->drv_ctx.video_resolution.frame_height) {
+
+ DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
+ pThis->rectangle.nTop, pThis->rectangle.nHeight,
+ pThis->drv_ctx.video_resolution.frame_height);
+ pThis->rectangle.nTop = 0;
+
+ if (pThis->rectangle.nHeight >
+ pThis->drv_ctx.video_resolution.frame_height) {
+
+ DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
+ pThis->rectangle.nHeight,
+ pThis->drv_ctx.video_resolution.frame_height);
+ pThis->rectangle.nHeight =
+ pThis->drv_ctx.video_resolution.frame_height;
+ }
+ }
+ DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
+ pThis->rectangle.nLeft, pThis->rectangle.nTop,
+ pThis->rectangle.nWidth, pThis->rectangle.nHeight);
+ } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
+ DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
+ } else {
+ DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
+ break;
+ }
+ if (pThis->m_debug.outfile) {
+ fclose(pThis->m_debug.outfile);
+ pThis->m_debug.outfile = NULL;
+ }
+ if (pThis->m_debug.out_ymeta_file) {
+ fclose(pThis->m_debug.out_ymeta_file);
+ pThis->m_debug.out_ymeta_file = NULL;
+ }
+ if (pThis->m_debug.out_uvmeta_file) {
+ fclose(pThis->m_debug.out_uvmeta_file);
+ pThis->m_debug.out_uvmeta_file = NULL;
+ }
+
+ if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) {
+ pThis->prefetchNewBuffers();
+ }
+
+ if (pThis->m_cb.EventHandler) {
+ uint32_t frame_data[4];
+ frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ?
+ pThis->m_reconfig_height : pThis->rectangle.nHeight;
+ frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ?
+ pThis->m_reconfig_width : pThis->rectangle.nWidth;
+
+ frame_data[2] = (p2 == OMX_IndexParamPortDefinition) ?
+ frame_data[0] : pThis->drv_ctx.video_resolution.frame_height;
+
+ frame_data[3] = (p2 == OMX_IndexParamPortDefinition) ?
+ frame_data[1] : pThis->drv_ctx.video_resolution.frame_width;
+
+ pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data );
+ } 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("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
+ pThis->omx_report_error();
+ break;
+
+ case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
+ pThis->omx_report_unsupported_setting();
+ break;
+
+ case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
+ pThis->omx_report_hw_overload();
+ break;
+
+ 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 != (int)drv_ctx.video_resolution.frame_height) ||
+ (width != (int)drv_ctx.video_resolution.frame_width)) {
+ DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
+ 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;
+ if(!is_down_scalar_enabled) {
+ 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()
+{
+ if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
+ OMX_MAX_STRINGNAME_SIZE) &&
+ (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
+ m_decoder_capability.max_width = 1280;
+ m_decoder_capability.max_height = 720;
+ DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
+ }
+
+ 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("video session supported");
+ return OMX_ErrorNone;
+}
+
+int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
+{
+ if (m_debug.in_buffer_log && !m_debug.infile) {
+ if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc,
+ drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ } else {
+ snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ }
+ m_debug.infile = fopen (m_debug.infile_name, "ab");
+ if (!m_debug.infile) {
+ DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
+ m_debug.infile_name[0] = '\0';
+ return -1;
+ }
+ if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
+ 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;
+ switch (drv_ctx.decoder_format) {
+ case VDEC_CODECTYPE_VP8:
+ file_header.FourCC = 0x30385056;
+ break;
+ case VDEC_CODECTYPE_VP9:
+ file_header.FourCC = 0x30395056;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("unsupported format for VP8/VP9");
+ break;
+ }
+ fwrite((const char *)&file_header,
+ sizeof(file_header),1,m_debug.infile);
+ }
+ }
+ if (m_debug.infile && buffer_addr && buffer_len) {
+ if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
+ struct vpx_ivf_frame_header {
+ OMX_U32 framesize;
+ OMX_U32 timestamp_lo;
+ OMX_U32 timestamp_hi;
+ } vpx_frame_header;
+ vpx_frame_header.framesize = buffer_len;
+ /* Currently FW doesn't use timestamp values */
+ vpx_frame_header.timestamp_lo = 0;
+ vpx_frame_header.timestamp_hi = 0;
+ fwrite((const char *)&vpx_frame_header,
+ sizeof(vpx_frame_header),1,m_debug.infile);
+ }
+ fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
+ }
+ return 0;
+}
+
+int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
+ int buf_index = 0;
+ char *temp = NULL;
+
+ if (m_debug.out_buffer_log && !m_debug.outfile && buffer->nFilledLen) {
+ snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ m_debug.outfile = fopen (m_debug.outfile_name, "ab");
+ if (!m_debug.outfile) {
+ DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
+ m_debug.outfile_name[0] = '\0';
+ return -1;
+ }
+ }
+
+ if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file
+ && buffer->nFilledLen) {
+ snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
+ m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+ m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
+ m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
+ if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
+ DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
+ m_debug.out_ymetafile_name[0] = '\0';
+ m_debug.out_uvmetafile_name[0] = '\0';
+ return -1;
+ }
+ }
+
+ if ((!m_debug.outfile && !m_debug.out_ymeta_file) || !buffer || !buffer->nFilledLen)
+ return 0;
+
+ buf_index = buffer - m_out_mem_ptr;
+ temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
+
+ if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
+ DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
+ drv_ctx.video_resolution.frame_width,
+ drv_ctx.video_resolution.frame_height);
+
+ if (m_debug.outfile)
+ fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
+
+ if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
+ unsigned int width = 0, height = 0;
+ unsigned int y_plane, y_meta_plane;
+ int y_stride = 0, y_sclines = 0;
+ int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
+ int color_fmt = COLOR_FMT_NV12_UBWC;
+ int i;
+ int bytes_written = 0;
+
+ width = drv_ctx.video_resolution.frame_width;
+ height = drv_ctx.video_resolution.frame_height;
+ y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
+ y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
+ y_stride = VENUS_Y_STRIDE(color_fmt, width);
+ y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
+ uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
+ uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
+
+ y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
+ y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
+
+ temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
+ for (i = 0; i < y_meta_scanlines; i++) {
+ bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
+ temp += y_meta_stride;
+ }
+
+ temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane;
+ for(i = 0; i < uv_meta_scanlines; i++) {
+ bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
+ temp += uv_meta_stride;
+ }
+ }
+ } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12 && m_debug.outfile) {
+ int stride = drv_ctx.video_resolution.stride;
+ int scanlines = drv_ctx.video_resolution.scan_lines;
+ if (m_smoothstreaming_mode) {
+ stride = drv_ctx.video_resolution.frame_width;
+ scanlines = drv_ctx.video_resolution.frame_height;
+ stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
+ scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
+ }
+ unsigned i;
+ DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
+ drv_ctx.video_resolution.frame_width,
+ drv_ctx.video_resolution.frame_height, stride, scanlines);
+ 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, m_debug.outfile);
+ 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, m_debug.outfile);
+ temp += stride_c;
+ }
+ }
+ return 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 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/video32";
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+ FILE *soc_file = NULL;
+ char buffer[10];
+
+#ifdef _ANDROID_
+ char platform_name[PROPERTY_VALUE_MAX];
+ property_get("ro.board.platform", platform_name, "0");
+ if (!strncmp(platform_name, "msm8610", 7)) {
+ device_name = (OMX_STRING)"/dev/video/q6_dec";
+ is_q6_platform = true;
+ maxSmoothStreamingWidth = 1280;
+ maxSmoothStreamingHeight = 720;
+ }
+#endif
+
+ is_thulium_v1 = false;
+ soc_file = fopen("/sys/devices/soc0/soc_id", "r");
+ if (soc_file) {
+ fread(buffer, 1, 4, soc_file);
+ fclose(soc_file);
+ if (atoi(buffer) == 246) {
+ soc_file = fopen("/sys/devices/soc0/revision", "r");
+ if (soc_file) {
+ fread(buffer, 1, 4, soc_file);
+ fclose(soc_file);
+ if (atoi(buffer) == 1) {
+ is_thulium_v1 = true;
+ DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
+ }
+ }
+ }
+ }
+
+#ifdef _ANDROID_
+ /*
+ * turn off frame parsing for Android by default.
+ * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode
+ */
+ arbitrary_bytes = false;
+ property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
+ if (atoi(property_value)) {
+ DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command");
+ arbitrary_bytes = true;
+ }
+#endif
+
+ if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
+ } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
+ } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
+ } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.vc1";
+ } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.wmv";
+ } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4";
+ } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
+ }
+ else if (!strncmp(role, "OMX.qcom.video.decoder.vp8.secure",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ secure_mode = true;
+ arbitrary_bytes = false;
+ role = (OMX_STRING)"OMX.qcom.video.decoder.vp8";
+ }
+
+ drv_ctx.video_driver_fd = open(device_name, O_RDWR);
+
+ DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
+
+ if (drv_ctx.video_driver_fd < 0) {
+ DEBUG_PRINT_ERROR("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;
+ operating_frame_rate = DEFAULT_FPS;
+ high_fps = false;
+ m_poll_efd = eventfd(0, 0);
+ if (m_poll_efd < 0) {
+ DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
+ return OMX_ErrorInsufficientResources;
+ }
+ 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("Failed to create async_message_thread");
+ async_thread_created = false;
+ return OMX_ErrorInsufficientResources;
+ }
+
+#ifdef OUTPUT_EXTRADATA_LOG
+ outputExtradataFile = fopen (output_extradata_filename, "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);
+ } 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);
+ } 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;
+ output_capability = V4L2_PIX_FMT_H263;
+ codec_type_parse = CODEC_TYPE_H263;
+ m_frame_parser.init_start_codes(codec_type_parse);
+ } 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;
+ 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);
+
+ } 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;
+ 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);
+
+ } 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;
+ 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);
+
+ } 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);
+ if (is_thulium_v1) {
+ arbitrary_bytes = true;
+ DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264");
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
+ drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
+ output_capability = V4L2_PIX_FMT_H264_MVC;
+ eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
+ codec_type_parse = CODEC_TYPE_H264;
+ m_frame_parser.init_start_codes(codec_type_parse);
+ m_frame_parser.init_nal_length(nal_length);
+ } 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);
+ } 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);
+ } 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);
+ } 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);
+ drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
+ output_capability = V4L2_PIX_FMT_VP8;
+ eCompressionFormat = OMX_VIDEO_CodingVP8;
+ codec_type_parse = CODEC_TYPE_VP8;
+ arbitrary_bytes = false;
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", \
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
+ drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
+ output_capability = V4L2_PIX_FMT_VP9;
+ eCompressionFormat = OMX_VIDEO_CodingVP9;
+ codec_type_parse = CODEC_TYPE_VP9;
+ arbitrary_bytes = false;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR:Unknown Component");
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+
+ if (eRet == OMX_ErrorNone) {
+ OMX_COLOR_FORMATTYPE dest_color_format;
+ if (m_disable_ubwc_mode) {
+ drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
+ } else {
+ drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
+ }
+ if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
+ dest_color_format = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
+ else
+ dest_color_format = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ if (!client_buffers.set_color_format(dest_color_format)) {
+ DEBUG_PRINT_ERROR("Setting color format failed");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
+ m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
+
+ if (m_disable_ubwc_mode) {
+ capture_capability = V4L2_PIX_FMT_NV12;
+ } else {
+ capture_capability = V4L2_PIX_FMT_NV12_UBWC;
+ }
+
+ struct v4l2_capability cap;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to query capabilities");
+ /*TODO: How to handle this case */
+ } else {
+ DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
+ " version = %d, capabilities = %x", 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", 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", 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");
+ return OMX_ErrorInsufficientResources;
+ }
+ DEBUG_PRINT_HIGH("Set Format was successful");
+ 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");
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Codec should not be ambiguous");
+ }
+ }
+
+ property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
+ m_conceal_color= atoi(property_value);
+ DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color);
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
+ control.value = m_conceal_color;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
+ }
+
+ //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");
+ 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;
+ }
+
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ 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");
+ }
+ memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
+ framesize.nWidth = drv_ctx.video_resolution.frame_width;
+ framesize.nHeight = drv_ctx.video_resolution.frame_height;
+
+ memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
+ rectangle.nWidth = drv_ctx.video_resolution.frame_width;
+ rectangle.nHeight = drv_ctx.video_resolution.frame_height;
+
+ DEBUG_PRINT_HIGH("Set Format was successful");
+ 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", 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", ret);
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ if (output_capability == V4L2_PIX_FMT_H264_MVC) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT;
+ control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set MVC buffer layout");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+
+ if (is_thulium_v1) {
+ eRet = enable_smoothstreaming();
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver");
+ return eRet;
+ }
+ }
+
+ /*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 = SECURE_ALIGN;
+ drv_ctx.ip_buf.alignment = SECURE_ALIGN;
+ } 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;
+
+#ifdef _ANDROID_
+ property_get("vidc.dec.downscalar_width",property_value,"0");
+ if (atoi(property_value)) {
+ m_downscalar_width = atoi(property_value);
+ }
+ property_get("vidc.dec.downscalar_height",property_value,"0");
+ if (atoi(property_value)) {
+ m_downscalar_height = atoi(property_value);
+ }
+
+ if (m_downscalar_width < m_decoder_capability.min_width ||
+ m_downscalar_height < m_decoder_capability.min_height) {
+ m_downscalar_width = 0;
+ m_downscalar_height = 0;
+ }
+
+ DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n",
+ m_downscalar_width, m_downscalar_height);
+
+ property_get("vidc.disable.split.mode",property_value,"0");
+ m_disable_split_mode = atoi(property_value);
+ DEBUG_PRINT_HIGH("split mode is %s", m_disable_split_mode ? "disabled" : "enabled");
+#endif
+ m_state = OMX_StateLoaded;
+#ifdef DEFAULT_EXTRADATA
+ enable_extradata(DEFAULT_EXTRADATA, true, true);
+#endif
+ eRet = get_buffer_req(&drv_ctx.ip_buf);
+ DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)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 ||
+ drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
+ 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("h264_scratch.pBuffer Allocation failed ");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
+ drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
+ if (m_frame_parser.mutils == NULL) {
+ m_frame_parser.mutils = new H264_Utils();
+ if (m_frame_parser.mutils == NULL) {
+ DEBUG_PRINT_ERROR("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");
+ eRet = OMX_ErrorInsufficientResources;
+ } else {
+ m_pipe_in = fds[0];
+ m_pipe_out = fds[1];
+ msg_thread_created = true;
+ r = pthread_create(&msg_thread_id,0,message_thread_dec,this);
+
+ if (r < 0) {
+ DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed");
+ msg_thread_created = false;
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ }
+
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("Component Init Failed");
+ } else {
+ DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
+ drv_ctx.video_driver_fd);
+ }
+ //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
+ )
+{
+ (void) hComp;
+ (void) componentName;
+ (void) componentVersion;
+ (void) componentUUID;
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("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
+ )
+{
+ (void) hComp;
+ (void) cmdData;
+ DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("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("send_command(): ERROR OMX_CommandFlush "
+ "to invalid port: %u", (unsigned int)param1);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
+ sem_wait(&m_cmd_lock);
+ DEBUG_PRINT_LOW("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
+ )
+{
+ (void) hComp;
+ (void) cmdData;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_STATETYPE eState = (OMX_STATETYPE) param1;
+ int bFlag = 1,sem_posted = 0,ret=0;
+
+ DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
+ DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
+ 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("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");
+ 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");
+ 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");
+ 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)",\
+ 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");
+ } else {
+ DEBUG_PRINT_LOW("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_LOW("send_command_proxy(): Idle-->Executing");
+ //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
+ bFlag = 1;
+ DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
+ m_state=OMX_StateExecuting;
+ DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
+ }
+ /* Requesting transition from Idle to Idle */
+ else if (eState == OMX_StateIdle) {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
+ 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");
+ 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("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");
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Idle to Invalid */
+ else if (eState == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ /******************************/
+ /* Current State is Executing */
+ /******************************/
+ else if (m_state == OMX_StateExecuting) {
+ DEBUG_PRINT_LOW("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("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_LOW("PAUSE Command Issued");
+ m_state = OMX_StatePause;
+ bFlag = 1;
+ }
+ /* Requesting transition from Executing to Loaded */
+ else if (eState == OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
+ 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("send_command_proxy(): Executing --> WaitForResources");
+ 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("send_command_proxy(): Executing --> Executing");
+ 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("send_command_proxy(): Executing --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",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("Pause --> Executing");
+ 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("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("Pause --> loaded");
+ 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("Pause --> WaitForResources");
+ 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("Pause --> Pause");
+ 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("Pause --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",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");
+ }
+ /* Requesting transition from WaitForResources to WaitForResources */
+ else if (eState == OMX_StateWaitForResources) {
+ DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
+ 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");
+ 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");
+ 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");
+ 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)",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");
+ 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: %u", (unsigned int)param1);
+#ifdef _MSM8974_
+ send_codec_config();
+#endif
+ if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
+ param1 == OMX_ALL)) {
+ if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
+ struct timespec ts;
+
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += 2;
+ DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
+ m_queued_codec_config_count);
+ BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
+ if (sem_timedwait(&m_safe_flush, &ts)) {
+ DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
+ }
+ BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
+ }
+ }
+
+ 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: %u", (unsigned int)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");
+ 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("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");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
+ // Skip the event notification
+ bFlag = 0;
+ /* enable/disable downscaling if required */
+ ret = decide_downscalar();
+ if (ret) {
+ DEBUG_PRINT_LOW("decide_downscalar failed\n");
+ }
+ }
+ }
+ } else if (cmd == OMX_CommandPortDisable) {
+ DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
+ "with param1: %u", (unsigned int)param1);
+ if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
+ codec_config_flag = false;
+ 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("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)",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 %u", __func__, (unsigned int)flushType);
+ memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
+ dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
+
+ DEBUG_PRINT_HIGH("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;
+ request_perf_level(VIDC_TURBO);
+ }
+
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
+ DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)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 long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ /*Generate FBD for all Buffers in the FTBq*/
+ pthread_mutex_lock(&m_lock);
+ DEBUG_PRINT_LOW("Initiate Output Flush");
+
+ //reset last render TS
+ if(m_last_rendered_TS > 0) {
+ m_last_rendered_TS = 0;
+ }
+
+ while (m_ftb_q.m_size) {
+ DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d",
+ m_ftb_q.m_size,pending_output_buffers);
+ m_ftb_q.pop_entry(&p1,&p2,&ident);
+ DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2);
+ if (ident == m_fill_output_msg ) {
+ m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
+ } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
+ fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)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 long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ /*Generate EBD for all Buffers in the ETBq*/
+ DEBUG_PRINT_LOW("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_LOW("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("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("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("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("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 long) 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("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 long p1,
+ unsigned long p2,
+ unsigned long id)
+{
+ bool bRet = false;
+
+ /* Just drop messages typically generated by hardware (w/o client request),
+ * if we've reported an error to client. */
+ if (m_error_propogated) {
+ switch (id) {
+ case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
+ case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
+ DEBUG_PRINT_ERROR("Dropping message %lx "
+ "since client expected to be in error state", id);
+ return false;
+ default:
+ /* whatever */
+ break;
+ }
+ }
+
+ pthread_mutex_lock(&m_lock);
+
+ if (id == m_fill_output_msg ||
+ id == OMX_COMPONENT_GENERATE_FBD ||
+ id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
+ 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_ETB_ARBITRARY ||
+ 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("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(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)) {
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel52;
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
+ } else if (profileLevelType->nProfileIndex == 1) {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
+ } else if (profileLevelType->nProfileIndex == 2) {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
+ } else if (profileLevelType->nProfileIndex == 3) {
+ profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
+ } else if (profileLevelType->nProfileIndex == 4) {
+ profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
+ } else {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh;
+ profileLevelType->eLevel = QOMX_VIDEO_MVCLevel51;
+ } else {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
+ profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51;
+ } else if (profileLevelType->nProfileIndex == 1) {
+ profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10;
+ profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel51;
+ } else {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)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_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)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_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",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_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u",
+ (unsigned int)profileLevelType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ return eRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::GetParameter
+
+ DESCRIPTION
+ OMX Get Parameter method implementation
+
+ PARAMETERS
+ <TBD>.
+
+ 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)
+{
+ (void) hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ DEBUG_PRINT_LOW("get_parameter:");
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("Get Param in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL) {
+ DEBUG_PRINT_LOW("Get Param in Invalid paramData");
+ return OMX_ErrorBadParameter;
+ }
+ switch ((unsigned long)paramIndex) {
+ case OMX_IndexParamPortDefinition: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
+ (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
+ decide_dpb_buffer_mode(is_down_scalar_enabled);
+ eRet = update_portdef(portDefn);
+ if (eRet == OMX_ErrorNone)
+ m_port_def = *portDefn;
+ break;
+ }
+ case OMX_IndexParamVideoInit: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
+ OMX_PORT_PARAM_TYPE *portParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
+
+ portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
+ portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
+ portParamType->nPorts = 2;
+ portParamType->nStartPortNumber = 0;
+ break;
+ }
+ case OMX_IndexParamVideoPortFormat: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
+
+ portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
+ portFmt->nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
+
+ 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");
+ eRet = OMX_ErrorNoMore;
+ }
+ } else if (1 == portFmt->nPortIndex) {
+ portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+ // Distinguish non-surface mode from normal playback use-case based on
+ // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
+ // For non-android, use the default list
+ // Also use default format-list if FLEXIBLE YUV is supported,
+ // as the client negotiates the standard color-format if it needs to
+ bool useNonSurfaceMode = false;
+#if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
+ useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
+#endif
+ if (is_thulium_v1) {
+ portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex);
+ } else {
+ portFmt->eColorFormat = useNonSurfaceMode ?
+ getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
+ getPreferredColorFormatDefaultMode(portFmt->nIndex);
+ }
+
+ if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
+ eRet = OMX_ErrorNoMore;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
+ " NoMore Color formats");
+ }
+ DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
+ (int)portFmt->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamAudioInit: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
+ OMX_PORT_PARAM_TYPE *audioPortParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
+ audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
+ audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
+ audioPortParamType->nPorts = 0;
+ audioPortParamType->nStartPortNumber = 0;
+ break;
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamImageInit: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
+ OMX_PORT_PARAM_TYPE *imagePortParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
+ imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
+ imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
+ imagePortParamType->nPorts = 0;
+ imagePortParamType->nStartPortNumber = 0;
+ break;
+
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamOtherInit: {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
+ paramIndex);
+ eRet =OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ case OMX_IndexParamStandardComponentRole: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
+ 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",
+ paramIndex);
+ strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
+ OMX_MAX_STRINGNAME_SIZE);
+ break;
+ }
+ /* Added for parameter test */
+ case OMX_IndexParamPriorityMgmt: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
+ OMX_PRIORITYMGMTTYPE *priorityMgmType =
+ (OMX_PRIORITYMGMTTYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
+ priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
+ priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
+
+ break;
+ }
+ /* Added for parameter test */
+ case OMX_IndexParamCompBufferSupplier: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
+ (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
+
+ bufferSupplierType->nSize = sizeof(OMX_PARAM_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",
+ paramIndex);
+ break;
+ }
+ case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
+ DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoH263: {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4: {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg2: {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelQuerySupported: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
+ (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
+ eRet = get_supported_profile_level(profileLevelType);
+ break;
+ }
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+ case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
+ VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
+ DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
+ GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
+ if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
+
+ if (secure_mode && !secure_scaling_to_non_secure_opb) {
+ nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
+ GRALLOC_USAGE_PRIVATE_UNCACHED);
+ } else {
+ nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
+ }
+ } else {
+ DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ break;
+#endif
+
+#ifdef FLEXYUV_SUPPORTED
+ case OMX_QcomIndexFlexibleYUVDescription: {
+ DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
+ VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
+ eRet = describeColorFormat(paramData);
+ break;
+ }
+#endif
+ case OMX_IndexParamVideoProfileLevelCurrent: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+ struct v4l2_control profile_control, level_control;
+
+ switch (drv_ctx.decoder_format) {
+ case VDEC_CODECTYPE_H264:
+ profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+ level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
+ eRet = OMX_ErrorNotImplemented;
+ break;
+ }
+
+ if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
+ switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
+ case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
+ pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
+ pParam->eProfile = OMX_VIDEO_AVCProfileMain;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
+ pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
+ pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
+ pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
+ pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ } else {
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+
+
+ if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
+ switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
+ pParam->eLevel = OMX_VIDEO_AVCLevel1;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
+ pParam->eLevel = OMX_VIDEO_AVCLevel1b;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
+ pParam->eLevel = OMX_VIDEO_AVCLevel11;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
+ pParam->eLevel = OMX_VIDEO_AVCLevel12;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
+ pParam->eLevel = OMX_VIDEO_AVCLevel13;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
+ pParam->eLevel = OMX_VIDEO_AVCLevel2;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
+ pParam->eLevel = OMX_VIDEO_AVCLevel21;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
+ pParam->eLevel = OMX_VIDEO_AVCLevel22;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
+ pParam->eLevel = OMX_VIDEO_AVCLevel3;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
+ pParam->eLevel = OMX_VIDEO_AVCLevel31;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
+ pParam->eLevel = OMX_VIDEO_AVCLevel32;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
+ pParam->eLevel = OMX_VIDEO_AVCLevel4;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
+ pParam->eLevel = OMX_VIDEO_AVCLevel41;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
+ pParam->eLevel = OMX_VIDEO_AVCLevel42;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
+ pParam->eLevel = OMX_VIDEO_AVCLevel5;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
+ pParam->eLevel = OMX_VIDEO_AVCLevel51;
+ break;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
+ pParam->eLevel = OMX_VIDEO_AVCLevel52;
+ break;
+ }
+ } else {
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+
+ break;
+
+ }
+ case OMX_QTIIndexParamVideoClientExtradata:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CLIENT_EXTRADATATYPE);
+ DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
+ QOMX_VIDEO_CLIENT_EXTRADATATYPE *pParam =
+ (QOMX_VIDEO_CLIENT_EXTRADATATYPE *)paramData;
+ pParam->nExtradataSize = VENUS_EXTRADATA_SIZE(4096, 2160);
+ pParam->nExtradataAllocSize = pParam->nExtradataSize * MAX_NUM_INPUT_OUTPUT_BUFFERS;
+ eRet = OMX_ErrorNone;
+ break;
+ }
+ default: {
+ DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", 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<android_native_buffer_t> 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
+
+OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
+ 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.");
+ return OMX_ErrorHardware;
+ }
+ m_smoothstreaming_mode = true;
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::Setparameter
+
+ DESCRIPTION
+ OMX Set Parameter method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ 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;
+#ifdef _ANDROID_
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+#endif
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("Set Param in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL) {
+ DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
+ 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");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ switch ((unsigned long)paramIndex) {
+ case OMX_IndexParamPortDefinition: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
+ 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 (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
+ DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
+ portDefn->nBufferCountActual);
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ if (OMX_DirOutput == portDefn->eDir) {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
+ bool port_format_changed = false;
+ m_display_id = portDefn->format.video.pNativeWindow;
+ unsigned int buffer_size;
+ /* update output port resolution with client supplied dimensions
+ in case scaling is enabled, else it follows input resolution set
+ */
+ decide_dpb_buffer_mode(is_down_scalar_enabled);
+ if (is_down_scalar_enabled) {
+ DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
+ (unsigned int)portDefn->format.video.nFrameWidth,
+ (unsigned int)portDefn->format.video.nFrameHeight);
+ if (portDefn->format.video.nFrameHeight != 0x0 &&
+ portDefn->format.video.nFrameWidth != 0x0) {
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Get Resolution failed");
+ eRet = OMX_ErrorHardware;
+ break;
+ }
+ if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
+ (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
+ port_format_changed = true;
+ }
+
+ /* set crop info */
+ rectangle.nLeft = 0;
+ rectangle.nTop = 0;
+ rectangle.nWidth = portDefn->format.video.nFrameWidth;
+ rectangle.nHeight = portDefn->format.video.nFrameHeight;
+
+ eRet = is_video_session_supported();
+ if (eRet)
+ break;
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight;
+ fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
+ 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("Set Resolution failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ } else
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+ }
+
+ if (eRet) {
+ break;
+ }
+
+ if (secure_mode) {
+ struct v4l2_control control;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
+ DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id);
+ eRet = OMX_ErrorHardware;
+ } else {
+ /* This is a workaround for a bug in fw which uses stride
+ * and slice instead of width and height to check against
+ * the threshold.
+ */
+ OMX_U32 stride, slice;
+ if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
+ stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
+ slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
+ } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
+ stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth);
+ slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight);
+ } else {
+ stride = portDefn->format.video.nFrameWidth;
+ slice = portDefn->format.video.nFrameHeight;
+ }
+
+ DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice);
+ DEBUG_PRINT_LOW("Threshold value is %d\n", control.value);
+
+ if (stride * slice <= (OMX_U32)control.value) {
+ secure_scaling_to_non_secure_opb = true;
+ DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ");
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2;
+ control.value = 1;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
+ DEBUG_PRINT_ERROR("Enabling non-secure output2 failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ }
+ }
+ }
+
+ if (eRet) {
+ break;
+ }
+
+ if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
+ DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
+ portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
+ eRet = OMX_ErrorBadParameter;
+ } else if (!client_buffers.get_buffer_req(buffer_size)) {
+ DEBUG_PRINT_ERROR("Error in getting buffer requirements");
+ eRet = OMX_ErrorBadParameter;
+ } else if (!port_format_changed) {
+
+ // Buffer count can change only when port is unallocated
+ if (m_out_mem_ptr &&
+ (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
+ portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
+
+ DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
+ eRet = OMX_ErrorInvalidState;
+ break;
+ }
+
+ // route updating of buffer requirements via c2d proxy.
+ // Based on whether c2d is enabled, requirements will be handed
+ // to the vidc driver appropriately
+ eRet = client_buffers.set_buffer_req(portDefn->nBufferSize,
+ portDefn->nBufferCountActual);
+ if (eRet == OMX_ErrorNone) {
+ m_port_def = *portDefn;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
+ drv_ctx.op_buf.mincount, (unsigned int)buffer_size,
+ (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ } else if (OMX_DirInput == portDefn->eDir) {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
+ bool port_format_changed = false;
+ 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 : %u",
+ (unsigned int)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)",
+ (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
+ (float)drv_ctx.frame_rate.fps_denominator);
+
+ 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");
+ eRet = OMX_ErrorHardware;
+ break;
+ }
+ m_perf_control.request_cores(frm_int);
+ }
+
+ 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(%u x %u)",
+ (unsigned int)portDefn->format.video.nFrameWidth,
+ (unsigned int)portDefn->format.video.nFrameHeight);
+ port_format_changed = true;
+ OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
+ OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
+ if (frameHeight != 0x0 && frameWidth != 0x0) {
+ if (m_smoothstreaming_mode &&
+ ((frameWidth * frameHeight) <
+ (m_smoothstreaming_width * m_smoothstreaming_height))) {
+ frameWidth = m_smoothstreaming_width;
+ frameHeight = m_smoothstreaming_height;
+ DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
+ "for adaptive-playback/smooth-streaming",
+ (unsigned int)frameWidth, (unsigned int)frameHeight);
+ }
+ update_resolution(frameWidth, frameHeight,
+ frameWidth, frameHeight);
+ eRet = is_video_session_supported();
+ if (eRet)
+ break;
+ if (is_down_scalar_enabled) {
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ 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("DS Enabled : height = %d , width = %d",
+ fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ } else {
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ 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("DS Disabled : height = %d , width = %d",
+ fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ }
+ if (ret) {
+ DEBUG_PRINT_ERROR("Set Resolution failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ } else {
+ if (!is_down_scalar_enabled)
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+ }
+ }
+ }
+ if (m_custom_buffersize.input_buffersize
+ && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
+ DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
+ m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
+ DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
+ portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ // Buffer count can change only when port is unallocated
+ if (m_inp_mem_ptr &&
+ (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
+ portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
+ DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
+ eRet = OMX_ErrorInvalidState;
+ break;
+ }
+
+ if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
+ || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
+ port_format_changed = true;
+ 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);
+ }
+ if (false == port_format_changed) {
+ DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
+ drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
+ (unsigned int)portDefn->nBufferCountActual, (unsigned int)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: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ int ret=0;
+ struct v4l2_format fmt;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
+ portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
+
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ if (1 == portFmt->nPortIndex) {
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ if (ret < 0) {
+ DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
+ return OMX_ErrorBadParameter;
+ }
+ enum vdec_output_fromat op_format;
+ if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
+ portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView ||
+ portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
+ portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
+ op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
+ } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
+ op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC;
+ } else
+ eRet = OMX_ErrorBadParameter;
+
+ if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
+ fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
+ } else {
+ fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
+ }
+
+ 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("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("Set color format failed");
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ }
+ }
+ break;
+
+ case OMX_QcomIndexPortDefn: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
+ OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
+ (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
+ (unsigned int)portFmt->nFramePackingFormat);
+
+ /* Input port */
+ if (portFmt->nPortIndex == 0) {
+ // arbitrary_bytes mode cannot be changed arbitrarily since this controls how:
+ // - headers are allocated and
+ // - headers-indices are derived
+ // Avoid changing arbitrary_bytes when the port is already allocated
+ if (m_inp_mem_ptr) {
+ DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
+ if (secure_mode || m_input_pass_buffer_fd) {
+ arbitrary_bytes = false;
+ DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
+ eRet = OMX_ErrorUnsupportedSetting;
+ } else {
+ arbitrary_bytes = true;
+ }
+ } else if (portFmt->nFramePackingFormat ==
+ OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
+ arbitrary_bytes = false;
+#ifdef _ANDROID_
+ property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
+ if (atoi(property_value)) {
+ DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command");
+ arbitrary_bytes = true;
+ }
+#endif
+ } else {
+ DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
+ (unsigned int)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: out pmem set");
+ m_use_output_pmem = OMX_TRUE;
+ }
+ }
+ }
+ }
+ if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
+ OMX_MAX_STRINGNAME_SIZE)) {
+ arbitrary_bytes = true;
+ DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264");
+ }
+ break;
+
+ case OMX_IndexParamStandardComponentRole: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
+ 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");
+ 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", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
+ if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
+ } else {
+ DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", 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", 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", 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", 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)) ||
+ (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", 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", 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", 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", comp_role->cRole);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
+ if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
+ !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
+ } else {
+ DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
+ if (!strncmp((const 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", comp_role->cRole);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+ break;
+ }
+
+ case OMX_IndexParamPriorityMgmt: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
+ if (m_state != OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
+ (unsigned int)priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
+ (unsigned int)priorityMgmtype->nGroupPriority);
+
+ m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
+ m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
+
+ break;
+ }
+
+ case OMX_IndexParamCompBufferSupplier: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
+ 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",
+ paramIndex);
+ break;
+ }
+ case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
+ DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoH263: {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4: {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
+ paramIndex);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg2: {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
+ paramIndex);
+ break;
+ }
+ case OMX_QTIIndexParamLowLatencyMode: {
+ struct v4l2_control control;
+ int rc = 0;
+ QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE* pParam =
+ (QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE*)paramData;
+ if (pParam->bLowLatencyMode) {
+ DEBUG_PRINT_HIGH("Enabling DECODE order");
+ time_stamp_dts.set_timestamp_reorder_mode(false);
+ 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("Set picture order failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ break;
+ }
+ case OMX_QcomIndexParamVideoDecoderPictureOrder: {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
+ 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",
+ 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("Set picture order failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ break;
+ }
+ case OMX_QcomIndexParamConcealMBMapExtraData:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexParamFrameInfoExtraData:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_ExtraDataFrameDimension:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexParamInterlaceExtraData:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexParamH264TimeInfo:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexParamVideoFramePackingExtradata:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexParamVideoQPExtraData:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_QP_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexEnableExtnUserData:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QTIIndexParamVQZipSEIExtraData:
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ break;
+ case OMX_QcomIndexParamVideoDivx: {
+ QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
+ }
+ break;
+ case OMX_QcomIndexPlatformPvt: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN);
+ 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: out 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");
+ 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("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("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("Sync frame setting failed: falied to get buffer i/p requirements");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ if (get_buffer_req(&drv_ctx.op_buf)) {
+ DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ }
+ break;
+
+ case OMX_QcomIndexParamIndexExtraDataType: {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
+ 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, false, extradataIndexType->bEnabled);
+
+ }
+ }
+ break;
+ case OMX_QcomIndexParamEnableSmoothStreaming: {
+#ifndef SMOOTH_STREAMING_DISABLED
+ eRet = enable_smoothstreaming();
+#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: {
+ VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
+ EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
+ if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ } else if (m_out_mem_ptr) {
+ DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
+ eRet = OMX_ErrorInvalidState;
+ break;
+ }
+ if (enableNativeBuffers) {
+ m_enable_android_native_buffers = enableNativeBuffers->enable;
+ }
+#if !defined(FLEXYUV_SUPPORTED)
+ if (m_enable_android_native_buffers) {
+ // Use the most-preferred-native-color-format as surface-mode is hinted here
+ if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
+ DEBUG_PRINT_ERROR("Failed to set native color format!");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+#endif
+ }
+ break;
+ case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
+ VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
+ eRet = use_android_native_buffer(hComp, paramData);
+ }
+ break;
+#if ALLOCATE_OUTPUT_NATIVEHANDLE
+ case OMX_GoogleAndroidIndexAllocateNativeHandle: {
+
+ AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
+ VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
+
+ if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on input port!");
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ } else if (m_inp_mem_ptr) {
+ DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
+ eRet = OMX_ErrorInvalidState;
+ break;
+ }
+
+ if (allocateNativeHandleParams != NULL) {
+ allocate_native_handle = allocateNativeHandleParams->enable;
+ }
+ }
+ break;
+#endif //ALLOCATE_OUTPUT_NATIVEHANDLE
+#endif
+ case OMX_QcomIndexParamEnableTimeStampReorder: {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
+ 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: {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
+ 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;
+
+ }
+ case OMX_QcomIndexParamVideoMetaBufferMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
+ StoreMetaDataInBuffersParams *metabuffer =
+ (StoreMetaDataInBuffersParams *)paramData;
+ if (!metabuffer) {
+ DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ if (m_disable_dynamic_buf_mode) {
+ DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+ if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
+
+ if (m_out_mem_ptr) {
+ DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
+ eRet = OMX_ErrorInvalidState;
+ break;
+ }
+ //set property dynamic buffer mode to driver.
+ struct v4l2_control control;
+ struct v4l2_format fmt;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
+ if (metabuffer->bStoreMetaData == true) {
+ control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
+ } else {
+ control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
+ }
+ int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
+ if (!rc) {
+ DEBUG_PRINT_HIGH("%s buffer mode",
+ (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
+ dynamic_buf_mode = metabuffer->bStoreMetaData;
+ } else {
+ DEBUG_PRINT_ERROR("Failed to %s buffer mode",
+ (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else {
+ DEBUG_PRINT_ERROR(
+ "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
+ (unsigned int)metabuffer->nPortIndex);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamVideoDownScalar:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
+ QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
+ struct v4l2_control control;
+ int rc;
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable);
+
+ if (pParam && pParam->bEnable) {
+ rc = enable_downscalar();
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_force_down_scalar = pParam->bEnable;
+ } else {
+ rc = disable_downscalar();
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_force_down_scalar = pParam->bEnable;
+ }
+ break;
+ }
+#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
+ case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams);
+ DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
+ PrepareForAdaptivePlaybackParams* pParams =
+ (PrepareForAdaptivePlaybackParams *) paramData;
+ if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
+ if (!pParams->bEnable) {
+ return OMX_ErrorNone;
+ }
+ if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
+ || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
+ DEBUG_PRINT_ERROR(
+ "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
+ (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
+ (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
+ eRet = OMX_ErrorBadParameter;
+ } else {
+ eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
+ }
+ } else {
+ DEBUG_PRINT_ERROR(
+ "Prepare for adaptive playback supported only on output port");
+ eRet = OMX_ErrorBadParameter;
+ }
+ break;
+ }
+
+ case OMX_QTIIndexParamVideoPreferAdaptivePlayback:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback");
+ m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable;
+ if (m_disable_dynamic_buf_mode) {
+ DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set");
+ }
+ break;
+ }
+#endif
+ case OMX_QcomIndexParamVideoCustomBufferSize:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
+ QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
+ if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
+ struct v4l2_control control;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
+ control.value = pParam->nBufferSize;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set input buffer size");
+ eRet = OMX_ErrorUnsupportedSetting;
+ } else {
+ eRet = get_buffer_req(&drv_ctx.ip_buf);
+ if (eRet == OMX_ErrorNone) {
+ m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
+ DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
+ m_custom_buffersize.input_buffersize);
+ } else {
+ DEBUG_PRINT_ERROR("Failed to get buffer requirement");
+ }
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
+ eRet = OMX_ErrorBadParameter;
+ }
+ break;
+ }
+ case OMX_QTIIndexParamVQZIPSEIType:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType");
+ OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
+ (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
+ DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
+ eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata");
+ eRet = OMX_ErrorBadParameter;
+ client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
+ } else {
+ eRet = enable_extradata(OMX_QP_EXTRADATA, false,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata");
+ eRet = OMX_ErrorBadParameter;
+ client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
+ client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
+ }
+ }
+ break;
+ }
+
+ case OMX_QTIIndexParamPassInputBufferFd:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
+ if (arbitrary_bytes) {
+ DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode");
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+
+ m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
+ if (m_input_pass_buffer_fd)
+ DEBUG_PRINT_LOW("Enable passing input buffer FD");
+ break;
+ }
+ case OMX_QTIIndexParamForceCompressedForDPB:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB");
+ OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam =
+ (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData;
+ if (m_disable_ubwc_mode) {
+ DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled");
+ eRet = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+ if (!paramData) {
+ DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL");
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+
+ m_force_compressed_for_dpb = pParam->bEnable;
+ break;
+ }
+ case OMX_QTIIndexParamForceUnCompressedForOPB:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
+ OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
+ (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
+ if (!paramData) {
+ DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ m_disable_ubwc_mode = pParam->bEnable;
+ DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
+ break;
+ }
+ case OMX_QTIIndexParamVideoClientExtradata:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CLIENT_EXTRADATATYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata");
+ QOMX_VIDEO_CLIENT_EXTRADATATYPE *pParam =
+ (QOMX_VIDEO_CLIENT_EXTRADATATYPE *)paramData;
+ OMX_U32 extradata_size = VENUS_EXTRADATA_SIZE(4096, 2160);
+ if (pParam->nExtradataSize < extradata_size ||
+ pParam->nExtradataAllocSize < (extradata_size * MAX_NUM_INPUT_OUTPUT_BUFFERS) ||
+ pParam->nExtradataAllocSize < (pParam->nExtradataSize * MAX_NUM_INPUT_OUTPUT_BUFFERS)) {
+ DEBUG_PRINT_ERROR("set_parameter: Incorrect buffer size for client extradata");
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ if (!m_client_extradata_info.set_extradata_info(dup(pParam->nFd),
+ pParam->nExtradataAllocSize, pParam->nExtradataSize)) {
+ DEBUG_PRINT_ERROR("set_parameter: Setting client extradata failed.");
+ eRet = OMX_ErrorBadParameter;
+ break;
+ }
+ break;
+ }
+
+ default: {
+ DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ if (eRet != OMX_ErrorNone)
+ DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
+ return eRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::GetConfig
+
+ DESCRIPTION
+ OMX Get Config Method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ 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)
+{
+ (void) hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("Get Config in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ switch ((unsigned long)configIndex) {
+ case OMX_QcomIndexConfigInterlaced: {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_CONFIG_INTERLACETYPE);
+ 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");
+ eRet = OMX_ErrorNoMore;
+ }
+
+ } else {
+ DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
+ (int)configFmt->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES);
+ 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) {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
+ OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
+ (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
+ memcpy(configFmt, &m_frame_pack_arrangement,
+ sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
+ } else {
+ DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
+ }
+ break;
+ }
+ case OMX_IndexConfigCommonOutputCrop: {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE);
+ OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
+ memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
+ DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
+ rectangle.nLeft, rectangle.nTop,
+ rectangle.nWidth, rectangle.nHeight);
+ break;
+ }
+ case OMX_QcomIndexConfigPerfLevel: {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
+ struct v4l2_control control;
+ OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
+ (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
+
+ control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
+ DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno);
+ eRet = OMX_ErrorHardware;
+ }
+
+ if (eRet == OMX_ErrorNone) {
+ switch (control.value) {
+ case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
+ perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo;
+ break;
+ default:
+ DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value);
+ /* Fall through */
+ case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
+ perf->ePerfLevel = OMX_QCOM_PerfLevelNominal;
+ break;
+ }
+ }
+
+ break;
+ }
+ case OMX_QcomIndexConfigH264EntropyCodingCabac: {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
+ QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData;
+ struct v4l2_control control;
+
+ if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) {
+ DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264");
+ eRet = OMX_ErrorNotImplemented;
+ break;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
+ if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) {
+ coding->bCabac = (OMX_BOOL)
+ (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC);
+ /* We can't query driver at the moment for the cabac mode, so
+ * just use 0xff...f as a place holder for future improvement */
+ coding->nCabacInitIdc = ~0;
+ } else {
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+
+ break;
+ }
+ case OMX_QTIIndexConfigDescribeColorAspects:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
+ DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
+
+ print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client");
+ print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal");
+
+ if (params->bRequestingDataSpace) {
+ DEBUG_PRINT_ERROR("Does not handle dataspace request");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (m_internal_color_space.bDataSpaceChanged == OMX_TRUE) {
+ DEBUG_PRINT_LOW("Updating Client's color aspects with internal");
+ memcpy(&(m_client_color_space.sAspects),
+ &(m_internal_color_space.sAspects), sizeof(ColorAspects));
+ m_internal_color_space.bDataSpaceChanged = OMX_FALSE;
+ }
+ memcpy(&(params->sAspects), &(m_client_color_space.sAspects), sizeof(ColorAspects));
+
+ break;
+ }
+ default: {
+ DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ }
+
+ return eRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::SetConfig
+
+ DESCRIPTION
+ OMX Set Config method implementation
+
+ PARAMETERS
+ <TBD>.
+
+ 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)
+{
+ (void) hComp;
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("Get Config in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ OMX_VIDEO_CONFIG_NALSIZE *pNal;
+
+ DEBUG_PRINT_LOW("Set Config Called");
+
+ if (configIndex == OMX_IndexConfigVideoNalSize) {
+ struct v4l2_control temp;
+ temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
+
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_NALSIZE);
+ 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("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
+ return ret;
+ } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
+ OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
+ DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)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 : %u",
+ (unsigned int)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;
+ } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) {
+ OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
+ (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
+ struct v4l2_control control;
+
+ DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
+
+ control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+
+ switch (perf->ePerfLevel) {
+ case OMX_QCOM_PerfLevelNominal:
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
+ break;
+ case OMX_QCOM_PerfLevelTurbo:
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+ break;
+ default:
+ ret = OMX_ErrorUnsupportedSetting;
+ break;
+ }
+
+ if (ret == OMX_ErrorNone) {
+ ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
+ OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
+ }
+
+ return ret;
+ } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) {
+ OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config =
+ (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData;
+ struct v4l2_control control;
+ DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType);
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE;
+
+ switch (config->eDecodeType) {
+ case OMX_QCOM_PictypeDecode_I:
+ control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON;
+ break;
+ case OMX_QCOM_PictypeDecode_IPB:
+ default:
+ control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF;
+ break;
+ }
+
+ ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
+ OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
+ if (ret)
+ DEBUG_PRINT_ERROR("Failed to set picture type decode");
+
+ return ret;
+ } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
+ OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
+ DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
+
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
+ if (priority->nU32 == 0)
+ control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
+ else
+ control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
+
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set Priority");
+ ret = OMX_ErrorUnsupportedSetting;
+ }
+ return ret;
+ } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
+ OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
+ DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
+
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
+ control.value = rate->nU32;
+
+ operating_frame_rate = rate->nU32 >> 16;
+
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
+ OMX_ErrorUnsupportedSetting;
+ DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
+ rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
+ }
+ return ret;
+
+ } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) {
+ VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
+ DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
+ if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) {
+ enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, true, true);
+ }
+
+ print_debug_color_aspects(&(params->sAspects), "Set Config");
+ memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams));
+ return ret;
+ }
+
+ return OMX_ErrorNotImplemented;
+}
+
+#define extn_equals(param, extn) (!strcmp(param, extn))
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::GetExtensionIndex
+
+ DESCRIPTION
+ OMX GetExtensionIndex method implementaion. <TBD>
+
+ PARAMETERS
+ <TBD>.
+
+ 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)
+{
+ (void) hComp;
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
+ return OMX_ErrorInvalidState;
+ } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
+ } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
+ } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
+ } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
+ } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
+ } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
+ } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
+ }
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+ else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
+ *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
+ } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
+ *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
+ } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
+ DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
+ *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
+ } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
+ *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
+ }
+#if ALLOCATE_OUTPUT_NATIVEHANDLE
+ else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
+ *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
+ }
+#endif //ALLOCATE_OUTPUT_NATIVEHANDLE
+#endif
+ else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
+ }
+#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
+ else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
+ } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback;
+ }
+#endif
+#ifdef FLEXYUV_SUPPORTED
+ else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
+ }
+#endif
+ else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd;
+ } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB;
+ } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB;
+ } else if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode;
+ } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata;
+ } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
+ } else {
+ DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
+ return OMX_ErrorNotImplemented;
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::GetState
+
+ DESCRIPTION
+ Returns the state information back to the caller.<TBD>
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ Error None if everything is successful.
+ ========================================================================== */
+OMX_ERRORTYPE omx_vdec::get_state(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STATETYPE* state)
+{
+ (void) hComp;
+ *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. <TBD>
+
+ 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)
+{
+ (void) hComp;
+ (void) port;
+ (void) peerComponent;
+ (void) peerPort;
+ (void) tunnelSetup;
+ DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
+ 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");
+ 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");
+ close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
+ free_ion_memory(&drv_ctx.extradata_info.ion);
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+#endif
+ if (!m_other_extradata) {
+ m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
+ if (!m_other_extradata) {
+ DEBUG_PRINT_ERROR("Failed to alloc memory\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ 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
+ if (m_other_extradata) {
+ free(m_other_extradata);
+ m_other_extradata = NULL;
+ }
+}
+
+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;
+ (void) hComp;
+ (void) port;
+
+ 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", drv_ctx.op_buf.actualcount);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ if (eRet != OMX_ErrorNone)
+ return eRet;
+
+ if (dynamic_buf_mode) {
+ *bufferHdr = (m_out_mem_ptr + i );
+ (*bufferHdr)->pBuffer = NULL;
+ if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) {
+ enum v4l2_buf_type buf_type;
+ int rr = 0;
+ buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) {
+ DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
+ return OMX_ErrorInsufficientResources;
+ } else {
+ streaming[CAPTURE_PORT] = true;
+ DEBUG_PRINT_LOW("STREAMON Successful");
+ }
+
+ DEBUG_PRINT_HIGH("Enabling Turbo mode");
+ request_perf_level(VIDC_TURBO);
+ }
+ BITMASK_SET(&m_out_bm_count,i);
+ (*bufferHdr)->pAppPrivate = appData;
+ (*bufferHdr)->pBuffer = buffer;
+ (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
+ return eRet;
+ }
+
+ 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<android_native_buffer_t> nBuf = params->nativeBuffer;
+ handle = (private_handle_t *)nBuf->handle;
+ privateAppData = params->pAppPrivate;
+ } else {
+ handle = (private_handle_t *)buff;
+ privateAppData = appData;
+ }
+ if (!handle) {
+ DEBUG_PRINT_ERROR("handle is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
+ if (secure_mode && secure_scaling_to_non_secure_opb) {
+ DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
+ (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
+ } else {
+ DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
+ " expected %u, got %u",
+ (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ drv_ctx.op_buf.buffer_size = 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].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 ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
+ if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
+ DEBUG_PRINT_ERROR("ION device fd is bad %d", 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", 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", 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("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");
+ 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("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 || !pmem_list->entryList || !pmem_list->entryList->entry ||
+ !pmem_list->nEntries ||
+ pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
+ DEBUG_PRINT_ERROR("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;
+ m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
+ m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
+ m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
+
+ *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("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", 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");
+ /*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("STREAMON Successful");
+ }
+
+ DEBUG_PRINT_HIGH("Enabling Turbo mode");
+ request_perf_level(VIDC_TURBO);
+ }
+
+ (*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
+ <TBD>.
+
+ 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 (secure_mode) {
+ DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode");
+ return OMX_ErrorUndefined;
+ }
+
+ 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 long)m_phdr_pmem_ptr[m_in_alloc_cnt],
+ (unsigned)NULL, (unsigned)NULL)) {
+ DEBUG_PRINT_ERROR("ERROR: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
+ <TBD>.
+
+ 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 || (!secure_mode && buffer == NULL)) {
+ DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+ if (port == OMX_CORE_INPUT_PORT_INDEX) {
+ // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
+ // ensure that use-buffer was called for previous allocation.
+ // Mix-and-match of useBuffer and allocateBuffer is not allowed
+ if (m_inp_mem_ptr && !input_use_buffer) {
+ DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !");
+ return OMX_ErrorUndefined;
+ }
+ 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",(int)port);
+ error = OMX_ErrorBadPortIndex;
+ }
+ DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)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);
+
+ auto_lock l(buf_lock);
+ bufferHdr->pInputPortPrivate = NULL;
+
+ 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_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("unmap the input buffer fd=%d",
+ drv_ctx.ptr_inputbuffer[index].pmem_fd);
+ DEBUG_PRINT_LOW("unmap the input buffer size=%u address = %p",
+ (unsigned int)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);
+ }
+
+ if (allocate_native_handle){
+ native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
+ native_handle_close(nh);
+ native_handle_delete(nh);
+ } else {
+ // Close fd for non-secure and secure non-native-handle case
+ 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("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 = %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));
+
+ if (!dynamic_buf_mode) {
+ if (streaming[CAPTURE_PORT] &&
+ !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
+ if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR("STREAMOFF Failed");
+ } else {
+ DEBUG_PRINT_LOW("STREAMOFF Successful");
+ }
+ }
+#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("unmap the output buffer fd = %d",
+ drv_ctx.ptr_outputbuffer[0].pmem_fd);
+ DEBUG_PRINT_LOW("unmap the ouput buffer size=%u address = %p",
+ (unsigned int)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
+ } //!dynamic_buf_mode
+ 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 || m_phdr_pmem_ptr == NULL) {
+ DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_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;
+ 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 long)m_phdr_pmem_ptr[i],
+ (unsigned)NULL, (unsigned)NULL)) {
+ DEBUG_PRINT_ERROR("ERROR: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;
+
+ (void) hComp;
+ (void) port;
+
+
+ if (bytes != drv_ctx.ip_buf.buffer_size) {
+ DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
+ (unsigned int)bytes, (unsigned int)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(%u)",
+ drv_ctx.ip_buf.actualcount,
+ (unsigned int)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) {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc;
+ 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, secure_mode ?
+ SECURE_FLAGS_INPUT_BUFFER : 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("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("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("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("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("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");
+ /*TODO: How to handle this case */
+ return OMX_ErrorInsufficientResources;
+ }
+
+ input = *bufferHdr;
+ BITMASK_SET(&m_inp_bm_count,i);
+ DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
+ if (allocate_native_handle) {
+ native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
+ if (!nh) {
+ DEBUG_PRINT_ERROR("Native handle create failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
+ input->pBuffer = (OMX_U8 *)nh;
+ } else if (secure_mode || m_input_pass_buffer_fd) {
+ /*Legacy method, pass ion fd stashed directly in pBuffer*/
+ input->pBuffer = (OMX_U8 *)(intptr_t)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("ERROR:Input Buffer Index not found");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::AllocateOutputBuffer
+
+ DESCRIPTION
+ Helper fn for AllocateBuffer in the output pin
+
+ PARAMETERS
+ <TBD>.
+
+ 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)
+{
+ (void)hComp;
+ (void)port;
+ 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("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
+ drv_ctx.op_buf.actualcount,
+ (unsigned int)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)",
+ 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 %u PMEM %d PL %d",nBufHdrSize,
+ (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
+ nPMEMInfoSize,
+ nPlatformListSize);
+ DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
+ drv_ctx.op_buf.actualcount);
+#ifdef USE_ION
+ // Allocate output buffers as cached to improve performance of software-reading
+ // of the YUVs. Output buffers are cache-invalidated in driver.
+ // If color-conversion is involved, Only the C2D output buffers are cached, no
+ // need to cache the decoder's output buffers
+ int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
+ ion_device_fd = alloc_map_ion_memory(
+ drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
+ secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
+ &ion_alloc_data, &fd_ion_data,
+ (secure_mode && !secure_scaling_to_non_secure_opb) ?
+ SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
+ 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("ERROR: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("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("MMAP failed for Size %u",
+ (unsigned int)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);
+ if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
+ DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
+ return OMX_ErrorInsufficientResources;
+ }
+
+#ifdef USE_ION
+ drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
+ calloc (sizeof(struct vdec_ion),
+ drv_ctx.op_buf.actualcount);
+ if (!drv_ctx.op_buf_ion_info) {
+ DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
+ return OMX_ErrorInsufficientResources;
+ }
+#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",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 = 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",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 = -1;
+ 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);
+ m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
+ m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
+ m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
+
+ DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
+ pmem_fd, (unsigned int)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]",\
+ 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;
+ }
+ 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("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) {
+#ifdef USE_ION
+ drv_ctx.ptr_outputbuffer[i].bufferaddr =
+ (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
+#else
+ drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
+#endif
+ }
+ 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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+ buf.m.planes = plane;
+ buf.length = drv_ctx.num_planes;
+ DEBUG_PRINT_LOW("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("STREAMON Successful");
+ }
+
+ DEBUG_PRINT_HIGH("Enabling Turbo mode");
+ request_perf_level(VIDC_TURBO);
+ }
+
+ (*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");
+ 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");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (port == OMX_CORE_INPUT_PORT_INDEX) {
+ // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
+ // ensure that use-buffer was never called.
+ // Mix-and-match of useBuffer and allocateBuffer is not allowed
+ if (m_inp_mem_ptr && input_use_buffer) {
+ DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !");
+ return OMX_ErrorUndefined;
+ }
+ 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",(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;
+ (void) hComp;
+ 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 %u disabled", (unsigned int)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 %u enable pending", (unsigned int)port);
+ } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
+ DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
+ 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");
+ 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 &&
+ BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
+ // 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;
+ if(release_input_done())
+ release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
+ /*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");
+ 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 &&
+ BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
+ 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()) {
+ release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
+ }
+ if (release_output_done()) {
+ free_output_buffer_header();
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
+ 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 (m_state != OMX_StateExecuting &&
+ m_state != OMX_StatePause &&
+ m_state != OMX_StateIdle) {
+ DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL) {
+ DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_inp_bEnabled) {
+ DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ 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;
+ if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
+ DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode");
+ return OMX_ErrorBadParameter;
+ }
+ 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 %u",
+ &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
+ } else {
+ nBufferIndex = buffer - m_inp_mem_ptr;
+ }
+ }
+
+ if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
+ DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ codec_config_flag = true;
+ DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
+ }
+
+ /* The client should not set this when codec is in arbitrary bytes mode */
+ if (m_input_pass_buffer_fd) {
+ buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
+ }
+
+ DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
+ buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
+ if (arbitrary_bytes) {
+ post_event ((unsigned long)hComp,(unsigned long)buffer,
+ OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
+ } else {
+ post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
+ }
+ time_stamp_dts.insert_timestamp(buffer);
+ 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)
+{
+ (void) hComp;
+ 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;
+
+ /*Should we generate a Aync error event*/
+ if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: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("ERROR: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 long)buffer,VDEC_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorNone;
+ }
+
+ if (input_flush_progress == true) {
+ DEBUG_PRINT_LOW("Flush in progress return buffer ");
+ post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorNone;
+ }
+
+ auto_lock l(buf_lock);
+ temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
+
+ if (!temp_buffer || (temp_buffer - drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
+ return OMX_ErrorBadParameter;
+ }
+ /* If its first frame, H264 codec and reject is true, then parse the nal
+ and get the profile. Based on this, reject the clip playback */
+ if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
+ m_reject_avc_1080p_mp) {
+ first_frame = 1;
+ DEBUG_PRINT_ERROR("Parse nal to get the profile");
+ h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
+ NALU_TYPE_SPS);
+ m_profile = h264_parser->get_profile();
+ ret = is_video_session_supported();
+ if (ret) {
+ post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
+ post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
+ /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
+ m_state = OMX_StateInvalid;
+ return OMX_ErrorNone;
+ }
+ }
+
+ 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 && temp_buffer->bufferaddr && !secure_mode) {
+ 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=%u",(unsigned int)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
+
+ log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
+
+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;
+ }
+ 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_QCOM_BUF_FLAG_EOS;
+ DEBUG_PRINT_HIGH("INPUT EOS reached") ;
+ }
+ 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;
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ DEBUG_PRINT_LOW("Increment codec_config buffer counter");
+ android_atomic_inc(&m_queued_codec_config_count);
+ }
+
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client");
+ m_cb.EmptyBufferDone(hComp, m_app_data, buffer);
+ return OMX_ErrorHardware;
+ }
+
+ if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+ codec_config_flag = false;
+ }
+ 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");
+ ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
+ if (!ret) {
+ DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
+ streaming[OUTPUT_PORT] = true;
+ } else if (errno == EBUSY) {
+ DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
+ post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorInsufficientResources;
+ } else {
+ DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
+ DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
+ post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorBadParameter;
+ }
+ }
+ DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)",
+ frameinfo.bufferaddr, (long long)frameinfo.timestamp,
+ (unsigned int)frameinfo.datalen);
+
+ 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_StateExecuting &&
+ m_state != OMX_StatePause &&
+ m_state != OMX_StateIdle) {
+ DEBUG_PRINT_ERROR("FTB in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (!m_out_bEnabled) {
+ DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ unsigned nPortIndex = 0;
+ if (dynamic_buf_mode) {
+ private_handle_t *handle = NULL;
+ struct VideoDecoderOutputMetaData *meta;
+ unsigned int nPortIndex = 0;
+
+ if (!buffer || !buffer->pBuffer) {
+ DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
+ return OMX_ErrorBadParameter;
+ }
+
+ //get the buffer type and fd info
+ meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
+ handle = (private_handle_t *)meta->pHandle;
+ DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
+
+ if (!handle) {
+ DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
+ return OMX_ErrorBadParameter;
+ }
+ //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
+ nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
+ if (nPortIndex < drv_ctx.op_buf.actualcount &&
+ nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
+ drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
+ drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
+
+ //Store private handle from GraphicBuffer
+ native_buffer[nPortIndex].privatehandle = handle;
+ native_buffer[nPortIndex].nativehandle = handle;
+ } else {
+ DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
+ //this with a more sane size so that we don't compensate in rest of code
+ //We'll restore this size later on, so that it's transparent to client
+ buffer->nFilledLen = 0;
+ buffer->nAllocLen = handle->size;
+
+ if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) {
+ m_is_display_session = true;
+ } else {
+ m_is_display_session = false;
+ }
+ DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session);
+
+ drv_ctx.op_buf.buffer_size = handle->size;
+ }
+
+ nPortIndex = buffer - client_buffers.get_il_buf_hdr();
+ if (buffer == NULL ||
+ (nPortIndex >= drv_ctx.op_buf.actualcount)) {
+ DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
+ nPortIndex, drv_ctx.op_buf.actualcount);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
+ post_event((unsigned long) hComp, (unsigned long)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) {
+ DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
+ nPortIndex, 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 || in_reconfig) {
+ DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
+ buffer->nFilledLen = 0;
+ m_cb.FillBufferDone (hComp,m_app_data,buffer);
+ return OMX_ErrorNone;
+ }
+
+ if (dynamic_buf_mode) {
+ drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
+ drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen;
+ buf_ref_add(nPortIndex);
+ drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen;
+ }
+
+ pending_output_buffers++;
+ buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
+ if (!buffer) {
+ DEBUG_PRINT_ERROR("err: client_buffer ptr invalid");
+ return OMX_ErrorBadParameter;
+ }
+ 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;
+ }
+
+ 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));
+ unsigned 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 = buffer->nAllocLen;
+ 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: %u", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+ buf.m.planes = plane;
+ buf.length = drv_ctx.num_planes;
+ DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
+ plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress);
+
+ rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
+ if (rc) {
+ /*TODO: How to handle this case */
+ buffer->nFilledLen = 0;
+ DEBUG_PRINT_ERROR("Failed to qbuf to driver, send FTB back to client");
+ m_cb.FillBufferDone(hComp, m_app_data, buffer);
+ }
+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)
+{
+ (void) hComp;
+ 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
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if everything successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ (void) hComp;
+
+ unsigned i = 0;
+ if (OMX_StateLoaded != m_state) {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
+ m_state);
+ DEBUG_PRINT_ERROR("Playback Ended - FAILED");
+ } else {
+ DEBUG_PRINT_HIGH("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");
+ for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
+ if (BITMASK_PRESENT(&m_out_bm_count, i)) {
+ BITMASK_CLEAR(&m_out_bm_count, i);
+ client_buffers.free_output_buffer (&m_out_mem_ptr[i]);
+ }
+
+ if (release_output_done()) {
+ break;
+ }
+ }
+#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; i<drv_ctx.ip_buf.actualcount; i++ ) {
+
+ if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
+ BITMASK_CLEAR(&m_inp_bm_count, i);
+ if (m_inp_mem_ptr)
+ free_input_buffer (i,&m_inp_mem_ptr[i]);
+ else
+ free_input_buffer (i,NULL);
+ }
+
+ if (release_input_done()) {
+ break;
+ }
+ }
+ }
+ free_input_buffer_header();
+ free_output_buffer_header();
+ if (h264_scratch.pBuffer) {
+ free(h264_scratch.pBuffer);
+ h264_scratch.pBuffer = NULL;
+ }
+
+ if (h264_parser) {
+ delete h264_parser;
+ h264_parser = NULL;
+ }
+
+ if (m_frame_parser.mutils) {
+ DEBUG_PRINT_LOW("Free utils parser");
+ delete (m_frame_parser.mutils);
+ m_frame_parser.mutils = NULL;
+ }
+
+ if (m_platform_list) {
+ free(m_platform_list);
+ m_platform_list = NULL;
+ }
+ if (m_vendor_config.pData) {
+ free(m_vendor_config.pData);
+ m_vendor_config.pData = NULL;
+ }
+
+ // Reset counters in mesg queues
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+#ifdef _ANDROID_
+ if (m_debug_timestamp) {
+ m_timestamp_list.reset_ts_list();
+ }
+#endif
+
+ DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
+ //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
+ // NULL);
+ DEBUG_PRINT_HIGH("Close the driver instance");
+
+ if (m_debug.infile) {
+ fclose(m_debug.infile);
+ m_debug.infile = NULL;
+ }
+ if (m_debug.outfile) {
+ fclose(m_debug.outfile);
+ m_debug.outfile = NULL;
+ }
+ if (m_debug.out_ymeta_file) {
+ fclose(m_debug.out_ymeta_file);
+ m_debug.out_ymeta_file = NULL;
+ }
+ if (m_debug.out_uvmeta_file) {
+ fclose(m_debug.out_uvmeta_file);
+ m_debug.out_uvmeta_file = NULL;
+ }
+#ifdef OUTPUT_EXTRADATA_LOG
+ if (outputExtradataFile)
+ fclose (outputExtradataFile);
+#endif
+ DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::UseEGLImage
+
+ DESCRIPTION
+ OMX Use EGL Image method implementation <TBD>.
+
+ PARAMETERS
+ <TBD>.
+
+ 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)
+{
+ (void) appData;
+ 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("Invalid EGL image");
+ }
+#ifdef USE_EGL_IMAGE_GPU
+ if (m_display_id == NULL) {
+ DEBUG_PRINT_ERROR("Display ID is not set by IL client");
+ return OMX_ErrorInsufficientResources;
+ }
+ egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
+ eglGetProcAddress("eglQueryImageKHR");
+ egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
+ egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &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",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");
+ return OMX_ErrorInsufficientResources;
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ComponentRoleEnum
+
+ DESCRIPTION
+ OMX Component Role Enum method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ 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)
+{
+ (void) hComp;
+ 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;
+ }
+ }
+
+ 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",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.mvc", OMX_MAX_STRINGNAME_SIZE)) {
+ if ((0 == index) && role) {
+ strlcpy((char *)role, "video_decoder.mvc", 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.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", 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 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",role);
+ } else {
+ DEBUG_PRINT_LOW("No more roles");
+ eRet = OMX_ErrorNoMore;
+ }
+ } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
+ if ((0 == index) && role) {
+ strlcpy((char *)role, "video_decoder.vp9",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("ERROR: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.ip_buf.actualcount; i++) {
+ if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
+ break;
+ }
+ }
+ }
+ if (i == drv_ctx.ip_buf.actualcount) {
+ bRet = true;
+ DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
+ }
+ if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
+ m_inp_bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+/* ======================================================================
+ FUNCTION
+ omx_vdec::AllocateOutputDone
+
+ DESCRIPTION
+ Checks if entire O/P buffer pool is allocated by IL Client or not.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false.
+
+ ========================================================================== */
+bool omx_vdec::allocate_output_done(void)
+{
+ bool bRet = false;
+ unsigned j=0;
+
+ if (m_out_mem_ptr == NULL) {
+ return bRet;
+ }
+
+ if (m_out_mem_ptr) {
+ for (; j < drv_ctx.op_buf.actualcount; j++) {
+ if (BITMASK_ABSENT(&m_out_bm_count,j)) {
+ break;
+ }
+ }
+ }
+
+ if (j == drv_ctx.op_buf.actualcount) {
+ bRet = true;
+ DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
+ if (m_out_bEnabled)
+ m_out_bPopulated = OMX_TRUE;
+ }
+
+ return bRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ReleaseDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_vdec::release_done(void)
+{
+ bool bRet = false;
+
+ if (release_input_done()) {
+ if (release_output_done()) {
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ReleaseOutputDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_vdec::release_output_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr);
+ if (m_out_mem_ptr) {
+ for (; j < drv_ctx.op_buf.actualcount ; j++) {
+ if (BITMASK_PRESENT(&m_out_bm_count,j)) {
+ break;
+ }
+ }
+ if (j == drv_ctx.op_buf.actualcount) {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ } else {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ return bRet;
+}
+/* ======================================================================
+ FUNCTION
+ omx_vdec::ReleaseInputDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_vdec::release_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
+ if (m_inp_mem_ptr) {
+ for (; j<drv_ctx.ip_buf.actualcount; j++) {
+ if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
+ break;
+ }
+ }
+ if (j==drv_ctx.ip_buf.actualcount) {
+ bRet = true;
+ }
+ } else {
+ bRet = true;
+ }
+ return bRet;
+}
+
+OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
+ if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("[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("***************************************************");
+ DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
+ DEBUG_PRINT_HIGH("***************************************************");
+ }
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
+ DEBUG_PRINT_HIGH("***************************************************");
+ DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
+ DEBUG_PRINT_HIGH("***************************************************");
+ }
+ }
+
+
+ DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld",
+ buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp);
+ pending_output_buffers --;
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
+ DEBUG_PRINT_HIGH("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 long) pdest_frame,(unsigned)NULL,
+ (unsigned)NULL);
+ pdest_frame = NULL;
+ }
+ }
+
+ if (!output_flush_progress && (buffer->nFilledLen > 0)) {
+ // set the default colorspace advised by client, since the bitstream may be
+ // devoid of colorspace-info.
+ if (m_enable_android_native_buffers) {
+ ColorSpace_t color_space = ITU_R_601;
+
+ // Disabled ?
+ // WA for VP8. Vp8 encoder does not embed color-info (yet!).
+ // Encoding RGBA results in 601-LR for all resolutions.
+ // This conflicts with the client't defaults which are based on resolution.
+ // Eg: 720p will be encoded as 601-LR. Client will say 709.
+ // Re-enable this code once vp8 encoder generates color-info and hence the
+ // decoder will be able to override with the correct source color.
+#if 0
+ switch (m_client_color_space.sAspects.mPrimaries) {
+ case ColorAspects::PrimariesBT601_6_625:
+ case ColorAspects::PrimariesBT601_6_525:
+ {
+ color_space = m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ?
+ ITU_R_601_FR : ITU_R_601;
+ break;
+ }
+ case ColorAspects::PrimariesBT709_5:
+ {
+ color_space = ITU_R_709;
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+#endif
+ DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)",
+ color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+ set_colorspace_in_handle(color_space, buffer - m_out_mem_ptr);
+ }
+ DEBUG_PRINT_LOW("Processing extradata");
+ handle_extradata(buffer);
+ }
+
+#ifdef OUTPUT_EXTRADATA_LOG
+ if (outputExtradataFile) {
+ int buf_index = buffer - m_out_mem_ptr;
+ OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr);
+
+ OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
+ p_extra = (OMX_OTHER_EXTRADATATYPE *)
+ ((unsigned long)(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=%x",
+ 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
+
+ /* 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 ||
+ output_capability == V4L2_PIX_FMT_H264_MVC) &&
+ is_interlaced) {
+ if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_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("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
+ buffer->nTimeStamp, expected_ts);
+
+ if (buffer->nTimeStamp != expected_ts) {
+ DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
+ }
+ }
+ }
+ }
+ }
+
+ if (m_cb.FillBufferDone) {
+ if (buffer->nFilledLen > 0) {
+ if (arbitrary_bytes)
+ adjust_timestamp(buffer->nTimeStamp);
+ else
+ set_frame_rate(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(%u) proc_time(%.2f)S fps(%.2f)",
+ (unsigned int)proc_frms, (float)proc_time / 1e6,
+ (float)(1e6 * proc_frms) / proc_time);
+ proc_frms = 0;
+ }
+ }
+ }
+ 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 %lu",pPMEMInfo->pmem_fd);
+ OMX_BUFFERHEADERTYPE *il_buffer;
+ il_buffer = client_buffers.get_il_buf_hdr(buffer);
+ OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
+
+ if (il_buffer && m_last_rendered_TS >= 0) {
+ OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
+
+ // Current frame can be send for rendering if
+ // (a) current FPS is <= 60
+ // (b) is the next frame after the frame with TS 0
+ // (c) is the first frame after seek
+ // (d) the delta TS b\w two consecutive frames is > 16 ms
+ // (e) its TS is equal to previous frame TS
+ // (f) if marked EOS
+
+ if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
+ il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
+ ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
+ m_last_rendered_TS = il_buffer->nTimeStamp;
+ } else {
+ //mark for droping
+ buffer->nFilledLen = 0;
+ }
+
+ DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
+ buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
+ il_buffer->nTimeStamp,ts_delta);
+
+ //above code makes sure that delta b\w two consecutive frames is not
+ //greater than 16ms, slow-mo feature, so cap fps to max 60
+ if (current_framerate > 60 ) {
+ current_framerate = 60;
+ }
+ }
+
+ // add current framerate to gralloc meta data
+ if (m_enable_android_native_buffers && m_out_mem_ptr) {
+ OMX_U32 buf_index = buffer - m_out_mem_ptr;
+ setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
+ UPDATE_REFRESH_RATE, (void*)&current_framerate);
+ }
+
+ if (buffer->nFilledLen && m_enable_android_native_buffers && m_out_mem_ptr) {
+ OMX_U32 buf_index = buffer - m_out_mem_ptr;
+ DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode);
+ setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
+ S3D_FORMAT, (void*)&stereo_output_mode);
+ }
+
+ if (il_buffer) {
+ log_output_buffers(il_buffer);
+ if (dynamic_buf_mode) {
+ unsigned int nPortIndex = 0;
+ nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
+
+ // Since we're passing around handles, adjust nFilledLen and nAllocLen
+ // to size of the handle. Do it _after_ log_output_buffers which
+ // requires the respective sizes to be accurate.
+
+ buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
+ buffer->nFilledLen = buffer->nFilledLen ?
+ sizeof(struct VideoDecoderOutputMetaData) : 0;
+
+ //Clear graphic buffer handles in dynamic mode
+ if (nPortIndex < drv_ctx.op_buf.actualcount &&
+ nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
+ native_buffer[nPortIndex].privatehandle = NULL;
+ native_buffer[nPortIndex].nativehandle = NULL;
+ } else {
+ DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
+ }
+ 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 %lu",pPMEMInfo->pmem_fd);
+ } else {
+ return OMX_ErrorBadParameter;
+ }
+
+#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
+ if (m_smoothstreaming_mode && m_out_mem_ptr) {
+ OMX_U32 buf_index = buffer - m_out_mem_ptr;
+ BufferDim_t dim;
+ private_handle_t *private_handle = NULL;
+ dim.sliceWidth = framesize.nWidth;
+ dim.sliceHeight = framesize.nHeight;
+ if (buf_index < drv_ctx.op_buf.actualcount &&
+ buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
+ native_buffer[buf_index].privatehandle)
+ private_handle = native_buffer[buf_index].privatehandle;
+ if (private_handle) {
+ DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
+ dim.sliceWidth, dim.sliceHeight);
+ setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
+ }
+ }
+#endif
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer)
+{
+
+ int nBufferIndex = buffer - m_inp_mem_ptr;
+
+ if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) {
+ DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
+ return OMX_ErrorBadParameter;
+ }
+
+ DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x",
+ buffer, buffer->pBuffer, buffer->nFlags);
+ 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 long)buffer,
+ (unsigned)NULL, (unsigned)NULL)) {
+ DEBUG_PRINT_ERROR("ERROR: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];
+ }
+
+ /* Restore the FD that we over-wrote in ETB */
+ if (m_input_pass_buffer_fd) {
+ buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
+ }
+
+ 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 v4l2_plane *plane = NULL;
+ struct vdec_output_frameinfo *output_respbuf = NULL;
+ int rc=1;
+ if (context == NULL || message == NULL) {
+ DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
+ return -1;
+ }
+ vdec_msg = (struct vdec_msginfo *)message;
+
+ omx = reinterpret_cast<omx_vdec*>(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_EVT_HW_OVERLOAD:
+ omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
+ OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
+ break;
+
+ case VDEC_MSG_EVT_HW_UNSUPPORTED:
+ omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
+ OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
+ 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;
+ if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
+ v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
+ omxhdr = NULL;
+ vdec_msg->status_code = VDEC_S_EFATAL;
+ break;
+
+ }
+ omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
+
+ if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
+ DEBUG_PRINT_HIGH("Unsupported input");
+ omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
+ OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+ }
+ if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+ vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
+ }
+ if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+
+ DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
+ android_atomic_dec(&omx->m_queued_codec_config_count);
+ if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
+ BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
+ DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
+ sem_post(&omx->m_safe_flush);
+ }
+ }
+ if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME ||
+ v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+ }
+ omx->post_event ((unsigned long)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 long)timestamp, vdec_msg->status_code,
+ OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
+ DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
+ (long long)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;
+ if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL ||
+ v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
+ omxhdr = NULL;
+ vdec_msg->status_code = VDEC_S_EFATAL;
+ break;
+ }
+ plane = v4l2_buf_ptr->m.planes;
+ omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index;
+
+ if (omxhdr && omxhdr->pOutputPortPrivate &&
+ ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
+ (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
+ - omx->drv_ctx.ptr_respbuffer) < (int)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_QCOM_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 (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
+ omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
+ }
+ if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
+ DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
+ omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
+ }
+
+ if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
+ !omx->output_flush_progress &&
+ !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
+ !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
+ unsigned int index = v4l2_buf_ptr->index;
+ unsigned int extra_idx = EXTRADATA_IDX(omx->drv_ctx.num_planes);
+ omx->time_stamp_dts.remove_time_stamp(
+ omxhdr->nTimeStamp,
+ (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
+ ?true:false);
+ plane[0].bytesused = 0;
+ plane[0].m.userptr =
+ (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].bufferaddr -
+ (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].offset;
+ plane[0].reserved[0] = omx->drv_ctx.ptr_outputbuffer[index].pmem_fd;
+ plane[0].reserved[1] = omx->drv_ctx.ptr_outputbuffer[index].offset;
+ plane[0].data_offset = 0;
+ v4l2_buf_ptr->flags = 0x0;
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ plane[extra_idx].bytesused = 0;
+ plane[extra_idx].length = omx->drv_ctx.extradata_info.buffer_size;
+ plane[extra_idx].m.userptr = (long unsigned int) (omx->drv_ctx.extradata_info.uaddr + index * omx->drv_ctx.extradata_info.buffer_size);
+#ifdef USE_ION
+ plane[extra_idx].reserved[0] = omx->drv_ctx.extradata_info.ion.fd_ion_data.fd;
+#endif
+ plane[extra_idx].reserved[1] = v4l2_buf_ptr->index * omx->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: %u", extra_idx);
+ return -1;
+ }
+
+ DEBUG_PRINT_LOW("SENDING FTB TO F/W from async_message_process - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
+ plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], omx->output_flush_progress);
+ if(ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_QBUF, v4l2_buf_ptr)) {
+ DEBUG_PRINT_ERROR("Failed to queue buffer back to driver: %d, %d, %d", v4l2_buf_ptr->length, v4l2_buf_ptr->m.planes[0].reserved[0], v4l2_buf_ptr->m.planes[1].reserved[0]);
+ return -1;
+ }
+ break;
+ }
+ if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+ }
+
+ output_respbuf = (struct vdec_output_frameinfo *)\
+ omxhdr->pOutputPortPrivate;
+ if (!output_respbuf) {
+ DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
+ return -1;
+ }
+ 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 (vdec_msg->msgdata.output_frame.len) {
+ DEBUG_PRINT_LOW("Processing extradata");
+ omx->handle_extradata(omxhdr);
+
+ if (omx->m_extradata_info.output_crop_updated) {
+ DEBUG_PRINT_LOW("Read FBD crop from output extra data");
+ vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft;
+ vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop;
+ vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth;
+ vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight;
+ vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width;
+ vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height;
+ } else {
+ DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields");
+ 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[2] + plane[0].reserved[4];
+ vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5];
+ vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
+ vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
+ }
+ }
+
+ vdec_msg->msgdata.output_frame.bufferaddr =
+ omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
+
+ if (vdec_msg->msgdata.output_frame.len)
+ memcpy(&omx->drv_ctx.frame_size,
+ &vdec_msg->msgdata.output_frame.framesize,
+ sizeof(struct vdec_framesize));
+
+ DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)"
+ " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
+ omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
+ omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
+ vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
+ (unsigned int)vdec_msg->msgdata.output_frame.len,
+ vdec_msg->msgdata.output_frame.framesize.left,
+ vdec_msg->msgdata.output_frame.framesize.top,
+ vdec_msg->msgdata.output_frame.framesize.right,
+ vdec_msg->msgdata.output_frame.framesize.bottom);
+
+ /* Post event if resolution OR crop changed */
+ /* filled length will be changed if resolution changed */
+ /* Crop parameters can be changed even without resolution change */
+ if (omxhdr->nFilledLen
+ && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
+ || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
+ || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
+ || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
+ || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
+ || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
+ || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
+
+ DEBUG_PRINT_HIGH("Parameters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u",
+ omx->prev_n_filled_len,
+ omx->drv_ctx.video_resolution.frame_width,
+ omx->drv_ctx.video_resolution.frame_height,
+ omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
+ omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
+ omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
+ vdec_msg->msgdata.output_frame.picsize.frame_height,
+ vdec_msg->msgdata.output_frame.framesize.left,
+ vdec_msg->msgdata.output_frame.framesize.top,
+ vdec_msg->msgdata.output_frame.framesize.right,
+ vdec_msg->msgdata.output_frame.framesize.bottom);
+
+ omx->drv_ctx.video_resolution.frame_width =
+ vdec_msg->msgdata.output_frame.picsize.frame_width;
+ omx->drv_ctx.video_resolution.frame_height =
+ vdec_msg->msgdata.output_frame.picsize.frame_height;
+ if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
+ omx->drv_ctx.video_resolution.stride =
+ VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
+ omx->drv_ctx.video_resolution.scan_lines =
+ VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
+ } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
+ omx->drv_ctx.video_resolution.stride =
+ VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
+ omx->drv_ctx.video_resolution.scan_lines =
+ VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
+ }
+
+ 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;
+
+ if (omxhdr && omxhdr->nFilledLen && !omx->high_fps) {
+ omx->request_perf_level(VIDC_NOMINAL);
+ }
+ if (omx->output_use_buffer && omxhdr->pBuffer &&
+ vdec_msg->msgdata.output_frame.bufferaddr)
+ 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 {
+ DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
+ (unsigned int)vdec_msg->msgdata.output_frame.len,
+ omxhdr->nAllocLen, omx->prev_n_filled_len);
+ omxhdr->nFilledLen = 0;
+ }
+
+ omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
+ OMX_COMPONENT_GENERATE_FBD);
+
+ } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
+ omx->post_event ((unsigned long)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("Port settings changed");
+ omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
+ omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
+ omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
+ OMX_COMPONENT_GENERATE_PORT_RECONFIG);
+ if (!omx->high_fps) {
+ omx->request_perf_level(VIDC_NOMINAL);
+ }
+ 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("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 %u, timestamp %lld",
+ (unsigned int)buffer->nFilledLen, (unsigned int)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("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 %lld",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 long)buffer, (unsigned)NULL,
+ (unsigned)NULL)) {
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+ codec_config_flag = false;
+ }
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
+{
+ unsigned long 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 %lld",psource_frame,
+ psource_frame->nTimeStamp);
+ DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
+ (unsigned int)psource_frame->nFlags, (unsigned int)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("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 long address = 0, p2 = 0, id = 0;
+
+ DEBUG_PRINT_LOW("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("Error In Parsing Return Error");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (partial_frame == 0) {
+ DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
+ (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
+
+
+ DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
+ /*First Parsed buffer will have only header Hence skip*/
+ if (frame_count == 0) {
+ DEBUG_PRINT_LOW("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("Zero len buffer return back to POOL");
+ m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
+ (unsigned)NULL);
+ pdest_frame = NULL;
+ }
+ }
+ } else {
+ DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
+ /*Check if Destination Buffer is full*/
+ if (pdest_frame->nAllocLen ==
+ pdest_frame->nFilledLen + pdest_frame->nOffset) {
+ DEBUG_PRINT_ERROR("ERROR: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;
+ pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
+ DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
+ (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
+ DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
+ (unsigned int)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 %lld",psource_frame,
+ psource_frame->nTimeStamp);
+ DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
+ (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
+ }
+ }
+ }
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
+{
+ OMX_U32 partial_frame = 1;
+ unsigned long 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("ERROR:H.264 Scratch Buffer not allocated");
+ return OMX_ErrorBadParameter;
+ }
+ DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
+ "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
+ DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)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("Error:1: Destination buffer overflow for H264");
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
+ in EOS flag getting associated with the destination
+ */
+ if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
+ pdest_frame->nFilledLen) {
+ DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
+ generate_ebd = OMX_FALSE;
+ }
+
+ 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("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("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 = %u",(unsigned int)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 %u",
+ (unsigned int)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("Error:2: Destination buffer overflow for H264");
+ return OMX_ErrorBadParameter;
+ }
+ } else if(h264_scratch.nFilledLen) {
+ look_ahead_nal = true;
+ DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
+ (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
+ DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
+ (unsigned int)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("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 %u", (unsigned int)pdest_frame->nFilledLen);
+ /*Check if Destination Buffer is full*/
+ if (h264_scratch.nAllocLen ==
+ h264_scratch.nFilledLen + h264_scratch.nOffset) {
+ DEBUG_PRINT_ERROR("ERROR: 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) {
+ if(pdest_frame->nFilledLen == 0) {
+ /* No residual frame from before, send whatever
+ * we have left */
+ memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
+ h264_scratch.pBuffer, h264_scratch.nFilledLen);
+ pdest_frame->nFilledLen += h264_scratch.nFilledLen;
+ h264_scratch.nFilledLen = 0;
+ pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
+ } else {
+ m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
+ if(!isNewFrame) {
+ /* Have a residual frame, but we know that the
+ * AU in this frame is belonging to whatever
+ * frame we had left over. So append it */
+ memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
+ h264_scratch.pBuffer,h264_scratch.nFilledLen);
+ pdest_frame->nFilledLen += h264_scratch.nFilledLen;
+ h264_scratch.nFilledLen = 0;
+ if (h264_last_au_ts != LLONG_MAX)
+ pdest_frame->nTimeStamp = h264_last_au_ts;
+ } else {
+ /* Completely new frame, let's just push what
+ * we have now. The resulting EBD would trigger
+ * another push */
+ generate_ebd = OMX_FALSE;
+ pdest_frame->nTimeStamp = h264_last_au_ts;
+ h264_last_au_ts = h264_scratch.nTimeStamp;
+ }
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
+ return OMX_ErrorBadParameter;
+ }
+
+ /* Iff we coalesced two buffers, inherit the flags of both bufs */
+ if(generate_ebd == OMX_TRUE) {
+ pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
+ }
+
+ DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
+ (unsigned int)pdest_frame->nFilledLen,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 %u",
+ pdest_frame, (unsigned int)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 %u src length %u",
+ (unsigned int)psource_frame->nFlags, (unsigned int)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 = 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");
+ rc = OMX_ErrorBadParameter;
+ }
+ return rc;
+}
+
+OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
+{
+ OMX_U32 partial_frame = 1;
+ unsigned long 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("ERROR:Hevc Scratch Buffer not allocated");
+ return OMX_ErrorBadParameter;
+ }
+
+ DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
+ pdest_frame nFilledLen %u nTimeStamp %lld",
+ (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
+
+ if (h264_scratch.nFilledLen && look_ahead_nal) {
+ look_ahead_nal = false;
+ 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("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("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 = %u", (unsigned int)h264_scratch.nFilledLen);
+ if (h264_scratch.nFilledLen) {
+ m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
+ nal_count++;
+ }
+
+ if (!isNewFrame) {
+ DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
+ nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
+ (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
+ (unsigned int)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");
+ 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("FrameDetected # %d pdest_frame nFilledLen %u \
+ nTimeStamp %lld, look_ahead_nal in h264_scratch \
+ nFilledLen %u nTimeStamp %lld",
+ frame_count++, (unsigned int)pdest_frame->nFilledLen,
+ pdest_frame->nTimeStamp, (unsigned int)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", pdest_frame);
+ pdest_frame->nFilledLen = 0;
+ pdest_frame->nFlags = 0;
+ pdest_frame->nTimeStamp = LLONG_MAX;
+ }
+ }
+ }
+ }
+ } else {
+ DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
+ pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
+ nFilledLen %u nTimeStamp %lld",
+ (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
+ (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
+ (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
+
+ if (h264_scratch.nAllocLen ==
+ h264_scratch.nFilledLen + h264_scratch.nOffset) {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+ 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 =%u TimeStamp = %lld",
+ frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
+ 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 %u",
+ pdest_frame, (unsigned int)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 %u nFilledLen %u, nTimeStamp %lld",
+ (unsigned int)psource_frame->nFlags, (unsigned int)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("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("Invalid 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("Destination 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("Error In Parsing VC1 AP start code");
+ return OMX_ErrorBadParameter;
+ }
+ break;
+
+ case VC1_SP_MP_RCV:
+ default:
+ DEBUG_PRINT_ERROR("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("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");
+ 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", fd);
+ return fd;
+ }
+
+ alloc_data->flags = flag;
+ alloc_data->len = buffer_size;
+ alloc_data->align = clip2(alignment);
+ if (alloc_data->align < 4096) {
+ alloc_data->align = 4096;
+ }
+
+ alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
+ if (secure_mode && (alloc_data->flags & ION_SECURE)) {
+ alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
+ }
+
+ /* Use secure display cma heap for obvious reasons. */
+ if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
+ alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
+ }
+
+ rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
+ if (rc || !alloc_data->handle) {
+ DEBUG_PRINT_ERROR("ION ALLOC memory failed");
+ alloc_data->handle = 0;
+ 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("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;
+ fd = -ENOMEM;
+ }
+
+ return fd;
+}
+
+void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
+{
+
+ if (!buf_ion_info) {
+ DEBUG_PRINT_ERROR("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("ION: free failed" );
+ }
+ close(buf_ion_info->ion_device_fd);
+ buf_ion_info->ion_device_fd = -1;
+ buf_ion_info->ion_alloc_data.handle = 0;
+ 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
+ buf_ref_remove();
+}
+
+void omx_vdec::free_input_buffer_header()
+{
+ input_use_buffer = false;
+ if (arbitrary_bytes) {
+ 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;
+ }
+ /* We just freed all the buffer headers, every thing in m_input_free_q,
+ * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
+ while (m_input_free_q.m_size) {
+ unsigned long address, p2, id;
+ m_input_free_q.pop_entry(&address, &p2, &id);
+ }
+ while (m_input_pending_q.m_size) {
+ unsigned long address, p2, id;
+ m_input_pending_q.pop_entry(&address, &p2, &id);
+ }
+ pdest_frame = NULL;
+ psource_frame = 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
+}
+
+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", 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, default_extra_data_size = 0;
+ unsigned int final_extra_data_size = 0;
+ struct v4l2_format fmt;
+ int ret = 0;
+ DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
+ buffer_prop->actualcount, (unsigned int)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 {
+ bool is_res_1080p_or_below = (drv_ctx.video_resolution.frame_width <= 1920 &&
+ drv_ctx.video_resolution.frame_height <= 1088) ||
+ (drv_ctx.video_resolution.frame_height <= 1088 &&
+ drv_ctx.video_resolution.frame_width <= 1920);
+
+ int fps = drv_ctx.frame_rate.fps_numerator / (float)drv_ctx.frame_rate.fps_denominator;
+ bool fps_above_180 = (fps >= 180 || operating_frame_rate >= 180) ? true : false;
+ bool increase_output = (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) && (bufreq.count >= 16);
+
+ if (increase_output && fps_above_180 &&
+ output_capability == V4L2_PIX_FMT_H264 &&
+ is_res_1080p_or_below) {
+ high_fps = true;
+ DEBUG_PRINT_LOW("High fps - fps = %d operating_rate = %d", fps, operating_frame_rate);
+ DEBUG_PRINT_LOW("getbufreq[output]: Increase buffer count (%d) to (%d) to support high fps",
+ bufreq.count, bufreq.count + 10);
+ bufreq.count += 10;
+ ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
+ if (ret) {
+ DEBUG_PRINT_ERROR("(Failed to set updated buffer count to driver");
+ eRet = OMX_ErrorInsufficientResources;
+ return eRet;
+ }
+ DEBUG_PRINT_LOW("new buf count = %d set to driver", bufreq.count);
+ request_perf_level(VIDC_TURBO);
+ }
+
+ buffer_prop->actualcount = bufreq.count;
+ buffer_prop->mincount = bufreq.count;
+ DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
+ }
+ DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
+ buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
+
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+
+ 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",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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+
+ default_extra_data_size = VENUS_EXTRADATA_SIZE(
+ drv_ctx.video_resolution.frame_height,
+ drv_ctx.video_resolution.frame_width);
+ final_extra_data_size = extra_data_size > default_extra_data_size ?
+ extra_data_size : default_extra_data_size;
+
+ final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
+ (~(buffer_prop->alignment - 1));
+
+ drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
+ drv_ctx.extradata_info.count = buffer_prop->actualcount;
+ drv_ctx.extradata_info.buffer_size = final_extra_data_size;
+ buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
+ DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
+ buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
+ if (extra_data_size)
+ DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
+ drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_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(%u)",
+ buffer_prop->actualcount, (unsigned int)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, c_fmt;
+ struct v4l2_requestbuffers bufreq;
+ int ret = 0;
+ DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
+ buffer_prop->actualcount, (unsigned int)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(%u) Required(%d)",
+ (unsigned int)buffer_prop->buffer_size, buf_size);
+ eRet = OMX_ErrorBadParameter;
+ } else {
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ memset(&c_fmt, 0x0, sizeof(struct v4l2_format));
+ 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.plane_fmt[0].sizeimage = buf_size;
+
+ if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
+ fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = output_capability;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
+ c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ c_fmt.fmt.pix_mp.pixelformat = capture_capability;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt);
+ c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt);
+ } else {
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ 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;
+ struct v4l2_format fmt;
+ if (!portDefn) {
+ return OMX_ErrorBadParameter;
+ }
+ DEBUG_PRINT_LOW("omx_vdec::update_portdef");
+ portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
+ portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
+ 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) << 16; //Q16 format
+ else {
+ DEBUG_PRINT_ERROR("Error: Divide by zero");
+ return OMX_ErrorBadParameter;
+ }
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ 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;
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = output_capability;
+ ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ } else if (1 == portDefn->nPortIndex) {
+ unsigned int buf_size = 0;
+ int ret = 0;
+ if (!is_down_scalar_enabled) {
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ }
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Get Resolution failed");
+ return OMX_ErrorHardware;
+ }
+ drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+ if (!client_buffers.update_buffer_req()) {
+ DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
+ return OMX_ErrorHardware;
+ }
+
+ if (!client_buffers.get_buffer_req(buf_size)) {
+ DEBUG_PRINT_ERROR("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("Error in getting color format");
+ return OMX_ErrorHardware;
+ }
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ } else {
+ portDefn->eDir = OMX_DirMax;
+ DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
+ (int)portDefn->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ 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]);
+
+ 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;
+
+ if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
+ (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
+ portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
+ portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
+ }
+ DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
+ "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
+ (unsigned int)portDefn->nPortIndex,
+ (unsigned int)portDefn->format.video.nFrameWidth,
+ (unsigned int)portDefn->format.video.nFrameHeight,
+ (int)portDefn->format.video.nStride,
+ (unsigned int)portDefn->format.video.nSliceHeight,
+ (unsigned int)portDefn->format.video.eColorFormat,
+ (unsigned int)portDefn->nBufferSize,
+ (unsigned int)portDefn->nBufferCountActual);
+
+ 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 %u PMEM %d PL %d",nBufHdrSize,
+ (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
+ nPMEMInfoSize,
+ nPlatformListSize);
+ DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , 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);
+ if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
+ DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
+ return OMX_ErrorInsufficientResources;
+ }
+
+#ifdef USE_ION
+ drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
+ calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
+ if (!drv_ctx.op_buf_ion_info) {
+ DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ if (dynamic_buf_mode) {
+ out_dynamic_list = (struct dynamic_buf_list *) \
+ calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
+ if (out_dynamic_list) {
+ for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++)
+ out_dynamic_list[i].dup_fd = -1;
+ }
+ }
+
+ 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 = -1;
+ 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]",\
+ 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 long p1, p2, 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("ERROR: empty_buffer_done() failed!");
+ omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FBD:
+ if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
+ DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
+ 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 : (act_timestamp - prev_ts) > 0 ?
+ llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
+ 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)",
+ (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
+ (float)drv_ctx.frame_rate.fps_denominator);
+ m_perf_control.request_cores(frm_int);
+ /* 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;
+ prev_ts_actual = 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_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
+ (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
+ prev_ts_actual = act_timestamp; //unadjusted previous timestamp
+ 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 {
+ if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
+ // ensure that timestamps can never step backwards when in display order
+ act_timestamp = prev_ts;
+ }
+ 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;
+ }
+}
+
+OMX_BUFFERHEADERTYPE* omx_vdec::get_omx_output_buffer_header(int index)
+{
+ return m_out_mem_ptr + index;
+}
+
+void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
+ OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects)
+{
+ switch (primaries) {
+ case MSM_VIDC_BT709_5:
+ *color_space = ITU_R_709;
+ aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
+ break;
+ case MSM_VIDC_BT470_6_M:
+ aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
+ break;
+ case MSM_VIDC_BT601_6_625:
+ aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
+ break;
+ case MSM_VIDC_BT601_6_525:
+ *color_space = range ? ITU_R_601_FR : ITU_R_601;
+ aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
+ break;
+ case MSM_VIDC_GENERIC_FILM:
+ aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
+ break;
+ case MSM_VIDC_BT2020:
+ aspects->mPrimaries = ColorAspects::PrimariesBT2020;
+ break;
+ case MSM_VIDC_UNSPECIFIED:
+ //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
+ default:
+ //aspects->mPrimaries = ColorAspects::PrimariesOther;
+ aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
+ break;
+ }
+
+ aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
+
+ switch (transfer) {
+ case MSM_VIDC_TRANSFER_BT709_5:
+ case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
+ aspects->mTransfer = ColorAspects::TransferSMPTE170M;
+ break;
+ case MSM_VIDC_TRANSFER_BT_470_6_M:
+ aspects->mTransfer = ColorAspects::TransferGamma22;
+ break;
+ case MSM_VIDC_TRANSFER_BT_470_6_BG:
+ aspects->mTransfer = ColorAspects::TransferGamma28;
+ break;
+ case MSM_VIDC_TRANSFER_SMPTE_240M:
+ aspects->mTransfer = ColorAspects::TransferSMPTE240M;
+ break;
+ case MSM_VIDC_TRANSFER_LINEAR:
+ aspects->mTransfer = ColorAspects::TransferLinear;
+ break;
+ case MSM_VIDC_TRANSFER_IEC_61966:
+ aspects->mTransfer = ColorAspects::TransferXvYCC;
+ break;
+ case MSM_VIDC_TRANSFER_BT_1361:
+ aspects->mTransfer = ColorAspects::TransferBT1361;
+ break;
+ case MSM_VIDC_TRANSFER_SRGB:
+ aspects->mTransfer = ColorAspects::TransferSRGB;
+ break;
+ default:
+ //aspects->mTransfer = ColorAspects::TransferOther;
+ aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
+ break;
+ }
+
+ switch (matrix) {
+ case MSM_VIDC_MATRIX_BT_709_5:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
+ break;
+ case MSM_VIDC_MATRIX_FCC_47:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
+ break;
+ case MSM_VIDC_MATRIX_601_6_625:
+ case MSM_VIDC_MATRIX_601_6_525:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
+ break;
+ case MSM_VIDC_MATRIX_SMPTE_240M:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
+ break;
+ case MSM_VIDC_MATRIX_BT_2020:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
+ break;
+ case MSM_VIDC_MATRIX_BT_2020_CONST:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
+ break;
+ default:
+ //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
+ aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
+ break;
+ }
+}
+
+void omx_vdec::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
+ DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
+ prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
+}
+
+void omx_vdec::handle_color_space_info(void *data, unsigned int buf_index)
+{
+ ColorSpace_t color_space = ITU_R_601;
+ ColorAspects tempAspects;
+ memset(&tempAspects, 0x0, sizeof(ColorAspects));
+ ColorAspects *aspects = &tempAspects;
+
+ switch(output_capability) {
+ case V4L2_PIX_FMT_MPEG2:
+ {
+ struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
+ seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
+
+ /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
+ * understand this code */
+
+ if (seqdisp_payload && seqdisp_payload->color_descp) {
+
+ convert_color_space_info(seqdisp_payload->color_primaries, 1,
+ seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
+ &color_space,aspects);
+ m_disp_hor_size = seqdisp_payload->disp_width;
+ m_disp_vert_size = seqdisp_payload->disp_height;
+ }
+ }
+ break;
+ case V4L2_PIX_FMT_H264:
+ case V4L2_PIX_FMT_HEVC:
+ {
+ struct msm_vidc_vui_display_info_payload *display_info_payload;
+ display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
+
+ /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
+
+ if (display_info_payload->video_signal_present_flag &&
+ display_info_payload->color_description_present_flag) {
+ convert_color_space_info(display_info_payload->color_primaries,
+ display_info_payload->video_full_range_flag,
+ display_info_payload->transfer_characteristics,
+ display_info_payload->matrix_coefficients,
+ &color_space,aspects);
+ }
+ }
+ break;
+ case V4L2_PIX_FMT_VC1_ANNEX_G:
+ case V4L2_PIX_FMT_VC1_ANNEX_L:
+ {
+ struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload;
+ vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data;
+
+ /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23
+ * SMPTE 421M to understand this code */
+
+ if (m_enable_android_native_buffers &&
+ vc1_seq_disp_payload->color_primaries) {
+
+ convert_color_space_info(vc1_seq_disp_payload->color_primaries,
+ 1,
+ vc1_seq_disp_payload->transfer_char,
+ vc1_seq_disp_payload->matrix_coeffs,
+ &color_space,aspects);
+ }
+ }
+ break;
+ case V4L2_PIX_FMT_VP8:
+ {
+ struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
+ vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
+
+ /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
+ * to understand this code */
+
+ if (vpx_color_space_payload->color_space == 0) {
+ color_space = ITU_R_601;
+ } else {
+ DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
+ break;
+ }
+ }
+ break;
+ case V4L2_PIX_FMT_VP9:
+ {
+ struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
+ vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
+
+ /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
+ * to understand this code */
+
+ switch(vpx_color_space_payload->color_space) {
+ case MSM_VIDC_CS_BT_601:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
+ aspects->mTransfer = ColorAspects::TransferSMPTE170M;
+ aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
+ aspects->mRange = m_client_color_space.sAspects.mRange;
+ break;
+ case MSM_VIDC_CS_BT_709:
+ color_space = ITU_R_709;
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
+ aspects->mTransfer = ColorAspects::TransferSMPTE170M;
+ aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
+ aspects->mRange = m_client_color_space.sAspects.mRange;
+ break;
+ case MSM_VIDC_CS_SMPTE_170:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
+ aspects->mTransfer = ColorAspects::TransferSMPTE170M;
+ aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
+ aspects->mRange = m_client_color_space.sAspects.mRange;
+ break;
+ case MSM_VIDC_CS_SMPTE_240:
+ aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
+ aspects->mTransfer = ColorAspects::TransferSMPTE240M;
+ aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
+ aspects->mRange = m_client_color_space.sAspects.mRange;
+ break;
+ case MSM_VIDC_CS_BT_2020:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
+ aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
+ aspects->mPrimaries = ColorAspects::PrimariesBT2020;
+ aspects->mRange = m_client_color_space.sAspects.mRange;
+ break;
+ case MSM_VIDC_CS_RESERVED:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
+ aspects->mTransfer = ColorAspects::TransferOther;
+ aspects->mPrimaries = ColorAspects::PrimariesOther;
+ aspects->mRange = m_client_color_space.sAspects.mRange;
+ break;
+ case MSM_VIDC_CS_RGB:
+ aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
+ aspects->mTransfer = ColorAspects::TransferSMPTE170M;
+ aspects->mPrimaries = ColorAspects::PrimariesOther;
+ aspects->mRange = m_client_color_space.sAspects.mRange;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (m_enable_android_native_buffers) {
+ DEBUG_PRINT_HIGH("setMetaData for Color Space = 0x%x (601=%u FR=%u 709=%u)", color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+ set_colorspace_in_handle(color_space, buf_index);
+ }
+ print_debug_color_aspects(aspects, "Bitstream");
+
+ if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
+ m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
+ m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
+ m_internal_color_space.sAspects.mRange != aspects->mRange) {
+ memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
+ m_internal_color_space.bDataSpaceChanged = OMX_TRUE;
+
+ DEBUG_PRINT_HIGH("Initiating PORT Reconfig");
+ print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
+ print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
+
+ post_event(OMX_CORE_OUTPUT_PORT_INDEX,
+ OMX_QTIIndexConfigDescribeColorAspects,
+ OMX_COMPONENT_GENERATE_PORT_RECONFIG);
+ }
+}
+
+void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) {
+ private_handle_t *private_handle = NULL;
+ if (buf_index < drv_ctx.op_buf.actualcount &&
+ buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
+ native_buffer[buf_index].privatehandle) {
+ private_handle = native_buffer[buf_index].privatehandle;
+ }
+ if (private_handle) {
+ setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space);
+ }
+}
+
+void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
+{
+ OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL;
+ OMX_U8 *pBuffer = NULL;
+ OMX_U32 num_conceal_MB = 0;
+ OMX_TICKS time_stamp = 0;
+ OMX_U32 frame_rate = 0;
+ unsigned long consumed_len = 0;
+ OMX_U32 num_MB_in_frame;
+ OMX_U32 recovery_sei_flags = 1;
+ int enable = OMX_InterlaceFrameProgressive;
+
+ if (output_flush_progress)
+ return;
+
+ int buf_index = p_buf_hdr - m_out_mem_ptr;
+ if (buf_index >= drv_ctx.extradata_info.count) {
+ DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
+ buf_index, drv_ctx.extradata_info.count);
+ return;
+ }
+ struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
+
+ if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) {
+ DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
+ return;
+ }
+
+ if (!drv_ctx.extradata_info.uaddr) {
+ DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
+ return;
+ }
+ if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
+ DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
+ p_extra = NULL;
+ return;
+ }
+ if (!secure_mode) {
+ pBuffer = (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[buf_index].buffer_len,
+ PROT_READ|PROT_WRITE, MAP_SHARED, drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, 0);
+ if (pBuffer == MAP_FAILED) {
+ DEBUG_PRINT_ERROR("handle_extradata output buffer mmap failed - errno: %d", errno);
+ return;
+ }
+ p_extra = (OMX_OTHER_EXTRADATATYPE *)
+ ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
+ } else
+ p_extra = m_other_extradata;
+
+ AutoUnmap autounmap(pBuffer, drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
+ if (m_client_extradata_info.getBase() &&
+ m_client_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) {
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (m_client_extradata_info.getBase() +
+ buf_index * m_client_extradata_info.getSize());
+ }
+
+ char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
+
+ if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
+ p_extra = NULL;
+ DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
+ return;
+ }
+ m_extradata_info.output_crop_updated = OMX_FALSE;
+ OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
+ if (data && p_extra) {
+ while ((consumed_len < drv_ctx.extradata_info.buffer_size)
+ && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
+ if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
+ DEBUG_PRINT_LOW("Invalid extra data size");
+ break;
+ }
+
+ if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
+ p_extra = NULL;
+ DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
+ return;
+ }
+
+ DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
+ switch ((unsigned long)data->eType) {
+ case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
+ struct msm_vidc_interlace_payload *payload;
+ OMX_U32 interlace_color_format;
+ payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
+ if (payload) {
+ enable = OMX_InterlaceFrameProgressive;
+ switch (payload->format) {
+ case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
+ drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
+ break;
+ case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
+ drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
+ enable = OMX_InterlaceInterleaveFrameTopFieldFirst;
+ break;
+ case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
+ drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
+ enable = OMX_InterlaceInterleaveFrameBottomFieldFirst;
+ break;
+ default:
+ DEBUG_PRINT_LOW("default case - set to progressive");
+ drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
+ }
+ switch (payload->color_format) {
+ case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12:
+ interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ break;
+ case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC:
+ interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
+ break;
+ default:
+ interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame");
+ }
+ }
+
+ if (m_enable_android_native_buffers) {
+ DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d",
+ payload->format, interlace_color_format ,enable,
+ (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false);
+
+ setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
+ PP_PARAM_INTERLACED, (void*)&enable);
+
+ if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
+ setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
+ LINEAR_FORMAT, (void*)&interlace_color_format);
+ } else if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
+ setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
+ LINEAR_FORMAT, NULL);
+ }
+ }
+ if (client_extradata & OMX_INTERLACE_EXTRADATA) {
+ append_interlace_extradata(p_extra, payload->format);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_interlace_extradata(p_client_extra, payload->format);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *)
+ (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_FRAME_RATE:
+ struct msm_vidc_framerate_payload *frame_rate_payload;
+ frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
+ frame_rate = frame_rate_payload->frame_rate;
+ break;
+ case MSM_VIDC_EXTRADATA_TIMESTAMP:
+ struct msm_vidc_ts_payload *time_stamp_payload;
+ time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
+ time_stamp = time_stamp_payload->timestamp_lo;
+ time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
+ p_buf_hdr->nTimeStamp = time_stamp;
+ break;
+ case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
+ struct msm_vidc_concealmb_payload *conceal_mb_payload;
+ conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)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 MSM_VIDC_EXTRADATA_INDEX:
+ int *etype;
+ etype = (int *)(void *)data->data;
+ if (etype && *etype == MSM_VIDC_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;
+ }
+ } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) {
+ struct msm_vidc_output_crop_payload *output_crop_payload;
+ output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype);
+ if (output_crop_payload) {
+ m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left;
+ m_extradata_info.output_crop_rect.nTop = output_crop_payload->top;
+ m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width;
+ m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height;
+ m_extradata_info.output_width = output_crop_payload->width;
+ m_extradata_info.output_height = output_crop_payload->height;
+ m_extradata_info.output_crop_updated = OMX_TRUE;
+ }
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
+ struct msm_vidc_recoverysei_payload *recovery_sei_payload;
+ recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
+ recovery_sei_flags = recovery_sei_payload->flags;
+ if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
+ p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
+ DEBUG_PRINT_HIGH("***************************************************");
+ DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
+ DEBUG_PRINT_HIGH("***************************************************");
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
+ panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
+ if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
+ DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
+ DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
+ MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
+ return;
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
+ case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
+ case MSM_VIDC_EXTRADATA_VC1_SEQDISP:
+ case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
+ handle_color_space_info((void *)data->data, buf_index);
+ break;
+ case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
+ struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
+ s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
+ switch (s3d_frame_packing_payload->fpa_type) {
+ case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE:
+ if (s3d_frame_packing_payload->content_interprtation_type == 1)
+ stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R;
+ else if (s3d_frame_packing_payload->content_interprtation_type == 2)
+ stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L;
+ else {
+ DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type");
+ stereo_output_mode = HAL_NO_3D;
+ }
+ break;
+ case MSM_VIDC_FRAMEPACK_TOP_BOTTOM:
+ stereo_output_mode = HAL_3D_TOP_BOTTOM;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("Unsupported framepacking type");
+ stereo_output_mode = HAL_NO_3D;
+ }
+ DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d",
+ s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode);
+ if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
+ append_framepack_extradata(p_extra, s3d_frame_packing_payload);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_framepack_extradata(p_client_extra, s3d_frame_packing_payload);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_FRAME_QP:
+ struct msm_vidc_frame_qp_payload *qp_payload;
+ qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
+ if (client_extradata & OMX_QP_EXTRADATA) {
+ append_qp_extradata(p_extra, qp_payload);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_qp_extradata(p_client_extra, qp_payload);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
+ struct msm_vidc_frame_bits_info_payload *bits_info_payload;
+ bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
+ if (client_extradata & OMX_BITSINFO_EXTRADATA) {
+ append_bitsinfo_extradata(p_extra, bits_info_payload);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_bitsinfo_extradata(p_client_extra, bits_info_payload);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
+ if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
+ append_user_extradata(p_extra, data);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_user_extradata(p_client_extra, data);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ break;
+ case MSM_VIDC_EXTRADATA_VQZIP_SEI:
+ struct msm_vidc_vqzip_sei_payload *vqzip_payload;
+ vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data;
+ if (client_extradata & OMX_VQZIPSEI_EXTRADATA) {
+ p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
+ append_vqzip_extradata(p_extra, vqzip_payload);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_vqzip_extradata(p_client_extra, vqzip_payload);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ break;
+ default:
+ DEBUG_PRINT_LOW("Unrecognized extradata");
+ goto unrecognized_extradata;
+ }
+ consumed_len += data->nSize;
+ data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+ }
+ if (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,
+ time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
+ p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_frame_info_extradata(p_client_extra,
+ num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
+ time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
+ p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
+ append_frame_dimension_extradata(p_extra);
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
+ if (p_client_extra) {
+ append_frame_dimension_extradata(p_client_extra);
+ p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
+ }
+ }
+ }
+unrecognized_extradata:
+ if (client_extradata && p_extra) {
+ p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
+ append_terminator_extradata(p_extra);
+ if (p_client_extra) {
+ append_terminator_extradata(p_client_extra);
+ }
+ }
+ if (secure_mode && p_extradata && m_other_extradata) {
+ struct vdec_output_frameinfo *ptr_extradatabuff = NULL;
+ memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
+ ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
+ ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
+ ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
+ ptr_extradatabuff->metadata_info.fd = drv_ctx.extradata_info.ion.fd_ion_data.fd;
+ ptr_extradatabuff->metadata_info.offset = buf_index * drv_ctx.extradata_info.buffer_size;
+ ptr_extradatabuff->metadata_info.buffer_size = drv_ctx.extradata_info.size;
+ }
+ 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_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
+ (unsigned int)client_extradata, (unsigned int)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.");
+ }
+ }
+ 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");
+ }
+ 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");
+ }
+ 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");
+ }
+ 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");
+ }
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set panscan extradata");
+ }
+ 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");
+ }
+ }
+ }
+ 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");
+ }
+ }
+ if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) {
+ if (output_capability == V4L2_PIX_FMT_H264) {
+ DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
+ }
+ } else {
+ DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
+ }
+ }
+ if (requested_extradata & OMX_QP_EXTRADATA) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set QP extradata");
+ }
+ }
+ if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
+ }
+ }
+ if (!secure_mode && (requested_extradata & OMX_EXTNUSER_EXTRADATA)) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
+ }
+ }
+ if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata");
+ }
+ client_extradata |= OMX_VQZIPSEI_EXTRADATA;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set QP extradata");
+ }
+ client_extradata |= OMX_QP_EXTRADATA;
+ }
+ if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP;
+ DEBUG_PRINT_LOW("Enable output crop extra data");
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set output crop extradata");
+ }
+ }
+ if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ switch(output_capability) {
+ case V4L2_PIX_FMT_H264:
+ case V4L2_PIX_FMT_HEVC:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
+ break;
+ case CODEC_TYPE_MPEG2:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
+ break;
+ case V4L2_PIX_FMT_VP8:
+ case V4L2_PIX_FMT_VP9:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
+ break;
+ case V4L2_PIX_FMT_VC1_ANNEX_G:
+ case V4L2_PIX_FMT_VC1_ANNEX_L:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP;
+ break;
+ default:
+ DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
+ return ret;
+ }
+
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_HIGH("Failed to set Display info extradata");
+ }
+ }
+ }
+ 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 || !extra)
+ return;
+
+
+ DEBUG_PRINT_HIGH(
+ "============== Extra Data ==============\n"
+ " Size: %u\n"
+ " Version: %u\n"
+ " PortIndex: %u\n"
+ " Type: %x\n"
+ " DataSize: %u",
+ (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
+ (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
+
+ if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
+ OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
+ DEBUG_PRINT_HIGH(
+ "------ Interlace Format ------\n"
+ " Size: %u\n"
+ " Version: %u\n"
+ " PortIndex: %u\n"
+ " Is Interlace Format: %d\n"
+ " Interlace Formats: %u\n"
+ "=========== End of Interlace ===========",
+ (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
+ intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
+ } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
+ OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
+
+ DEBUG_PRINT_HIGH(
+ "-------- Frame Format --------\n"
+ " Picture Type: %d\n"
+ " Interlace Type: %d\n"
+ " Pan Scan Total Frame Num: %u\n"
+ " Concealed Macro Blocks: %u\n"
+ " frame rate: %u\n"
+ " Time Stamp: %llu\n"
+ " Aspect Ratio X: %u\n"
+ " Aspect Ratio Y: %u",
+ fminfo->ePicType,
+ fminfo->interlaceType,
+ (unsigned int)fminfo->panScan.numWindows,
+ (unsigned int)fminfo->nConcealedMacroblocks,
+ (unsigned int)fminfo->nFrameRate,
+ fminfo->nTimeStamp,
+ (unsigned int)fminfo->aspectRatio.aspectRatioX,
+ (unsigned int)fminfo->aspectRatio.aspectRatioY);
+
+ for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
+ DEBUG_PRINT_HIGH(
+ "------------------------------"
+ " Pan Scan Frame Num: %u\n"
+ " Rectangle x: %d\n"
+ " Rectangle y: %d\n"
+ " Rectangle dx: %d\n"
+ " Rectangle dy: %d",
+ (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
+ (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
+ }
+
+ DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
+ } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
+ OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
+ DEBUG_PRINT_HIGH(
+ "------------------ Framepack Format ----------\n"
+ " id: %u \n"
+ " cancel_flag: %u \n"
+ " type: %u \n"
+ " quincunx_sampling_flagFormat: %u \n"
+ " content_interpretation_type: %u \n"
+ " spatial_flipping_flag: %u \n"
+ " frame0_flipped_flag: %u \n"
+ " field_views_flag: %u \n"
+ " current_frame_is_frame0_flag: %u \n"
+ " frame0_self_contained_flag: %u \n"
+ " frame1_self_contained_flag: %u \n"
+ " frame0_grid_position_x: %u \n"
+ " frame0_grid_position_y: %u \n"
+ " frame1_grid_position_x: %u \n"
+ " frame1_grid_position_y: %u \n"
+ " reserved_byte: %u \n"
+ " repetition_period: %u \n"
+ " extension_flag: %u \n"
+ "================== End of Framepack ===========",
+ (unsigned int)framepack->id,
+ (unsigned int)framepack->cancel_flag,
+ (unsigned int)framepack->type,
+ (unsigned int)framepack->quincunx_sampling_flag,
+ (unsigned int)framepack->content_interpretation_type,
+ (unsigned int)framepack->spatial_flipping_flag,
+ (unsigned int)framepack->frame0_flipped_flag,
+ (unsigned int)framepack->field_views_flag,
+ (unsigned int)framepack->current_frame_is_frame0_flag,
+ (unsigned int)framepack->frame0_self_contained_flag,
+ (unsigned int)framepack->frame1_self_contained_flag,
+ (unsigned int)framepack->frame0_grid_position_x,
+ (unsigned int)framepack->frame0_grid_position_y,
+ (unsigned int)framepack->frame1_grid_position_x,
+ (unsigned int)framepack->frame1_grid_position_y,
+ (unsigned int)framepack->reserved_byte,
+ (unsigned int)framepack->repetition_period,
+ (unsigned int)framepack->extension_flag);
+ } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
+ OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
+ DEBUG_PRINT_HIGH(
+ "---- QP (Frame quantization parameter) ----\n"
+ " Frame QP: %u \n"
+ "================ End of QP ================\n",
+ (unsigned int)qp->nQP);
+ } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
+ OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
+ DEBUG_PRINT_HIGH(
+ "--------- Input bits information --------\n"
+ " Header bits: %u \n"
+ " Frame bits: %u \n"
+ "===== End of Input bits information =====\n",
+ (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
+ } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
+ OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
+ OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
+ OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
+ OMX_U32 i = 0;
+ DEBUG_PRINT_HIGH(
+ "-------------- Userdata -------------\n"
+ " Stream userdata type: %u\n"
+ " userdata size: %u\n"
+ " STREAM_USERDATA:",
+ (unsigned int)userdata->type, (unsigned int)userdata_size);
+ for (i = 0; i < userdata_size; i+=4) {
+ DEBUG_PRINT_HIGH(" %x %x %x %x",
+ data_ptr[i], data_ptr[i+1],
+ data_ptr[i+2], data_ptr[i+3]);
+ }
+ DEBUG_PRINT_HIGH(
+ "=========== End of Userdata ===========");
+ } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
+ OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
+ DEBUG_PRINT_HIGH(
+ "-------------- VQZip -------------\n"
+ " Size: %u\n",
+ (unsigned int)vq->nSize);
+ DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
+ } 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;
+
+ if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
+ return;
+ }
+ if (!extra) {
+ DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
+ 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 *)(void *)extra->data;
+ interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
+ interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
+ interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+
+ if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
+ interlace_format->bInterlaceFormat = OMX_FALSE;
+ interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
+ drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
+ } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) {
+ interlace_format->bInterlaceFormat = OMX_TRUE;
+ interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
+ drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
+ } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) {
+ interlace_format->bInterlaceFormat = OMX_TRUE;
+ interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
+ drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
+ } else {
+ //default case - set to progressive
+ interlace_format->bInterlaceFormat = OMX_FALSE;
+ interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
+ drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
+ }
+ print_debug_extradata(extra);
+}
+
+void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
+{
+ OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
+ if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
+ return;
+ }
+ extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
+ extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
+ extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
+ frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
+ frame_dimension->nDecWidth = rectangle.nLeft;
+ frame_dimension->nDecHeight = rectangle.nTop;
+ frame_dimension->nActualWidth = rectangle.nWidth;
+ frame_dimension->nActualHeight = rectangle.nHeight;
+}
+
+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 %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
+ (unsigned int)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,
+ OMX_TICKS time_stamp, 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 *)(void *)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->nTimeStamp = time_stamp;
+ 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;
+ } else {
+ frame_info->displayAspectRatio.displayHorizontalSize = 0;
+ frame_info->displayAspectRatio.displayVerticalSize = 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 *)(void *)extra->data;
+ *portDefn = m_port_def;
+ DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
+ "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
+ (unsigned int)portDefn->format.video.nFrameWidth,
+ (unsigned int)portDefn->format.video.nStride,
+ (unsigned int)portDefn->format.video.nSliceHeight);
+}
+
+void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
+{
+ OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
+ if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
+ DEBUG_PRINT_ERROR("frame packing size mismatch");
+ return;
+ }
+ extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
+ extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
+ extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
+ framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
+ framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
+ framepack->nVersion.nVersion = OMX_SPEC_VERSION;
+ framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ memcpy(&framepack->id, s3d_frame_packing_payload,
+ sizeof(struct msm_vidc_s3d_frame_packing_payload));
+ memcpy(&m_frame_pack_arrangement, framepack,
+ sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
+ print_debug_extradata(extra);
+}
+
+void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_frame_qp_payload *qp_payload)
+{
+ OMX_QCOM_EXTRADATA_QP * qp = NULL;
+ if (!qp_payload) {
+ DEBUG_PRINT_ERROR("QP payload is NULL");
+ return;
+ }
+ extra->nSize = OMX_QP_EXTRADATA_SIZE;
+ extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
+ extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
+ qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
+ qp->nQP = qp_payload->frame_qp;
+ print_debug_extradata(extra);
+}
+
+void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_frame_bits_info_payload *bits_payload)
+{
+ OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
+ if (!bits_payload) {
+ DEBUG_PRINT_ERROR("bits info payload is NULL");
+ return;
+ }
+ extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
+ extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
+ extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
+ bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
+ bits->frame_bits = bits_payload->frame_bits;
+ bits->header_bits = bits_payload->header_bits;
+ print_debug_extradata(extra);
+}
+
+void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ OMX_OTHER_EXTRADATATYPE *p_user)
+{
+ int userdata_size = 0;
+ struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
+ userdata_payload =
+ (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
+ userdata_size = p_user->nDataSize;
+ extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
+ extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
+ extra->nDataSize = userdata_size;
+ if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
+ memcpy(extra->data, p_user->data, extra->nDataSize);
+ print_debug_extradata(extra);
+}
+
+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);
+}
+
+void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+ struct msm_vidc_vqzip_sei_payload *vqzip_payload)
+{
+ OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL;
+
+ extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size;
+ extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI;
+ extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size;
+
+ vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
+ vq->nSize = vqzip_payload->size;
+ memcpy(vq->data, vqzip_payload->data, vqzip_payload->size);
+
+ 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("ERROR: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("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("desc 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 (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)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 (%u) demux entry offsets", (unsigned int)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 (%u)", (unsigned int)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(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
+ (unsigned int)start_addr,
+ (unsigned int)suffix_byte,
+ (unsigned int)nal_size,
+ (unsigned int)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=%u", (unsigned int)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;
+}
+
+void omx_vdec::request_perf_level(enum vidc_perf_level perf_level)
+{
+ struct v4l2_control control;
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+
+ property_get("vidc.debug.turbo", property_value, "0");
+ memset(&control, 0, sizeof(v4l2_control));
+ control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+ switch (perf_level) {
+ case VIDC_NOMINAL:
+ if (atoi(property_value))
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+ else
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
+ break;
+ case VIDC_TURBO:
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("Requested PERF level not supported");
+ break;
+ }
+ if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig)
+ return;
+
+ DEBUG_PRINT_HIGH("changing performance level to %d", control.value);
+ if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+ current_perf_level = control.value;
+ } else {
+ DEBUG_PRINT_ERROR("Failed to set PERF level");
+ }
+}
+
+omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
+{
+ enabled = false;
+ omx = NULL;
+ init_members();
+ ColorFormat = OMX_COLOR_FormatMax;
+ dest_format = YCbCr420P;
+ m_c2d_width = 0;
+ m_c2d_height = 0;
+}
+
+void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
+{
+ omx = reinterpret_cast<omx_vdec*>(client);
+}
+
+void omx_vdec::allocate_color_convert_buf::init_members()
+{
+ allocated_count = 0;
+ buffer_size_req = 0;
+ buffer_alignment_req = 0;
+ m_c2d_width = m_c2d_height = 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;
+ unsigned int height, width;
+ struct v4l2_format fmt;
+ OMX_COLOR_FORMATTYPE drv_color_format;
+
+ if (!omx) {
+ DEBUG_PRINT_ERROR("Invalid client in color convert");
+ return false;
+ }
+ if (!enabled) {
+ DEBUG_PRINT_HIGH("No color conversion required");
+ return status;
+ }
+ pthread_mutex_lock(&omx->c_lock);
+
+ memset(&fmt, 0x0, sizeof(struct v4l2_format));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = omx->capture_capability;
+ ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+ width = fmt.fmt.pix_mp.width;
+ height = fmt.fmt.pix_mp.height;
+
+ bool resolution_upgrade = (height > m_c2d_height ||
+ width > m_c2d_width);
+ if (resolution_upgrade) {
+ // resolution upgraded ? ensure we are yet to allocate;
+ // failing which, c2d buffers will never be reallocated and bad things will happen
+ if (allocated_count > 0) {
+ DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations",
+ allocated_count);
+ status = false;
+ goto fail_update_buf_req;
+ }
+ }
+
+ if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
+ ColorFormat != OMX_COLOR_FormatYUV420Planar) {
+ DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
+ status = false;
+ goto fail_update_buf_req;
+ }
+ c2d.close();
+ status = c2d.open(height,
+ width,
+ NV12_128m,dest_format);
+ 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("ERROR: Size mismatch in C2D src_size %d"
+ "driver size %u destination size %d",
+ src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
+ destination_size);
+ status = false;
+ c2d.close();
+ buffer_size_req = 0;
+ // TODO: make this fatal. Driver is not supposed to quote size
+ // smaller than what C2D needs !!
+ } else {
+ buffer_size_req = destination_size;
+ m_c2d_height = height;
+ m_c2d_width = width;
+ }
+ }
+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("Invalid client in color convert");
+ return false;
+ }
+ pthread_mutex_lock(&omx->c_lock);
+ if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
+ if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
+ drv_color_format = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
+ else
+ drv_color_format = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
+ drv_color_format = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
+ } else {
+ DEBUG_PRINT_ERROR("Incorrect color format");
+ status = false;
+ }
+ if (status &&
+ drv_color_format != dest_color_format &&
+ drv_color_format != (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView &&
+ drv_color_format != (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed &&
+ dest_color_format != (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
+ DEBUG_PRINT_LOW("Enabling C2D");
+ if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
+ (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
+ DEBUG_PRINT_ERROR("Unsupported color format for c2d");
+ status = false;
+ } else {
+ ColorFormat = dest_color_format;
+ dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
+ YCbCr420P : YCbCr420SP;
+ if (enabled)
+ c2d.destroy();
+ enabled = false;
+ if (!c2d.init()) {
+ DEBUG_PRINT_ERROR("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("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("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);
+ cache_clean_buffer(index);
+ 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]);
+ if (!status) {
+ DEBUG_PRINT_ERROR("Failed color conversion %d", status);
+ m_out_mem_ptr_client[index].nFilledLen = 0;
+ pthread_mutex_unlock(&omx->c_lock);
+ return &m_out_mem_ptr_client[index];
+ } else {
+ unsigned int filledLen = 0;
+ c2d.get_output_filled_length(filledLen);
+ m_out_mem_ptr_client[index].nFilledLen = filledLen;
+ cache_clean_invalidate_buffer(index);
+ }
+ pthread_mutex_unlock(&omx->c_lock);
+ } else
+ m_out_mem_ptr_client[index].nFilledLen = 0;
+ return &m_out_mem_ptr_client[index];
+ }
+ DEBUG_PRINT_ERROR("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("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("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("Get buffer size failed");
+ status = false;
+ goto fail_get_buffer_size;
+ }
+ }
+fail_get_buffer_size:
+ pthread_mutex_unlock(&omx->c_lock);
+ return status;
+}
+
+OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req(
+ OMX_U32 buffer_size, OMX_U32 actual_count) {
+ OMX_U32 expectedSize = enabled ? buffer_size_req : omx->drv_ctx.op_buf.buffer_size;
+
+ if (buffer_size < expectedSize) {
+ DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)",
+ buffer_size, expectedSize);
+ return OMX_ErrorBadParameter;
+ }
+ if (actual_count < omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)",
+ actual_count, omx->drv_ctx.op_buf.actualcount);
+ return OMX_ErrorBadParameter;
+ }
+
+ bool reqs_updated = false;
+ if (enabled) {
+ // disallow changing buffer size/count while we have active allocated buffers
+ if (allocated_count > 0) {
+ DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations",
+ buffer_size_req, buffer_size, allocated_count);
+ return OMX_ErrorInvalidState;
+ }
+
+ buffer_size_req = buffer_size;
+ } else {
+ if (buffer_size > omx->drv_ctx.op_buf.buffer_size) {
+ omx->drv_ctx.op_buf.buffer_size = buffer_size;
+ reqs_updated = true;
+ }
+ }
+
+ if (actual_count > omx->drv_ctx.op_buf.actualcount) {
+ omx->drv_ctx.op_buf.actualcount = actual_count;
+ reqs_updated = true;
+ }
+
+ if (reqs_updated) {
+ omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount;
+ omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count *
+ omx->drv_ctx.extradata_info.buffer_size;
+ return omx->set_buffer_req(&(omx->drv_ctx.op_buf));
+ }
+ return OMX_ErrorNone;
+}
+
+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("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("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("Notin color convert mode secure_mode %d",
+ omx->is_component_secure());
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (!bufferHdr || bytes > buffer_size_req) {
+ DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
+ DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u",
+ (unsigned int)buffer_size_req, (unsigned int)bytes);
+ return OMX_ErrorBadParameter;
+ }
+ if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("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("Buffer allocation failed color_convert");
+ return eRet;
+ }
+ if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
+ (int)omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("Invalid header index %ld",
+ (long int)(temp_bufferHdr - omx->m_out_mem_ptr));
+ return OMX_ErrorUndefined;
+ }
+ unsigned int i = allocated_count;
+#ifdef USE_ION
+ // Allocate color-conversion buffers as cached to improve software-reading
+ // performance of YUV (thumbnails). NOTE: These buffers will need an explicit
+ // cache invalidation.
+ 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("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("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 = (unsigned long)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_HIGH("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) {
+ if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
+ dest_color_format = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
+ else
+ dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){
+ dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
+ } else
+ status = false;
+ } else {
+ if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
+ ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
+ dest_color_format = ColorFormat;
+ } else
+ status = false;
+ }
+ return status;
+}
+
+OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops(
+ unsigned int index, unsigned int cmd)
+{
+ if (!enabled) {
+ return OMX_ErrorNone;
+ }
+
+ if (!omx || index >= omx->drv_ctx.op_buf.actualcount) {
+ DEBUG_PRINT_ERROR("%s: Invalid param", __func__);
+ return OMX_ErrorBadParameter;
+ }
+
+ struct ion_flush_data flush_data;
+ struct ion_custom_data custom_data;
+
+ memset(&flush_data, 0x0, sizeof(flush_data));
+ memset(&custom_data, 0x0, sizeof(custom_data));
+
+ flush_data.vaddr = pmem_baseaddress[index];
+ flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd;
+ flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle;
+ flush_data.length = buffer_size_req;
+ custom_data.cmd = cmd;
+ custom_data.arg = (unsigned long)&flush_data;
+
+ DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d",
+ (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
+ flush_data.fd, flush_data.handle, flush_data.vaddr,
+ flush_data.length);
+ int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data);
+ if (ret < 0) {
+ DEBUG_PRINT_ERROR("Cache %s failed: %s\n",
+ (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
+ strerror(errno));
+ return OMX_ErrorUndefined;
+ }
+ return OMX_ErrorNone;
+}
+
+void omx_vdec::buf_ref_add(int nPortIndex)
+{
+ unsigned long i = 0;
+ bool buf_present = false;
+ long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
+ OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
+
+ if (!dynamic_buf_mode || !out_dynamic_list) {
+ return;
+ }
+
+ pthread_mutex_lock(&m_lock);
+ for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
+ //check the buffer fd, offset, uv addr with list contents
+ //If present increment reference.
+ if ((out_dynamic_list[i].fd == fd) &&
+ (out_dynamic_list[i].offset == offset)) {
+ DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u",
+ (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
+ if (!secure_mode) {
+ drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr;
+ }
+ buf_present = true;
+ break;
+ }
+ }
+ if (!buf_present) {
+ for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
+ //search for a entry to insert details of the new buffer
+ if (out_dynamic_list[i].dup_fd < 0) {
+ out_dynamic_list[i].fd = fd;
+ out_dynamic_list[i].offset = offset;
+ out_dynamic_list[i].dup_fd = dup(fd);
+ out_dynamic_list[i].ref_count++;
+ DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u",
+ (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
+
+ if (!secure_mode) {
+ drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
+ (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len,
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
+ //mmap returns (void *)-1 on failure and sets error code in errno.
+ if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) {
+ DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno);
+ drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL;
+ break;
+ }
+ out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr;
+ out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len;
+ DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
+ }
+ break;
+ }
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+}
+
+void omx_vdec::buf_ref_remove()
+{
+ unsigned long i = 0;
+
+ if (!dynamic_buf_mode || !out_dynamic_list) {
+ return;
+ }
+
+ pthread_mutex_lock(&m_lock);
+ for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
+ if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) {
+ DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
+ munmap(out_dynamic_list[i].buffaddr,
+ out_dynamic_list[i].mapped_size);
+ }
+
+ DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u",
+ (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
+ close(out_dynamic_list[i].dup_fd);
+ out_dynamic_list[i].dup_fd = -1;
+ }
+ pthread_mutex_unlock(&m_lock);
+
+ if (out_dynamic_list) {
+ free(out_dynamic_list);
+ out_dynamic_list = NULL;
+ }
+}
+
+#ifdef _MSM8974_
+void omx_vdec::send_codec_config() {
+ if (codec_config_flag) {
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ pthread_mutex_lock(&m_lock);
+ DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
+ while (m_etb_q.m_size) {
+ m_etb_q.pop_entry(&p1,&p2,&ident);
+ if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
+ if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
+ omx_report_error();
+ }
+ } else {
+ 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) {
+ if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+ if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
+ omx_report_error ();
+ }
+ } else {
+ 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);
+ }
+ }
+ pthread_mutex_unlock(&m_lock);
+ }
+}
+#endif
+
+omx_vdec::perf_control::perf_control()
+{
+ m_perf_lib = NULL;
+ m_perf_handle = 0;
+ m_perf_lock_acquire = NULL;
+ m_perf_lock_release = NULL;
+}
+
+omx_vdec::perf_control::~perf_control()
+{
+ if (m_perf_handle != 0 && m_perf_lock_release) {
+ DEBUG_PRINT_LOW("NOTE2: release perf lock");
+ m_perf_lock_release(m_perf_handle);
+ }
+ if (m_perf_lib) {
+ dlclose(m_perf_lib);
+ }
+}
+
+struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0};
+
+omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock;
+
+void omx_vdec::perf_control::send_hint_to_mpctl(bool state)
+{
+ if (load_lib() == false) {
+ return;
+ }
+ m_perf_lock.lock();
+ /* 0x4401 maps to video decode playback hint
+ * in perflock, enum number is 44 and state
+ * being sent on perflock acquire is 01 (true)
+ */
+ int arg = 0x4401;
+
+ if (state == true) {
+ mpctl_obj.vid_inst_count++;
+ } else if (state == false) {
+ mpctl_obj.vid_inst_count--;
+ }
+
+ if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) {
+ mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int));
+ mpctl_obj.vid_acquired = true;
+ DEBUG_PRINT_INFO("Video slvp perflock acquired");
+ } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) {
+ m_perf_lock_release(mpctl_obj.vid_disp_handle);
+ mpctl_obj.vid_acquired = false;
+ DEBUG_PRINT_INFO("Video slvp perflock released");
+ }
+ m_perf_lock.unlock();
+}
+
+void omx_vdec::perf_control::request_cores(int frame_duration_us)
+{
+ if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) {
+ return;
+ }
+ bool retVal = load_lib();
+ if (retVal && m_perf_lock_acquire && m_perf_handle == 0) {
+ int arg = 0x700 /*base value*/ + 2 /*cores*/;
+ m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int));
+ if (m_perf_handle) {
+ DEBUG_PRINT_HIGH("perf lock acquired");
+ }
+ }
+}
+
+bool omx_vdec::perf_control::load_lib()
+{
+ char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
+ if (m_perf_lib)
+ return true;
+
+ if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
+ DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
+ goto handle_err;
+ }
+
+ if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
+ DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
+ goto handle_err;
+ } else {
+ m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
+ if (m_perf_lock_acquire == NULL) {
+ DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
+ goto handle_err;
+ }
+ m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
+ if (m_perf_lock_release == NULL) {
+ DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
+ goto handle_err;
+ }
+ }
+ return true;
+
+handle_err:
+ if (m_perf_lib) {
+ dlclose(m_perf_lib);
+ }
+ m_perf_lib = NULL;
+ return false;
+}
+
+OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
+ unsigned long nMaxFrameHeight)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ int ret = 0;
+ unsigned long min_res_buf_count = 0;
+
+ eRet = enable_smoothstreaming();
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
+ return eRet;
+ }
+
+ DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
+ nMaxFrameWidth,
+ nMaxFrameHeight);
+ m_smoothstreaming_mode = true;
+ m_smoothstreaming_width = nMaxFrameWidth;
+ m_smoothstreaming_height = nMaxFrameHeight;
+
+ //Get upper limit buffer count for min supported resolution
+ struct v4l2_format fmt;
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
+ fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
+ fmt.fmt.pix_mp.pixelformat = output_capability;
+
+ ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
+ m_decoder_capability.min_height,
+ m_decoder_capability.min_width);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("failed to get_buffer_req");
+ return eRet;
+ }
+
+ min_res_buf_count = drv_ctx.op_buf.mincount;
+ DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
+ min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
+
+ update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
+ m_smoothstreaming_width, m_smoothstreaming_height);
+ eRet = is_video_session_supported();
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("video session is not supported");
+ return eRet;
+ }
+
+ //Get upper limit buffer size for max smooth streaming resolution set
+ 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) {
+ DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
+ return eRet;
+ }
+ DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
+ (unsigned int)drv_ctx.op_buf.buffer_size);
+
+ drv_ctx.op_buf.mincount = min_res_buf_count;
+ drv_ctx.op_buf.actualcount = min_res_buf_count;
+ drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
+ eRet = set_buffer_req(&drv_ctx.op_buf);
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("failed to set_buffer_req");
+ return eRet;
+ }
+
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+ if (eRet != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
+ return eRet;
+ }
+ DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
+ drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
+ return eRet;
+}
+
+//static
+OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
+
+#ifndef FLEXYUV_SUPPORTED
+ return OMX_ErrorUndefined;
+#else
+
+ if (pParam == NULL) {
+ DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
+ return OMX_ErrorBadParameter;
+ }
+
+ DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
+
+ MediaImage *img = &(params->sMediaImage);
+ switch(params->eColorFormat) {
+ case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
+ {
+ img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
+ img->mNumPlanes = 3;
+ // mWidth and mHeight represent the W x H of the largest plane
+ // In our case, this happens to be the Stride x Scanlines of Y plane
+ img->mWidth = params->nFrameWidth;
+ img->mHeight = params->nFrameHeight;
+ size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
+ size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
+ img->mBitDepth = 8;
+ //Plane 0 (Y)
+ img->mPlane[MediaImage::Y].mOffset = 0;
+ img->mPlane[MediaImage::Y].mColInc = 1;
+ img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
+ img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
+ img->mPlane[MediaImage::Y].mVertSubsampling = 1;
+ //Plane 1 (U)
+ img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
+ img->mPlane[MediaImage::U].mColInc = 2; //interleaved UV
+ img->mPlane[MediaImage::U].mRowInc =
+ VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
+ img->mPlane[MediaImage::U].mHorizSubsampling = 2;
+ img->mPlane[MediaImage::U].mVertSubsampling = 2;
+ //Plane 2 (V)
+ img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
+ img->mPlane[MediaImage::V].mColInc = 2; //interleaved UV
+ img->mPlane[MediaImage::V].mRowInc =
+ VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
+ img->mPlane[MediaImage::V].mHorizSubsampling = 2;
+ img->mPlane[MediaImage::V].mVertSubsampling = 2;
+ break;
+ }
+
+ case OMX_COLOR_FormatYUV420Planar:
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ // We need not describe the standard OMX linear formats as these are
+ // understood by client. Fail this deliberately to let client fill-in
+ return OMX_ErrorUnsupportedSetting;
+
+ default:
+ // Rest all formats which are non-linear cannot be described
+ DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
+ img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
+ return OMX_ErrorNone;
+ };
+
+ DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
+ DEBUG_PRINT_LOW(" FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
+ DEBUG_PRINT_LOW(" YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
+ for (size_t i = 0; i < img->mNumPlanes; ++i) {
+ DEBUG_PRINT_LOW(" Plane[%zu] : offset=%d / xStep=%d / yStep = %d",
+ i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
+ }
+ return OMX_ErrorNone;
+#endif //FLEXYUV_SUPPORTED
+}
+
+void omx_vdec::prefetchNewBuffers() {
+
+ struct v4l2_decoder_cmd dec;
+ uint32_t prefetch_count;
+ uint32_t prefetch_size;
+ uint32_t want_size;
+ uint32_t have_size;
+ int color_fmt, rc;
+ uint32_t new_calculated_size;
+ uint32_t new_buffer_size;
+ uint32_t new_buffer_count;
+ uint32_t old_buffer_size;
+ uint32_t old_buffer_count;
+
+ memset((void *)&dec, 0 , sizeof(dec));
+ DEBUG_PRINT_LOW("Old size : %zu, count : %d, width : %u, height : %u\n",
+ drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount,
+ drv_ctx.video_resolution.frame_width,
+ drv_ctx.video_resolution.frame_height);
+ dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT;
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
+ DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno);
+ } else {
+ DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n",
+ dec.raw.data[0], dec.raw.data[1]);
+ }
+
+ switch ((int)drv_ctx.output_format) {
+ case VDEC_YUV_FORMAT_NV12:
+ color_fmt = COLOR_FMT_NV12;
+ break;
+ case VDEC_YUV_FORMAT_NV12_UBWC:
+ color_fmt = COLOR_FMT_NV12_UBWC;
+ break;
+ default:
+ color_fmt = -1;
+ DEBUG_PRINT_HIGH("Color format : %x not supported for secure memory prefetching\n", drv_ctx.output_format);
+ return;
+ }
+
+ new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height);
+ DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n",
+ m_reconfig_width, m_reconfig_height, new_calculated_size);
+ new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size;
+ new_buffer_count = dec.raw.data[1];
+ old_buffer_size = drv_ctx.op_buf.buffer_size;
+ old_buffer_count = drv_ctx.op_buf.actualcount;
+
+ new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count;
+
+ prefetch_count = new_buffer_count;
+ prefetch_size = new_buffer_size - old_buffer_size;
+ want_size = new_buffer_size * new_buffer_count;
+ have_size = old_buffer_size * old_buffer_count;
+
+ if (want_size > have_size) {
+ DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size);
+ DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size);
+
+ int ion_fd = open(MEM_DEVICE, O_RDONLY);
+ if (ion_fd < 0) {
+ DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd);
+ return;
+ }
+
+ struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data));
+ struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data));
+ struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions));
+ size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count);
+
+ if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) {
+ DEBUG_PRINT_ERROR("prefetch data allocation failed");
+ goto prefetch_exit;
+ }
+
+ for (uint32_t i = 0; i < prefetch_count; i++) {
+ sizes[i] = prefetch_size;
+ }
+
+ regions[0].nr_sizes = prefetch_count;
+ regions[0].sizes = sizes;
+ regions[0].vmid = ION_FLAG_CP_PIXEL;
+
+ prefetch_data->nr_regions = 1;
+ prefetch_data->regions = regions;
+ prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
+
+ custom_data->cmd = ION_IOC_PREFETCH;
+ custom_data->arg = (unsigned long )prefetch_data;
+
+ rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno);
+ }
+
+prefetch_exit:
+ close(ion_fd);
+ free(sizes);
+ free(regions);
+ free(prefetch_data);
+ free(custom_data);
+ }
+}
+
diff --git a/msmcobalt/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp b/msmcobalt/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp
new file mode 100644
index 0000000..809a1f7
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp
@@ -0,0 +1,325 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2015, 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"
+#include "vidc_debug.h"
+
+#define DEBUG DEBUG_PRINT_ERROR
+
+void omx_time_stamp_reorder::set_timestamp_reorder_mode(bool mode)
+{
+ auto_lock l(&m_lock);
+ reorder_ts = mode;
+}
+
+void omx_time_stamp_reorder::enable_debug_print(bool flag)
+{
+ auto_lock l(&m_lock);
+ print_debug = flag;
+}
+
+omx_time_stamp_reorder::~omx_time_stamp_reorder()
+{
+ delete_list();
+ pthread_mutex_destroy(&m_lock);
+}
+
+omx_time_stamp_reorder::omx_time_stamp_reorder()
+{
+ reorder_ts = false;
+ phead = pcurrent = NULL;
+ error = false;
+ print_debug = false;
+ pthread_mutex_init(&m_lock, NULL);
+}
+
+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)
+{
+ auto_lock l(&m_lock);
+ OMX_TICKS *table_entry = NULL;
+
+ if (!reorder_ts || error || !header) {
+ if (error || !header)
+ DEBUG("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("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("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("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)
+{
+ auto_lock l(&m_lock);
+ unsigned int num_ent_remove = (is_interlaced)?2:1;
+
+ if (!reorder_ts || error) {
+ DEBUG("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()
+{
+ auto_lock l(&m_lock);
+ delete_list();
+}
+
+bool omx_time_stamp_reorder::get_next_timestamp(OMX_BUFFERHEADERTYPE *header, bool is_interlaced)
+{
+ auto_lock l(&m_lock);
+ timestamp *element = NULL,*duplicate = NULL;
+ bool status = false;
+
+ if (!reorder_ts || error || !header) {
+ if (error || !header)
+ DEBUG("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/msmcobalt/mm-video-v4l2/vidc/venc/Android.mk b/msmcobalt/mm-video-v4l2/vidc/venc/Android.mk
new file mode 100644
index 0000000..06306f8
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/Android.mk
@@ -0,0 +1,156 @@
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+# ---------------------------------------------------------------------------------
+# 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 += -UENABLE_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
+libmm-venc-def += -Werror
+libmm-venc-def += -D_ANDROID_ICS_
+libmm-venc-def += -D_MSM8974_
+
+TARGETS_THAT_USE_FLAG_MSM8226 := msm8226 msm8916 msm8909
+TARGETS_THAT_NEED_SW_VENC_MPEG4 := msm8909 msm8937
+TARGETS_THAT_NEED_SW_VENC_HEVC := msm8992
+TARGETS_THAT_SUPPORT_UBWC := msm8996 msmcobalt
+TARGETS_THAT_SUPPORT_VQZIP := msm8996 msmcobalt
+TARGETS_THAT_SUPPORT_PQ := msm8996 msmcobalt
+
+ifeq ($(TARGET_BOARD_PLATFORM),msm8610)
+libmm-venc-def += -DMAX_RES_720P
+libmm-venc-def += -D_MSM8610_
+else
+ifeq ($(TARGET_BOARD_PLATFORM),msm8226)
+libmm-venc-def += -DMAX_RES_1080P
+else
+libmm-venc-def += -DMAX_RES_1080P
+libmm-venc-def += -DMAX_RES_1080P_EBI
+endif
+endif
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_SUPPORT_UBWC)),true)
+libmm-venc-def += -D_UBWC_
+endif
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_SUPPORT_VQZIP)),true)
+libmm-venc-def += -D_VQZIP_
+endif
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_SUPPORT_PQ)),true)
+libmm-venc-def += -D_PQ_
+endif
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_USE_FLAG_MSM8226)),true)
+libmm-venc-def += -D_MSM8226_
+endif
+
+ifeq ($(TARGET_USES_ION),true)
+libmm-venc-def += -DUSE_ION
+endif
+
+ifeq ($(TARGET_USES_MEDIA_EXTENSIONS),true)
+libmm-venc-def += -DUSE_NATIVE_HANDLE_SOURCE
+endif
+
+ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)),true)
+libmm-venc-def += -DMASTER_SIDE_CP
+endif
+
+ifeq ($(TARGET_USES_MEDIA_EXTENSIONS),true)
+libmm-venc-def += -DSUPPORT_CONFIG_INTRA_REFRESH
+endif
+
+# Common Includes
+libmm-venc-inc := $(LOCAL_PATH)/inc
+libmm-venc-inc += $(QCOM_MEDIA_ROOT)/mm-video-v4l2/vidc/common/inc
+libmm-venc-inc += $(QCOM_MEDIA_ROOT)/mm-core/inc
+libmm-venc-inc += $(QCOM_MEDIA_ROOT)/libstagefrighthw
+libmm-venc-inc += $(TARGET_OUT_HEADERS)/qcom/display
+libmm-venc-inc += $(TARGET_OUT_HEADERS)/adreno
+libmm-venc-inc += frameworks/native/include/media/hardware
+libmm-venc-inc += frameworks/native/include/media/openmax
+libmm-venc-inc += $(QCOM_MEDIA_ROOT)/libc2dcolorconvert
+libmm-venc-inc += $(TARGET_OUT_HEADERS)/libvqzip
+libmm-venc-inc += $(TARGET_OUT_HEADERS)/libgpustats
+libmm-venc-inc += frameworks/av/include/media/stagefright
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+libmm-venc-inc += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+
+# Common Dependencies
+libmm-venc-add-dep := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
+
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxVenc)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libOmxVenc
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libmm-venc-def)
+LOCAL_C_INCLUDES := $(libmm-venc-inc)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-venc-add-dep)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils \
+ libdl libgui
+ifeq ($(BOARD_USES_ADRENO), true)
+LOCAL_SHARED_LIBRARIES += libc2dcolorconvert
+endif # ($(BOARD_USES_ADRENO), true)
+LOCAL_SHARED_LIBRARIES += libqdMetaData
+LOCAL_STATIC_LIBRARIES := libOmxVidcCommon
+
+LOCAL_SRC_FILES := src/omx_video_base.cpp
+LOCAL_SRC_FILES += src/omx_video_encoder.cpp
+LOCAL_SRC_FILES += src/video_encoder_device_v4l2.cpp
+
+include $(BUILD_SHARED_LIBRARY)
+
+ifeq ($(call is-board-platform-in-list, $(TARGETS_THAT_NEED_SW_VENC_MPEG4)),true)
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxSwVencMpeg4)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+libmm-venc-inc += $(TARGET_OUT_HEADERS)/mm-video/swvenc
+
+LOCAL_MODULE := libOmxSwVencMpeg4
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libmm-venc-def)
+LOCAL_C_INCLUDES := $(libmm-venc-inc)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(libmm-venc-add-dep)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils \
+ libdl libgui
+LOCAL_SHARED_LIBRARIES += libMpeg4SwEncoder
+ifeq ($(BOARD_USES_ADRENO), true)
+LOCAL_SHARED_LIBRARIES += libc2dcolorconvert
+endif # ($(BOARD_USES_ADRENO), true)
+LOCAL_STATIC_LIBRARIES := libOmxVidcCommon
+
+LOCAL_SRC_FILES := src/omx_video_base.cpp
+LOCAL_SRC_FILES += src/omx_swvenc_mpeg4.cpp
+
+include $(BUILD_SHARED_LIBRARY)
+endif
+
+
+# ---------------------------------------------------------------------------------
+# END
+# ---------------------------------------------------------------------------------
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/inc/camera_test.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/camera_test.h
new file mode 100644
index 0000000..84c5e5f
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/camera_test.h
@@ -0,0 +1,58 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, 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 _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/msmcobalt/mm-video-v4l2/vidc/venc/inc/fb_test.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/fb_test.h
new file mode 100644
index 0000000..173150c
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/fb_test.h
@@ -0,0 +1,48 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, 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 _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/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_hevc.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_hevc.h
new file mode 100644
index 0000000..4ec9906
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_hevc.h
@@ -0,0 +1,113 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 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_SWVENC__H
+#define __OMX_SWVENC__H
+
+#include <unistd.h>
+#include "omx_video_base.h"
+#include "SwVencTypes.h"
+#include "SwVencAPI.h"
+
+extern "C" {
+ OMX_API void * get_omx_component_factory_fn(void);
+}
+
+class omx_swvenc: public omx_video
+{
+public:
+ omx_swvenc(); //constructor
+ ~omx_swvenc(); //des
+
+ 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);
+ bool is_secure_session();
+
+ static SWVENC_STATUS swvenc_input_buffer_done_cb(SWVENC_HANDLE pSwEnc, SWVENC_IPBUFFER *pIpBuffer, void *pClientHandle);
+ static SWVENC_STATUS swvenc_fill_buffer_done_cb(SWVENC_HANDLE pSwEnc, SWVENC_OPBUFFER *pOpBuffer, void *pClientHandle);
+ static SWVENC_STATUS swvenc_handle_event_cb (SWVENC_HANDLE pSwEnc, SWVENC_EVENTHANDLER* pEventHandler, void *pClientHandle);
+ void swvenc_input_buffer_done(SWVENC_IPBUFFER *pIpBuffer);
+ void swvenc_fill_buffer_done(SWVENC_OPBUFFER *pOpBuffer);
+ void swvenc_handle_event(SWVENC_EVENTHANDLER *pEvent);
+ bool update_profile_level();
+
+ //OMX strucutres
+ OMX_U32 m_nVenc_format;
+
+private:
+ virtual OMX_U32 dev_stop(void);
+ virtual OMX_U32 dev_pause(void);
+ virtual OMX_U32 dev_start(void);
+ virtual OMX_U32 dev_flush(unsigned);
+ virtual OMX_U32 dev_resume(void);
+ virtual OMX_U32 dev_start_done(void);
+ virtual OMX_U32 dev_set_message_thread_id(pthread_t);
+ virtual bool dev_use_buf(void *,unsigned,unsigned);
+ virtual bool dev_free_buf(void *,unsigned);
+ virtual bool dev_empty_buf(void *, void *,unsigned,unsigned);
+ virtual bool dev_fill_buf(void *buffer, void *,unsigned,unsigned);
+ virtual 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);
+ virtual bool dev_get_seq_hdr(void *, unsigned, unsigned *);
+ virtual bool dev_loaded_start(void);
+ virtual bool dev_loaded_stop(void);
+ virtual bool dev_loaded_start_done(void);
+ virtual bool dev_loaded_stop_done(void);
+#ifdef _MSM8974_
+ virtual int dev_handle_extradata(void*, int);
+ virtual int dev_set_format(int);
+#endif
+ virtual bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height);
+ virtual bool dev_get_capability_ltrcount(OMX_U32 *, OMX_U32 *, OMX_U32 *);
+ virtual bool dev_get_performance_level(OMX_U32 *);
+ virtual bool dev_get_vui_timing_info(OMX_U32 *);
+ virtual bool dev_get_peak_bitrate(OMX_U32 *);
+ virtual bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/) {
+ return false;
+ }
+ virtual bool dev_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
+ OMX_U32 height);
+ virtual bool dev_get_output_log_flag();
+ virtual int dev_output_log_buffers(const char *buffer_addr, int buffer_len);
+ virtual int dev_extradata_log_buffers(char *buffer_addr);
+
+ SWVENC_HANDLE m_pSwVenc;
+ SWVENC_CALLBACK m_callBackInfo;
+ SWVENC_IPBUFFER m_pSwVencIpBuffer[32];
+ SWVENC_OPBUFFER m_pSwVencOpBuffer[32];
+};
+
+#endif //__OMX_SWVENC__H
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h
new file mode 100644
index 0000000..0443c80
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h
@@ -0,0 +1,165 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, 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 <unistd.h>
+#include "omx_video_base.h"
+#ifdef _MSM8974_
+#include "video_encoder_device_v4l2.h"
+#else
+#include "video_encoder_device.h"
+#endif
+
+#include "swvenc_api.h"
+#include "swvenc_types.h"
+
+extern "C" {
+ OMX_API void * get_omx_component_factory_fn(void);
+}
+
+struct swvenc_video_capability {
+ unsigned int min_width;
+ unsigned int max_width;
+ unsigned int min_height;
+ unsigned int max_height;
+};
+
+
+class omx_venc: public omx_video
+{
+ public:
+ omx_venc();
+ ~omx_venc();
+ 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);
+ bool is_secure_session();
+ //OMX strucutres
+ OMX_U32 m_nVenc_format;
+
+ SWVENC_HANDLE m_hSwVenc;
+ SWVENC_CODEC m_codec;
+ swvenc_video_capability m_capability;
+ bool m_max_allowed_bitrate_check;
+ bool m_stopped;
+ bool format_set;
+
+ int dev_handle_output_extradata(void *, int);
+ int dev_handle_input_extradata(void *, int, int);
+ bool dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer);
+ void dev_set_extradata_cookie(void *);
+ int dev_set_format(int);
+
+ static SWVENC_STATUS swvenc_empty_buffer_done_cb
+ (
+ SWVENC_HANDLE swvenc,
+ SWVENC_IPBUFFER *p_ipbuffer,
+ void *p_client
+ );
+ SWVENC_STATUS swvenc_empty_buffer_done
+ (
+ SWVENC_IPBUFFER *p_ipbuffer
+ );
+ static SWVENC_STATUS swvenc_fill_buffer_done_cb
+ (
+ SWVENC_HANDLE swvenc,
+ SWVENC_OPBUFFER *p_opbuffer,
+ void *p_client
+ );
+ static SWVENC_STATUS swvenc_handle_event_cb
+ (
+ SWVENC_HANDLE swvenc,
+ SWVENC_EVENT event,
+ void *p_client
+ );
+
+ private:
+ venc_debug_cap m_debug;
+ bool m_bSeqHdrRequested;
+
+ 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 const *,OMX_U32 const *,OMX_U32 const *,OMX_U32);
+ 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_get_performance_level(OMX_U32 *);
+ bool dev_get_vui_timing_info(OMX_U32 *);
+ bool dev_get_vqzip_sei_info(OMX_U32 *);
+ bool dev_get_peak_bitrate(OMX_U32 *);
+ bool dev_get_batch_size(OMX_U32 *);
+ bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/) {
+ return false;
+ }
+ bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height);
+ bool dev_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
+ OMX_U32 height);
+ bool dev_get_output_log_flag();
+ int dev_output_log_buffers(const char *buffer_addr, int buffer_len);
+ int dev_extradata_log_buffers(char *buffer);
+
+ SWVENC_STATUS swvenc_set_rc_mode(OMX_VIDEO_CONTROLRATETYPE eControlRate);
+ SWVENC_STATUS swvenc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel);
+ SWVENC_STATUS swvenc_set_intra_refresh(OMX_VIDEO_PARAM_INTRAREFRESHTYPE *IntraRefresh);
+ SWVENC_STATUS swvenc_set_frame_rate(OMX_U32 nFrameRate);
+ SWVENC_STATUS swvenc_set_bit_rate(OMX_U32 nTargetBitrate);
+ SWVENC_STATUS swvenc_set_intra_period(OMX_U32 nPFrame,OMX_U32 nBFrame);
+ SWVENC_STATUS swvenc_get_buffer_req
+ (
+ OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 *buff_alignment,
+ OMX_U32 port
+ );
+ int swvenc_input_log_buffers(const char *buffer, int bufferlen);
+
+};
+
+#endif //__OMX_VENC__H
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
new file mode 100644
index 0000000..b2e21af
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -0,0 +1,712 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2016, 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"
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#ifdef _ANDROID_
+#include <binder/MemoryHeapBase.h>
+#ifdef _ANDROID_ICS_
+#include "QComOMXMetadata.h"
+#endif
+#endif // _ANDROID_
+#include <pthread.h>
+#include <semaphore.h>
+#include <linux/msm_vidc_enc.h>
+#include <media/hardware/HardwareAPI.h>
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "OMX_Skype_VideoExtensions.h"
+#include "OMX_VideoExt.h"
+#include "OMX_IndexExt.h"
+#include "qc_omx_component.h"
+#include "omx_video_common.h"
+#include "extra_data_handler.h"
+#include <linux/videodev2.h>
+#include <dlfcn.h>
+#include "C2DColorConverter.h"
+#include "vidc_debug.h"
+
+#ifdef _ANDROID_
+using namespace android;
+// local pmem heap object
+class VideoHeap : public MemoryHeapBase
+{
+ public:
+ VideoHeap(int fd, size_t size, void* base);
+ virtual ~VideoHeap() {}
+};
+
+#include <utils/Log.h>
+
+#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
+#define OMX_INIT_STRUCT(_s_, _name_) \
+ memset((_s_), 0x0, sizeof(_name_)); \
+(_s_)->nSize = sizeof(_name_); \
+(_s_)->nVersion.nVersion = OMX_SPEC_VERSION
+
+//////////////////////////////////////////////////////////////////////////////
+// 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_INDEX 64
+#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_INDEX - 1)/BITS_PER_INDEX)
+#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_INDEX)
+#define BITMASK_FLAG(mIndex) ((uint64_t)1 << ((mIndex) % BITS_PER_INDEX))
+#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 MAX_NUM_INPUT_BUFFERS 64
+#define MAX_NUM_OUTPUT_BUFFERS 64
+
+#ifdef USE_NATIVE_HANDLE_SOURCE
+#define LEGACY_CAM_SOURCE kMetadataBufferTypeNativeHandleSource
+#define LEGACY_CAM_METADATA_TYPE encoder_nativehandle_buffer_type
+#else
+#define LEGACY_CAM_SOURCE kMetadataBufferTypeCameraSource
+#define LEGACY_CAM_METADATA_TYPE encoder_media_buffer_type
+#endif
+
+void* message_thread_enc(void *);
+
+enum omx_venc_extradata_types {
+ VENC_EXTRADATA_SLICEINFO = 0x100,
+ VENC_EXTRADATA_MBINFO = 0x400,
+ VENC_EXTRADATA_FRAMEDIMENSION = 0x1000000,
+ VENC_EXTRADATA_YUV_STATS = 0x800,
+ VENC_EXTRADATA_VQZIP = 0x02000000,
+ VENC_EXTRADATA_ROI = 0x04000000,
+};
+
+struct output_metabuffer {
+ OMX_U32 type;
+ native_handle_t *nh;
+};
+
+// OMX video class
+class omx_video: public qc_omx_component
+{
+ protected:
+#ifdef _ANDROID_ICS_
+ bool meta_mode_enable;
+ bool c2d_opened;
+ LEGACY_CAM_METADATA_TYPE meta_buffers[MAX_NUM_INPUT_BUFFERS];
+ OMX_BUFFERHEADERTYPE *opaque_buffer_hdr[MAX_NUM_INPUT_BUFFERS];
+ bool get_syntaxhdr_enable;
+ OMX_BUFFERHEADERTYPE *psource_frame;
+ OMX_BUFFERHEADERTYPE *pdest_frame;
+ bool secure_session;
+ bool hier_b_enabled;
+ //intermediate conversion buffer queued to encoder in case of invalid EOS input
+ OMX_BUFFERHEADERTYPE *mEmptyEosBuffer;
+
+ 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, unsigned int flags);
+ 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:
+
+ bool mUseProxyColorFormat;
+ //RGB or non-native input, and we have pre-allocated conversion buffers
+ bool mUsesColorConversion;
+
+ 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;
+ virtual bool is_secure_session(void) = 0;
+ virtual int dev_handle_output_extradata(void*, int) = 0;
+ virtual int dev_set_format(int) = 0;
+ 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;
+ virtual bool dev_get_performance_level(OMX_U32 *) = 0;
+ virtual bool dev_get_vui_timing_info(OMX_U32 *) = 0;
+ virtual bool dev_get_vqzip_sei_info(OMX_U32 *) = 0;
+ virtual bool dev_get_peak_bitrate(OMX_U32 *) = 0;
+ virtual bool dev_get_batch_size(OMX_U32 *) = 0;
+ virtual bool dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer) = 0;
+ virtual bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/) = 0;
+#ifdef _ANDROID_ICS_
+ void omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer);
+#endif
+ virtual bool dev_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
+ OMX_U32 height) = 0;
+ virtual bool dev_get_output_log_flag() = 0;
+ virtual int dev_output_log_buffers(const char *buffer_addr, int buffer_len) = 0;
+ virtual int dev_extradata_log_buffers(char *buffer_addr) = 0;
+ 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;
+ volatile bool msg_thread_stop;
+
+ 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,
+ OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING = 0x14,
+ OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD = 0x15,
+ OMX_COMPONENT_CLOSE_MSG = 0x16
+ };
+
+ struct omx_event {
+ unsigned long param1;
+ unsigned long param2;
+ unsigned long id;
+ };
+
+ struct omx_cmd_queue {
+ omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE];
+ unsigned long m_read;
+ unsigned long m_write;
+ unsigned long m_size;
+
+ omx_cmd_queue();
+ ~omx_cmd_queue();
+ bool insert_entry(unsigned long p1, unsigned long p2, unsigned long id);
+ bool pop_entry(unsigned long *p1,unsigned long *p2, unsigned long *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 long &index);
+ OMX_ERRORTYPE queue_meta_buffer(OMX_HANDLETYPE hComp,
+ struct pmem &Input_pmem_info);
+ OMX_ERRORTYPE push_empty_eos_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+ OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+ bool release_done();
+
+ bool release_output_done();
+ bool release_input_done();
+
+ OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param1,
+ OMX_PTR cmdData);
+ bool post_event( unsigned long p1,
+ unsigned long p2,
+ unsigned long 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_state != OMX_StateLoaded) {
+ m_error_propogated = true;
+ DEBUG_PRINT_ERROR("ERROR: send OMX_ErrorHardware to Client");
+ m_pCallbacks.EventHandler(&m_cmp,m_app_data,
+ OMX_EventError,OMX_ErrorHardware,0,NULL);
+ }
+ }
+
+ inline void omx_report_hw_overload ()
+ {
+ if (m_pCallbacks.EventHandler && !m_error_propogated && m_state != OMX_StateLoaded) {
+ m_error_propogated = true;
+ DEBUG_PRINT_ERROR("ERROR: send OMX_ErrorInsufficientResources to Client");
+ m_pCallbacks.EventHandler(&m_cmp, m_app_data,
+ OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
+ }
+ }
+
+ inline void omx_report_unsupported_setting () {
+ if (m_pCallbacks.EventHandler && !m_error_propogated && m_state != OMX_StateLoaded) {
+ m_error_propogated = true;
+ m_pCallbacks.EventHandler(&m_cmp,m_app_data,
+ OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL);
+ }
+ }
+
+ void complete_pending_buffer_done_cbs();
+ bool is_conv_needed(int, int);
+ void print_debug_color_aspects(ColorAspects *aspects, const char *prefix);
+
+#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
+
+ //*************************************************************
+ //*******************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_VIDEO_PARAM_VP8TYPE m_sParamVP8;
+ OMX_VIDEO_PARAM_HEVCTYPE m_sParamHEVC;
+ 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_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE m_sSessionIPBQPRange;
+ 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_VIDEO_CONFIG_DEINTERLACE m_sConfigDeinterlace;
+ OMX_VIDEO_VP8REFERENCEFRAMETYPE m_sConfigVp8ReferenceFrame;
+ QOMX_VIDEO_HIERARCHICALLAYERS m_sHierLayers;
+ OMX_QOMX_VIDEO_MBI_STATISTICS m_sMBIStatistics;
+ QOMX_EXTNINDEX_VIDEO_INITIALQP m_sParamInitqp;
+ QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS m_sHPlayers;
+ OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID m_sBaseLayerID;
+ OMX_SKYPE_VIDEO_PARAM_DRIVERVER m_sDriverVer;
+ OMX_SKYPE_VIDEO_CONFIG_QP m_sConfigQP;
+ QOMX_EXTNINDEX_VIDEO_VENC_SAR m_sSar;
+ QOMX_VIDEO_H264ENTROPYCODINGTYPE m_sParamEntropy;
+ PrependSPSPPSToIDRFramesParams m_sPrependSPSPPS;
+ struct timestamp_info {
+ OMX_U64 m_TimeStamp;
+ bool is_buffer_pending;
+ OMX_BUFFERHEADERTYPE *pending_buffer;
+ pthread_mutex_t m_lock;
+ } timestamp;
+ OMX_U32 m_sExtraData;
+ OMX_U32 m_input_msg_id;
+ QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE m_slowLatencyMode;
+#ifdef SUPPORT_CONFIG_INTRA_REFRESH
+ OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE m_sConfigIntraRefresh;
+#endif
+ OMX_QTI_VIDEO_CONFIG_BLURINFO m_blurInfo;
+ DescribeColorAspectsParams m_sConfigColorAspects;
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE m_sParamTemporalLayers;
+ OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE m_sConfigTemporalLayers;
+
+ // 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;
+
+ uint64_t m_out_bm_count;
+ uint64_t m_inp_bm_count;
+ uint64_t m_flags;
+ uint64_t m_etb_count;
+ uint64_t m_fbd_count;
+#ifdef _ANDROID_
+ // Heap pointer to frame buffers
+ sp<MemoryHeapBase> m_heap_ptr;
+#endif //_ANDROID_
+ // to know whether Event Port Settings change has been triggered or not.
+ bool m_event_port_settings_sent;
+ OMX_U8 m_cRole[OMX_MAX_STRINGNAME_SIZE];
+ extra_data_handler extra_data_handle;
+ bool hw_overload;
+ size_t m_graphicbuffer_size;
+ char m_platform[OMX_MAX_STRINGNAME_SIZE];
+};
+
+#endif // __OMX_VIDEO_BASE_H__
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_common.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_common.h
new file mode 100644
index 0000000..699e1b9
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_common.h
@@ -0,0 +1,112 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2016, 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<stdlib.h>
+#include <stdio.h>
+#ifdef USE_ION
+#include <linux/msm_ion.h>
+#endif
+
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#else
+#define PROPERTY_VALUE_MAX 92
+#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
+#define OMX_CORE_FWVGA_HEIGHT 480
+#define OMX_CORE_FWVGA_WIDTH 864
+#define OMX_CORE_720P_WIDTH 1280
+#define OMX_CORE_720P_HEIGHT 720
+#define OMX_CORE_1080P_WIDTH 1920
+#define OMX_CORE_1080P_HEIGHT 1080
+#define OMX_CORE_4KUHD_WIDTH 3840
+#define OMX_CORE_4KUHD_HEIGHT 2160
+#define OMX_CORE_4KDCI_WIDTH 4096
+#define OMX_CORE_4KDCI_HEIGHT 2160
+
+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;
+};
+
+struct venc_debug_cap {
+ bool in_buffer_log;
+ bool out_buffer_log;
+ bool extradata_log;
+ char infile_name[PROPERTY_VALUE_MAX];
+ char outfile_name[PROPERTY_VALUE_MAX];
+ char extradatafile_name[PROPERTY_VALUE_MAX];
+ char log_loc[PROPERTY_VALUE_MAX];
+ FILE *infile;
+ FILE *outfile;
+ FILE *extradatafile;
+};
+#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/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
new file mode 100644
index 0000000..e648799
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
@@ -0,0 +1,123 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2015, 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 <unistd.h>
+#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);
+ bool is_secure_session();
+ //OMX strucutres
+ OMX_U32 m_nVenc_format;
+ class venc_dev *handle;
+ int dev_handle_output_extradata(void *, int);
+ int dev_set_format(int);
+ 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_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer);
+ 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_get_performance_level(OMX_U32 *);
+ bool dev_get_vui_timing_info(OMX_U32 *);
+ bool dev_get_vqzip_sei_info(OMX_U32 *);
+ bool dev_get_peak_bitrate(OMX_U32 *);
+ bool dev_get_batch_size(OMX_U32 *);
+ bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/);
+ bool dev_is_video_session_supported(OMX_U32 width, OMX_U32 height);
+ bool dev_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
+ OMX_U32 height);
+ bool dev_get_output_log_flag();
+ int dev_output_log_buffers(const char *buffer_addr, int buffer_len);
+ int dev_extradata_log_buffers(char *buffer);
+ class perf_control {
+ typedef int (*perf_lock_acquire_t)(int, int, int*, int);
+ typedef int (*perf_lock_release_t)(int);
+ public:
+ perf_control();
+ ~perf_control();
+ void send_hint_to_mpctl(bool state);
+ private:
+ int m_perf_handle;
+ void *m_perf_lib;
+ bool load_lib();
+ perf_lock_acquire_t m_perf_lock_acquire;
+ perf_lock_release_t m_perf_lock_release;
+ };
+ perf_control m_perf_control;
+};
+
+#ifdef _UBWC_
+ #define QOMX_DEFAULT_COLOR_FMT QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed
+ #define V4L2_DEFAULT_OUTPUT_COLOR_FMT V4L2_PIX_FMT_NV12_UBWC
+#else
+ #define QOMX_DEFAULT_COLOR_FMT QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m
+ #define V4L2_DEFAULT_OUTPUT_COLOR_FMT V4L2_PIX_FMT_NV12
+#endif
+#endif //__OMX_VENC__H
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/inc/queue.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/queue.h
new file mode 100644
index 0000000..0b653da
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/queue.h
@@ -0,0 +1,78 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, 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 QUEUE_H
+#define QUEUE_H
+
+#include<pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <string.h>
+
+/* Message Queue structure */
+struct video_msgq {
+ /* Command to be executed */
+ unsigned int cmd;
+
+ unsigned int status;
+
+ /* Client-specific data */
+ void *clientdata;
+};
+
+
+/* Thread & Message Queue information */
+struct video_queue_context {
+ /* Message Queue related members */
+ pthread_mutex_t mutex;
+ sem_t sem_message;
+ int commandq_size;
+ int dataq_size;
+ struct video_msgq *ptr_dataq;
+ struct video_msgq *ptr_cmdq;
+ int write_dataq ;
+ int read_dataq;
+ int write_comq ;
+ int read_comq ;
+
+};
+
+int check_if_queue_empty ( unsigned int queuetocheck,void* queuecontext );
+
+struct video_msgq * queue_get_cmd ( void* queuecontext );
+
+
+
+int queue_post_cmdq ( void *queuecontext,
+ struct video_msgq *post_msg
+ );
+
+int queue_post_dataq ( void *queuecontext,
+ struct video_msgq *post_msg
+ );
+
+#endif /* QUEUE_H */
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/inc/venc_util.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/venc_util.h
new file mode 100644
index 0000000..79602dc
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/venc_util.h
@@ -0,0 +1,53 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, 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 _ 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/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h
new file mode 100644
index 0000000..fde041d
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h
@@ -0,0 +1,177 @@
+/*--------------------------------------------------------------------------
+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 __OMX_VENC_DEV__
+#define __OMX_VENC_DEV__
+
+#include "OMX_Types.h"
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "qc_omx_component.h"
+#include "omx_video_common.h"
+#include <linux/msm_vidc_enc.h>
+#include <pthread.h>
+#include <linux/videodev2.h>
+#include <poll.h>
+#define TIMEOUT 5000
+#define MAX_RECON_BUFFERS 4
+
+void* async_venc_message_thread (void *);
+
+class venc_dev
+{
+ public:
+ venc_dev(class omx_venc *venc_class); //constructor
+ ~venc_dev(); //des
+
+ bool venc_open(OMX_U32);
+ void venc_close();
+ unsigned venc_stop(void);
+ unsigned venc_pause(void);
+ unsigned venc_start(void);
+ unsigned venc_flush(unsigned);
+#ifdef _ANDROID_ICS_
+ bool venc_set_meta_mode(bool);
+#endif
+ unsigned venc_resume(void);
+ unsigned venc_start_done(void);
+ unsigned venc_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_output_log_flag();
+ int venc_output_log_buffers(const char *buffer_addr, int buffer_len);
+ int venc_input_log_buffers(OMX_BUFFERHEADERTYPE *buffer, void* pmem_data_buf, int framelen);
+ int venc_extradata_log_buffers(char *buffer_addr);
+ 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 venc_debug_cap m_debug;
+
+ 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);
+ bool venc_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width, OMX_U32 height);
+#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/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
new file mode 100644
index 0000000..43d2705
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -0,0 +1,663 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2012-2016, 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_VideoExt.h"
+#include "OMX_QCOMExtns.h"
+#include "qc_omx_component.h"
+#ifdef _VQZIP_
+#include "VQZip.h"
+#endif
+
+#ifdef _PQ_
+#include "gpustats.h"
+#endif
+#include "omx_video_common.h"
+#include "omx_video_base.h"
+#include "omx_video_encoder.h"
+#include <linux/videodev2.h>
+#include <media/msm_vidc.h>
+#include <poll.h>
+
+#define TIMEOUT 5*60*1000
+#define BIT(num) (1 << (num))
+#define MAX_HYB_HIERP_LAYERS 6
+#define MAX_AVC_HP_LAYERS (4)
+#define MAX_V4L2_BUFS 64 //VB2_MAX_FRAME
+
+enum hier_type {
+ HIER_NONE = 0x0,
+ HIER_P = 0x1,
+ HIER_B = 0x2,
+ HIER_P_HYBRID = 0x3,
+};
+
+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 pframeqp;
+ unsigned long bframeqp;
+};
+
+struct msm_venc_initqp {
+ unsigned long iframeqp;
+ unsigned long pframeqp;
+ unsigned long bframeqp;
+ unsigned long enableinitqp;
+};
+
+struct msm_venc_qprange {
+ unsigned long maxqp;
+ unsigned long minqp;
+};
+
+struct msm_venc_ipb_qprange {
+ unsigned long max_i_qp;
+ unsigned long min_i_qp;
+ unsigned long max_p_qp;
+ unsigned long min_p_qp;
+ unsigned long max_b_qp;
+ unsigned long min_b_qp;
+};
+
+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;
+};
+
+struct msm_venc_hierlayers {
+ unsigned int numlayers;
+ enum hier_type hier_mode;
+};
+
+struct msm_venc_ltrinfo {
+ unsigned int enabled;
+ unsigned int count;
+};
+
+struct msm_venc_perf_level {
+ unsigned int perflevel;
+};
+
+struct msm_venc_vui_timing_info {
+ unsigned int enabled;
+};
+
+struct msm_venc_vqzip_sei_info {
+ unsigned int enabled;
+};
+
+struct msm_venc_peak_bitrate {
+ unsigned int peakbitrate;
+};
+
+struct msm_venc_vpx_error_resilience {
+ unsigned int enable;
+};
+
+struct msm_venc_priority {
+ OMX_U32 priority;
+};
+
+struct msm_venc_hybrid_hp {
+ unsigned int nSize;
+ unsigned int nKeyFrameInterval;
+ unsigned int nTemporalLayerBitrateRatio[OMX_VIDEO_MAX_HP_LAYERS];
+ unsigned int nMinQuantizer;
+ unsigned int nMaxQuantizer;
+ unsigned int nHpLayers;
+};
+
+struct msm_venc_color_space {
+ OMX_U32 primaries;
+ OMX_U32 range;
+ OMX_U32 matrix_coeffs;
+ OMX_U32 transfer_chars;
+};
+
+struct msm_venc_temporal_layers {
+ enum hier_type hier_mode;
+ OMX_U32 nMaxLayers;
+ OMX_U32 nMaxBLayers;
+ OMX_U32 nPLayers;
+ OMX_U32 nBLayers;
+ OMX_BOOL bIsBitrateRatioValid;
+ // cumulative ratio: eg [25, 50, 75, 100] means [L0=25%, L1=25%, L2=25%, L3=25%]
+ OMX_U32 nTemporalLayerBitrateRatio[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+ // Layerwise ratio: eg [L0=25%, L1=25%, L2=25%, L3=25%]
+ OMX_U32 nTemporalLayerBitrateFraction[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+};
+
+enum v4l2_ports {
+ CAPTURE_PORT,
+ OUTPUT_PORT,
+ MAX_PORT
+};
+
+struct extradata_buffer_info {
+ unsigned long buffer_size;
+ char* uaddr;
+ int count;
+ int size;
+ OMX_BOOL allocated;
+ enum v4l2_ports port_index;
+#ifdef USE_ION
+ struct venc_ion ion;
+ unsigned int m_ion_dev;
+#endif
+ bool vqzip_sei_found;
+};
+
+struct statistics {
+ struct timeval prev_tv;
+ int prev_fbd;
+ int bytes_generated;
+};
+
+enum rc_modes {
+ RC_VBR_VFR = BIT(0),
+ RC_VBR_CFR = BIT(1),
+ RC_CBR_VFR = BIT(2),
+ RC_CBR_CFR = BIT(3),
+ RC_MBR_CFR = BIT(4),
+ RC_MBR_VFR = BIT(5),
+ RC_ALL = (RC_VBR_VFR | RC_VBR_CFR
+ | RC_CBR_VFR | RC_CBR_CFR | RC_MBR_CFR | RC_MBR_VFR)
+};
+
+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(OMX_U32 *,OMX_U32 *,
+ OMX_U32 *,OMX_U32);
+ bool venc_set_buf_req(OMX_U32 *,OMX_U32 *,
+ OMX_U32 *,OMX_U32);
+ bool venc_set_param(void *,OMX_INDEXTYPE);
+ bool venc_set_config(void *configData, OMX_INDEXTYPE index);
+ bool venc_h264_transform_8x8(OMX_BOOL enable);
+ 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);
+ bool venc_color_align(OMX_BUFFERHEADERTYPE *buffer, OMX_U32 width,
+ OMX_U32 height);
+ bool venc_get_performance_level(OMX_U32 *perflevel);
+ bool venc_get_vui_timing_info(OMX_U32 *enabled);
+ bool venc_get_vqzip_sei_info(OMX_U32 *enabled);
+ bool venc_get_peak_bitrate(OMX_U32 *peakbitrate);
+ bool venc_get_batch_size(OMX_U32 *size);
+ bool venc_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
+ OMX_U32 * /*nMaxBLayers*/);
+ bool venc_get_output_log_flag();
+ bool venc_check_valid_config();
+ int venc_output_log_buffers(const char *buffer_addr, int buffer_len);
+ int venc_input_log_buffers(OMX_BUFFERHEADERTYPE *buffer, int fd, int plane_offset,
+ unsigned long inputformat);
+ int venc_extradata_log_buffers(char *buffer_addr);
+ bool venc_set_bitrate_type(OMX_U32 type);
+
+#ifdef _VQZIP_
+ class venc_dev_vqzip
+ {
+ public:
+ venc_dev_vqzip();
+ ~venc_dev_vqzip();
+ bool init();
+ void deinit();
+ struct VQZipConfig pConfig;
+ int tempSEI[300];
+ int fill_stats_data(void* pBuf, void *pStats);
+ typedef void (*vqzip_deinit_t)(void*);
+ typedef void* (*vqzip_init_t)(void);
+ typedef VQZipStatus (*vqzip_compute_stats_t)(void* const , const void * const , const VQZipConfig* ,VQZipStats*);
+ private:
+ pthread_mutex_t lock;
+ void *mLibHandle;
+ void *mVQZIPHandle;
+ vqzip_init_t mVQZIPInit;
+ vqzip_deinit_t mVQZIPDeInit;
+ vqzip_compute_stats_t mVQZIPComputeStats;
+ };
+ venc_dev_vqzip vqzip;
+#endif
+
+#ifdef _PQ_
+ class venc_dev_pq
+ {
+ public:
+ venc_dev_pq();
+ ~venc_dev_pq();
+ bool is_pq_enabled;
+ bool is_YUV_format_uncertain;
+ pthread_mutex_t lock;
+ struct extradata_buffer_info roi_extradata_info;
+ bool init(unsigned long);
+ void deinit();
+ void get_caps();
+ int configure();
+ bool is_pq_handle_valid();
+ bool is_color_format_supported(unsigned long);
+ bool reinit(unsigned long);
+ struct gpu_stats_lib_input_config pConfig;
+ int fill_pq_stats(struct v4l2_buffer buf, unsigned int data_offset);
+ gpu_stats_lib_caps_t caps;
+ typedef gpu_stats_lib_op_status (*gpu_stats_lib_init_t)(void**, enum perf_hint gpu_hint, enum color_compression_format format);
+ typedef gpu_stats_lib_op_status (*gpu_stats_lib_deinit_t)(void*);
+ typedef gpu_stats_lib_op_status (*gpu_stats_lib_get_caps_t)(void* handle, gpu_stats_lib_caps_t *caps);
+ typedef gpu_stats_lib_op_status (*gpu_stats_lib_configure_t)(void* handle, gpu_stats_lib_input_config *input_t);
+ typedef gpu_stats_lib_op_status (*gpu_stats_lib_fill_data_t)(void *handle, gpu_stats_lib_buffer_params_t *yuv_input,
+ gpu_stats_lib_buffer_params_t *roi_input,
+ gpu_stats_lib_buffer_params_t *stats_output, void *addr, void *user_data);
+ private:
+ void *mLibHandle;
+ void *mPQHandle;
+ gpu_stats_lib_init_t mPQInit;
+ gpu_stats_lib_get_caps_t mPQGetCaps;
+ gpu_stats_lib_configure_t mPQConfigure;
+ gpu_stats_lib_deinit_t mPQDeInit;
+ gpu_stats_lib_fill_data_t mPQComputeStats;
+ unsigned long configured_format;
+ };
+ venc_dev_pq m_pq;
+ void venc_try_enable_pq(void);
+#endif
+ struct venc_debug_cap m_debug;
+ OMX_U32 m_nDriver_fd;
+ int m_poll_efd;
+ bool m_profile_set;
+ bool m_level_set;
+ int num_input_planes, num_output_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;
+ int resume_in_stopped;
+ bool m_max_allowed_bitrate_check;
+ pthread_t m_tid;
+ bool async_thread_created;
+ bool async_thread_force_stop;
+ class omx_venc *venc_handle;
+ OMX_ERRORTYPE allocate_extradata(struct extradata_buffer_info *extradata_info);
+ void free_extradata();
+ int append_mbi_extradata(void *, struct msm_vidc_extradata_header*);
+ bool handle_output_extradata(void *, int);
+ bool handle_input_extradata(struct v4l2_buffer);
+ int venc_set_format(int);
+ bool deinterlace_enabled;
+ bool hw_overload;
+ bool is_gralloc_source_ubwc;
+ bool is_camera_source_ubwc;
+ bool is_csc_enabled;
+ bool is_pq_force_disable;
+ OMX_U32 fd_list[64];
+
+ private:
+ OMX_U32 m_codec;
+ 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_initqp init_qp;
+ struct msm_venc_qprange session_qp_range;
+ struct msm_venc_qprange session_qp_values;
+ struct msm_venc_ipb_qprange session_ipb_qp_values;
+ 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;
+ struct msm_venc_hierlayers hier_layers;
+ struct msm_venc_perf_level performance_level;
+ struct msm_venc_vui_timing_info vui_timing_info;
+ struct msm_venc_vqzip_sei_info vqzip_sei_info;
+ struct msm_venc_peak_bitrate peak_bitrate;
+ struct msm_venc_ltrinfo ltrinfo;
+ struct msm_venc_vpx_error_resilience vpx_err_resilience;
+ struct msm_venc_priority sess_priority;
+ OMX_U32 operating_rate;
+ int rc_off_level;
+ struct msm_venc_hybrid_hp hybrid_hp;
+ struct msm_venc_color_space color_space;
+ msm_venc_temporal_layers temporal_layers_config;
+
+ 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_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp);
+ bool venc_set_session_qp_range_packed(OMX_U32 min_qp, OMX_U32 max_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, OMX_BOOL enable);
+ bool venc_set_idr_period(OMX_U32 nPFrames, OMX_U32 nIDRPeriod);
+ bool venc_reconfig_reqbufs();
+ bool venc_set_vpe_rotation(OMX_S32 rotation_angle);
+ bool venc_set_deinterlace(OMX_U32 enable);
+ bool venc_set_ltrmode(OMX_U32 enable, OMX_U32 count);
+ bool venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp);
+ bool venc_set_useltr(OMX_U32 frameIdx);
+ bool venc_set_markltr(OMX_U32 frameIdx);
+ bool venc_set_inband_video_header(OMX_BOOL enable);
+ bool venc_set_au_delimiter(OMX_BOOL enable);
+ bool venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type, OMX_U32 num_layers);
+ bool venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel);
+ bool venc_set_vui_timing_info(OMX_BOOL enable);
+ bool venc_set_peak_bitrate(OMX_U32 nPeakBitrate);
+ bool venc_set_searchrange();
+ bool venc_set_vpx_error_resilience(OMX_BOOL enable);
+ bool venc_set_perf_mode(OMX_U32 mode);
+ bool venc_set_mbi_statistics_mode(OMX_U32 mode);
+ bool venc_set_vqzip_sei_type(OMX_BOOL enable);
+ bool venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp);
+ bool venc_set_batch_size(OMX_U32 size);
+ bool venc_calibrate_gop();
+ bool venc_set_vqzip_defaults();
+ int venc_get_index_from_fd(OMX_U32 ion_fd, OMX_U32 buffer_fd);
+ bool venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode);
+ bool venc_set_hierp_layers(OMX_U32 hierp_layers);
+ bool venc_set_baselayerid(OMX_U32 baseid);
+ bool venc_set_qp(OMX_U32 nQp);
+ bool venc_set_aspectratio(void *nSar);
+ bool venc_set_priority(OMX_U32 priority);
+ bool venc_set_session_priority(OMX_U32 priority);
+ bool venc_set_operatingrate(OMX_U32 rate);
+ bool venc_set_layer_bitrates(OMX_U32 *pLayerBitrates, OMX_U32 numLayers);
+ bool venc_set_lowlatency_mode(OMX_BOOL enable);
+ bool venc_set_low_latency(OMX_BOOL enable);
+ bool venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo);
+ bool venc_set_blur_resolution(OMX_QTI_VIDEO_CONFIG_BLURINFO *blurInfo);
+ bool venc_set_colorspace(OMX_U32 primaries, OMX_U32 range, OMX_U32 transfer_chars, OMX_U32 matrix_coeffs);
+ OMX_ERRORTYPE venc_set_temporal_layers(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams);
+ OMX_ERRORTYPE venc_set_temporal_layers_internal();
+
+#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 input_extradata_info;
+ struct extradata_buffer_info output_extradata_info;
+
+ pthread_mutex_t pause_resume_mlock;
+ pthread_cond_t pause_resume_cond;
+ bool paused;
+ int color_format;
+ bool is_searchrange_set;
+ bool enable_mv_narrow_searchrange;
+ int supported_rc_modes;
+ bool is_thulium_v1;
+ bool camera_mode_enabled;
+ OMX_BOOL low_latency_mode;
+ struct {
+ bool dirty;
+ OMX_QTI_VIDEO_CONFIG_ROIINFO info;
+ } roi;
+
+ bool venc_empty_batch (OMX_BUFFERHEADERTYPE *buf, unsigned index);
+ static const int kMaxBuffersInBatch = 16;
+ unsigned int mBatchSize;
+ struct BatchInfo {
+ BatchInfo();
+ /* register a buffer and obtain its unique id (v4l2-buf-id)
+ */
+ int registerBuffer(int bufferId);
+ /* retrieve the buffer given its v4l2-buf-id
+ */
+ int retrieveBufferAt(int v4l2Id);
+ bool isPending(int bufferId);
+
+ private:
+ static const int kMaxBufs = 64;
+ static const int kBufIDFree = -1;
+ pthread_mutex_t mLock;
+ int mBufMap[64]; // Map with slots for each buffer
+ size_t mNumPending;
+
+ public:
+ // utility methods to parse entities in batch
+ // payload format for batch of 3
+ //| fd0 | fd1 | fd2 | off0 | off1 | off2 | len0 | len1 | len2 | csc0 | csc1 | csc2 | dTS0 | dTS1 | dTS2|
+ static inline int getFdAt(native_handle_t *, int index);
+ static inline int getOffsetAt(native_handle_t *, int index);
+ static inline int getSizeAt(native_handle_t *, int index);
+ static inline int getUsageAt(native_handle_t *, int index);
+ static inline int getColorFormatAt(native_handle_t *, int index);
+ static inline int getTimeStampAt(native_handle_t *, int index);
+ };
+ BatchInfo mBatchInfo;
+};
+
+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/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_test.h b/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_test.h
new file mode 100644
index 0000000..217611a
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/inc/video_encoder_test.h
@@ -0,0 +1,75 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2011, 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 <stdio.h>
+#include <stdlib.h>
+#include "queue.h"
+#include<fcntl.h>
+#include<sys/ioctl.h>
+#include <sys/mman.h>
+#include <linux/msm_vidc_enc.h>
+#include<pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+
+#define INPUT_BUFFER 0
+#define OUTPUT_BUFFER 1
+
+struct video_encoder_context {
+ unsigned long input_width;
+ unsigned long input_height;
+ unsigned long codectype;
+ unsigned long fps_num;
+ unsigned long fps_den;
+ unsigned long targetbitrate;
+ unsigned long inputformat;
+
+ struct venc_allocatorproperty input_buffer;
+ struct venc_allocatorproperty output_buffer;
+ struct venc_bufferpayload **ptr_inputbuffer;
+ struct venc_bufferpayload **ptr_outputbuffer;
+ struct video_queue_context queue_context;
+ int video_driver_fd;
+
+ FILE * inputBufferFile;
+ FILE * outputBufferFile;
+
+ pthread_t videothread_id;
+ pthread_t asyncthread_id;
+ sem_t sem_synchronize;
+};
+
+int init_encoder ( struct video_encoder_context *init_decode );
+int allocate_buffer ( unsigned int buffer_dir,
+ struct video_encoder_context *decode_context
+ );
+int free_buffer ( unsigned int buffer_dir,
+ struct video_encoder_context *decode_context
+ );
+int start_encoding (struct video_encoder_context *decode_context);
+int stop_encoding (struct video_encoder_context *decode_context);
+int deinit_encoder (struct video_encoder_context *init_decode);
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_hevc.cpp b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_hevc.cpp
new file mode 100644
index 0000000..0bc2e32
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_hevc.cpp
@@ -0,0 +1,1554 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 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_swvenc_hevc.h"
+#include <string.h>
+#include <stdio.h>
+#include <media/hardware/HardwareAPI.h>
+#include <gralloc_priv.h>
+#include <media/msm_media_info.h>
+
+/*----------------------------------------------------------------------------
+ * 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_swvenc);
+}
+
+//constructor
+
+omx_swvenc::omx_swvenc()
+{
+#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
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+ property_get("vidc.debug.level", property_value, "0");
+ debug_level = atoi(property_value);
+ property_value[0] = '\0';
+ m_pSwVenc = NULL;
+}
+
+omx_swvenc::~omx_swvenc()
+{
+ get_syntaxhdr_enable = false;
+ //nothing to do
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_swvenc::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_swvenc::component_init(OMX_STRING role)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ int fds[2];
+ int r;
+
+ OMX_VIDEO_CODINGTYPE codec_type;
+
+ DEBUG_PRINT_HIGH("omx_swvenc(): Inside component_init()");
+ // Copy the role information which provides the decoder m_nkind
+ strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE);
+ secure_session = false;
+
+ if (!strncmp((char *)m_nkind,"OMX.qti.video.encoder.hevc",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_encoder.hevc",\
+ OMX_MAX_STRINGNAME_SIZE);
+ codec_type = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
+ }
+ else {
+ DEBUG_PRINT_ERROR("ERROR: Unknown Component");
+ 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
+
+ OMX_INIT_STRUCT(&m_sParamHEVC, OMX_VIDEO_PARAM_HEVCTYPE);
+ m_sParamHEVC.eProfile = OMX_VIDEO_HEVCProfileMain;
+ m_sParamHEVC.eLevel = OMX_VIDEO_HEVCMainTierLevel3;
+
+ // Init for SWCodec
+ DEBUG_PRINT_HIGH("\n:Initializing SwVenc");
+ SWVENC_INITPARAMS swVencParameter;
+ memset(&swVencParameter, 0, sizeof(SWVENC_INITPARAMS));
+ swVencParameter.sDimensions.nWidth = 176;
+ swVencParameter.sDimensions.nHeight = 144;
+ swVencParameter.uProfile.eHevcProfile = SWVENC_HEVC_MAIN_PROFILE;
+ //sSwVencParameter.nNumWorkerThreads = 3;
+
+ m_callBackInfo.FillBufferDone = swvenc_fill_buffer_done_cb;
+ m_callBackInfo.EmptyBufferDone = swvenc_input_buffer_done_cb;
+ m_callBackInfo.HandleEvent = swvenc_handle_event_cb;
+ m_callBackInfo.pClientHandle = this;
+ SWVENC_STATUS sRet = SwVenc_Init(&swVencParameter, &m_callBackInfo, &m_pSwVenc);
+ if (sRet != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: SwVenc_Init 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;
+
+ // 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 = (char *)"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_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ 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_CODINGTYPE)QOMX_VIDEO_CodingHevc) {
+ m_sOutPortDef.format.video.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
+ }
+ 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_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ 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_CODINGTYPE)QOMX_VIDEO_CodingHevc) {
+ m_sOutPortFormat.eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
+ };
+
+
+ // 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;
+
+
+ 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;
+
+ OMX_INIT_STRUCT(&m_sParamLTRCount, QOMX_VIDEO_PARAM_LTRCOUNT_TYPE);
+ m_sParamLTRCount.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamLTRCount.nCount = 0;
+
+ OMX_INIT_STRUCT(&m_sConfigDeinterlace, OMX_VIDEO_CONFIG_DEINTERLACE);
+ m_sConfigDeinterlace.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sConfigDeinterlace.nEnable = OMX_FALSE;
+
+ OMX_INIT_STRUCT(&m_sHierLayers, QOMX_VIDEO_HIERARCHICALLAYERS);
+ m_sHierLayers.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sHierLayers.nNumLayers = 0;
+ m_sHierLayers.eHierarchicalCodingType = QOMX_HIERARCHICALCODING_P;
+
+ m_state = OMX_StateLoaded;
+ m_sExtraData = 0;
+
+ if (eRet == OMX_ErrorNone) {
+ if (pipe(fds)) {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
+ eRet = OMX_ErrorInsufficientResources;
+ } else {
+ if (fds[0] == 0 || fds[1] == 0) {
+ if (pipe(fds)) {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
+ 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_enc, this);
+ if (r < 0) {
+ eRet = OMX_ErrorInsufficientResources;
+ msg_thread_created = false;
+ }
+ }
+
+ DEBUG_PRINT_HIGH("Component_init return value = 0x%x", eRet);
+ return eRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_swvenc::Setparameter
+
+ DESCRIPTION
+ OMX Set Parameter method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_swvenc::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");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
+ 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");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ switch ((int)paramIndex) {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
+ (int)portDefn->format.video.nFrameHeight,
+ (int)portDefn->format.video.nFrameWidth);
+
+ SWVENC_PROP prop;
+ prop.ePropId = SWVENC_PROP_ID_DIMENSIONS;
+ prop.uProperty.sDimensions.nWidth = portDefn->format.video.nFrameWidth;
+ prop.uProperty.sDimensions.nHeight= portDefn->format.video.nFrameHeight;
+ SWVENC_STATUS status = SwVenc_SetProperty(m_pSwVenc,&prop);
+ if (status != SWVENC_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("ERROR: (In_PORT) dimension not supported %d x %d",
+ portDefn->format.video.nFrameWidth, portDefn->format.video.nFrameHeight);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ 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");
+ omx_report_unsupported_setting();
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_LOW("i/p actual cnt requested = %u", portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("i/p min cnt requested = %u", portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("i/p buffersize requested = %u", portDefn->nBufferSize);
+ if (portDefn->nBufferCountMin > portDefn->nBufferCountActual) {
+ DEBUG_PRINT_ERROR("ERROR: (In_PORT) Min buffers (%u) > actual count (%u)",
+ portDefn->nBufferCountMin, portDefn->nBufferCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ DEBUG_PRINT_LOW("i/p previous actual cnt = %u", m_sInPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("i/p previous min cnt = %u", m_sInPortDef.nBufferCountMin);
+ memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+ DEBUG_PRINT_LOW("i/p COLOR FORMAT = %u", portDefn->format.video.eColorFormat);
+#ifdef _ANDROID_ICS_
+ if (portDefn->format.video.eColorFormat ==
+ (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) {
+ m_sInPortDef.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ if (!mUseProxyColorFormat) {
+ if (!c2d_conv.init()) {
+ DEBUG_PRINT_ERROR("C2D init failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_LOW("C2D 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("o/p actual cnt requested = %u", portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("o/p min cnt requested = %u", portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("o/p buffersize requested = %u", portDefn->nBufferSize);
+ if (portDefn->nBufferCountMin > portDefn->nBufferCountActual) {
+ DEBUG_PRINT_ERROR("ERROR: (Out_PORT) Min buffers (%u) > actual count (%u)",
+ portDefn->nBufferCountMin, portDefn->nBufferCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ /*Query ouput Buffer Requirements*/
+ dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+
+ memcpy(&m_sOutPortDef,portDefn,sizeof(struct OMX_PARAM_PORTDEFINITIONTYPE));
+ update_profile_level(); //framerate , bitrate
+
+ DEBUG_PRINT_LOW("o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("o/p previous min cnt = %u", 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",
+ portFmt->eColorFormat);
+ //set the driver with the corresponding values
+ if (PORT_INDEX_IN == portFmt->nPortIndex) {
+
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
+ portFmt->eColorFormat);
+
+ SWVENC_PROP prop;
+ prop.uProperty.nFrameRate = portFmt->xFramerate;
+ prop.ePropId = SWVENC_PROP_ID_FRAMERATE;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+
+ update_profile_level(); //framerate
+
+#ifdef _ANDROID_ICS_
+ if (portFmt->eColorFormat ==
+ (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) {
+ m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ if (!mUseProxyColorFormat) {
+ if (!c2d_conv.init()) {
+ DEBUG_PRINT_ERROR("C2D init failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_LOW("C2D 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("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");
+
+ SWVENC_PROP prop;
+ prop.uProperty.nFrameRate = pParam->nTargetBitrate;
+ prop.ePropId = SWVENC_PROP_ID_BITRATE;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+
+ prop.uProperty.nRcOn = pParam->eControlRate;
+ prop.ePropId = SWVENC_PROP_ID_RC_ON;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+
+ 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("bitrate = %u", m_sOutPortDef.format.video.nBitrate);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ case OMX_IndexParamVideoH263:
+ case OMX_IndexParamVideoAvc:
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
+ return OMX_ErrorUnsupportedSetting;
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
+ {
+ OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoHevc");
+ if (pParam->eProfile != OMX_VIDEO_HEVCProfileMain ||
+ (pParam->eLevel != OMX_VIDEO_HEVCMainTierLevel1 &&
+ pParam->eLevel != OMX_VIDEO_HEVCMainTierLevel2 &&
+ pParam->eLevel != OMX_VIDEO_HEVCMainTierLevel21 &&
+ pParam->eLevel != OMX_VIDEO_HEVCMainTierLevel3))
+ {
+ return OMX_ErrorBadParameter;
+ }
+ m_sParamHEVC.eProfile = OMX_VIDEO_HEVCProfileMain;
+ m_sParamHEVC.eLevel = pParam->eLevel;
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent");
+
+ m_sParamProfileLevel.eProfile = pParam->eProfile;
+ m_sParamProfileLevel.eLevel = pParam->eLevel;
+
+ if (!strncmp((char *)m_nkind, "OMX.qti.video.encoder.hevc",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+
+ // DEBUG_PRINT_LOW("HEVC profile = %d, level = %d");
+ }
+ 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");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (!strncmp((char*)m_nkind, "OMX.qti.video.encoder.hevc",OMX_MAX_STRINGNAME_SIZE)) {
+ if (!strncmp((char*)comp_role->cRole,"video_encoder.hevc",OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char*)m_cRole,"video_encoder.hevc",OMX_MAX_STRINGNAME_SIZE);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", 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");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
+ priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
+ 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",
+ 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");
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
+ if (session_qp->nPortIndex == PORT_INDEX_OUT) {
+ SWVENC_PROP prop;
+ prop.uProperty.nQp = session_qp->nQpI;
+ prop.ePropId = SWVENC_PROP_ID_QP;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+
+ m_sSessionQuantization.nQpI = session_qp->nQpI;
+ m_sSessionQuantization.nQpP = session_qp->nQpP;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP setting");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoQPRange:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoQPRange");
+ OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData;
+ if (qp_range->nPortIndex == PORT_INDEX_OUT) {
+ m_sSessionQPRange.minQP= qp_range->minQP;
+ m_sSessionQPRange.maxQP= qp_range->maxQP;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for QP range setting");
+ 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");
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam =
+ (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
+ memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection));
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh");
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam =
+ (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
+
+ memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh));
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoMetaBufferMode:
+ {
+ StoreMetaDataInBuffersParams *pParam =
+ (StoreMetaDataInBuffersParams*)paramData;
+ DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoMetaBufferMode: "
+ "port_index = %u, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData);
+ if (pParam->nPortIndex == PORT_INDEX_IN)
+ {
+ meta_mode_enable = pParam->bStoreMetaData;
+ }
+ else
+ {
+ if (pParam->bStoreMetaData)
+ {
+ DEBUG_PRINT_ERROR("set_parameter: metamode is "
+ "valid for input port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ }
+ break;
+ default:
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+ return eRet;
+}
+
+bool omx_swvenc::update_profile_level()
+{
+ if (!strncmp((char *)m_nkind, "OMX.qti.video.encoder.hevc",\
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ if (m_sParamHEVC.eProfile != OMX_VIDEO_HEVCProfileMain)
+ {
+ return false;
+ }
+ SWVENC_PROP prop;
+ prop.ePropId = SWVENC_PROP_ID_PROFILE;
+ prop.uProperty.nProfile = SWVENC_HEVC_MAIN_PROFILE;
+ if (SwVenc_SetProperty(m_pSwVenc, &prop) != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: failed to set profile");
+ }
+
+ int level = 0;
+ if (m_sParamHEVC.eLevel == OMX_VIDEO_HEVCMainTierLevel1)
+ {
+ level = SWVENC_HEVC_LEVEL_1;
+ }
+ else if (m_sParamHEVC.eLevel == OMX_VIDEO_HEVCMainTierLevel2)
+ {
+ level = SWVENC_HEVC_LEVEL_2;
+ }
+ else if (m_sParamHEVC.eLevel == OMX_VIDEO_HEVCMainTierLevel21)
+ {
+ level = SWVENC_HEVC_LEVEL_2_1;
+ }
+ else if (m_sParamHEVC.eLevel == OMX_VIDEO_HEVCMainTierLevel3)
+ {
+ level = SWVENC_HEVC_LEVEL_3;
+ }
+
+ if (level)
+ {
+ prop.ePropId = SWVENC_PROP_ID_LEVEL;
+ prop.uProperty.nLevel = (SWVENC_HEVC_LEVEL)level;
+ if (SwVenc_SetProperty(m_pSwVenc, &prop) != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: failed to set level %d", level);
+ }
+ }
+ }
+
+ return true;
+}
+/* ======================================================================
+ FUNCTION
+ omx_video::SetConfig
+
+ DESCRIPTION
+ OMX Set Config method implementation
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if successful.
+ ========================================================================== */
+OMX_ERRORTYPE omx_swvenc::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 ((int)configIndex) {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE* pParam =
+ reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", pParam->nEncodeBitrate);
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ SWVENC_PROP prop;
+ prop.uProperty.nBitrate = pParam->nEncodeBitrate;
+ prop.ePropId = SWVENC_PROP_ID_BITRATE;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+
+
+ m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate;
+ m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate;
+ m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", pParam->xEncodeFramerate);
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ SWVENC_PROP prop;
+ prop.uProperty.nFrameRate = pParam->xEncodeFramerate;
+ prop.ePropId = SWVENC_PROP_ID_FRAMERATE;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+
+ m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate;
+ m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate;
+ m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ QOMX_VIDEO_INTRAPERIODTYPE* pParam =
+ reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
+
+ DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod");
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ if (pParam->nBFrames > 0) {
+ DEBUG_PRINT_ERROR("B frames not supported");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_HIGH("Old: P/B frames = %u/%u, New: P/B frames = %u/%u",
+ 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;
+ }
+
+ SWVENC_PROP prop;
+ prop.uProperty.sIntraPeriod.pFrames = pParam->nPFrames;
+ prop.uProperty.sIntraPeriod.bFrames = pParam->nBFrames;
+ prop.ePropId = SWVENC_PROP_ID_INTRA_PERIOD;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+
+ m_sIntraperiod.nPFrames = pParam->nPFrames;
+ m_sIntraperiod.nBFrames = pParam->nBFrames;
+ m_sIntraperiod.nIDRPeriod = pParam->nIDRPeriod;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(configData);
+
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh");
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ SWVENC_PROP prop;
+ prop.ePropId = SWVENC_PROP_ID_IDR_INSERTION;
+ SwVenc_SetProperty(m_pSwVenc, &prop);
+ DEBUG_PRINT_HIGH("Setting SWVENC OMX_IndexConfigVideoIntraVOPRefresh");
+ m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ 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;
+ }
+ default:
+ DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_swvenc::ComponentDeInit
+
+ DESCRIPTION
+ Destroys the component and release memory allocated to the heap.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if everything successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_swvenc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ OMX_U32 i = 0;
+ DEBUG_PRINT_HIGH("omx_swvenc(): Inside component_deinit()");
+ if (OMX_StateLoaded != m_state) {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
+ m_state);
+ }
+ if (m_out_mem_ptr) {
+ DEBUG_PRINT_LOW("Freeing the Output Memory");
+ 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");
+ for (i=0; i<m_sInPortDef.nBufferCountActual; i++ ) {
+ free_input_buffer (&m_inp_mem_ptr[i]);
+ }
+
+
+ free(m_inp_mem_ptr);
+ m_inp_mem_ptr = NULL;
+ }
+
+ // Reset counters in mesg queues
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+
+#ifdef _ANDROID_
+ // Clear the strong reference
+ DEBUG_PRINT_HIGH("Calling m_heap_ptr.clear()");
+ m_heap_ptr.clear();
+#endif // _ANDROID_
+
+ DEBUG_PRINT_HIGH("Calling SwVenc_Stop()");
+ SWVENC_STATUS ret = SwVenc_Stop(m_pSwVenc);
+ if (ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("SwVenc_Stop Command failed in venc destructor");
+ }
+
+ DEBUG_PRINT_HIGH("Deleting m_pSwVenc HANDLE[%p]", m_pSwVenc);
+ SwVenc_DeInit(m_pSwVenc);
+ m_pSwVenc = NULL;
+
+ DEBUG_PRINT_HIGH("omx_swvenc:Component Deinit");
+ return OMX_ErrorNone;
+}
+
+
+OMX_U32 omx_swvenc::dev_stop( void)
+{
+ SwVenc_Stop(m_pSwVenc);
+ post_event (0,0,OMX_COMPONENT_GENERATE_STOP_DONE);
+ return SWVENC_S_SUCCESS;
+}
+
+
+OMX_U32 omx_swvenc::dev_pause(void)
+{
+ return SWVENC_S_SUCCESS;
+}
+
+OMX_U32 omx_swvenc::dev_start(void)
+{
+ SwVenc_Start(m_pSwVenc);
+ post_event (0,0,OMX_COMPONENT_GENERATE_START_DONE);
+ return SWVENC_S_SUCCESS;
+}
+
+OMX_U32 omx_swvenc::dev_flush(unsigned port)
+{
+ if (port == PORT_INDEX_IN)
+ {
+ return SWVENC_S_EUNSUPPORTED;
+ }
+
+ DEBUG_PRINT_HIGH("SwVenc_Flush port %d", port);
+ return SwVenc_Flush(m_pSwVenc);
+}
+
+OMX_U32 omx_swvenc::dev_resume(void)
+{
+ return SWVENC_S_SUCCESS;
+}
+
+OMX_U32 omx_swvenc::dev_start_done(void)
+{
+ return SWVENC_S_SUCCESS;
+}
+
+OMX_U32 omx_swvenc::dev_set_message_thread_id(pthread_t tid)
+{
+ return SWVENC_S_SUCCESS;
+}
+
+bool omx_swvenc::dev_use_buf(void *buf_addr,unsigned port,unsigned index)
+{
+ struct pmem* buf = (struct pmem*)buf_addr;
+ if (port == PORT_INDEX_IN)
+ {
+ // m_pSwVencIpBuffer[index].nSize = buf->size;
+ m_pSwVencIpBuffer[index].pBuffer = (unsigned char*)buf->buffer;
+ m_pSwVencIpBuffer[index].pClientBufferData = (void*)index;
+
+ DEBUG_PRINT_LOW("dev_use_buf input %p, index %d userData %p",
+ m_pSwVencIpBuffer[index].pBuffer, index, m_pSwVencIpBuffer[index].pClientBufferData);
+ }
+ else
+ {
+ m_pSwVencOpBuffer[index].nSize = buf->size;
+ m_pSwVencOpBuffer[index].pBuffer = (unsigned char*)buf->buffer;
+ m_pSwVencOpBuffer[index].pClientBufferData = (void*)index;
+ DEBUG_PRINT_LOW("dev_use_buf output %p, index %d userData %p",
+ m_pSwVencIpBuffer[index].pBuffer, index, m_pSwVencIpBuffer[index].pClientBufferData);
+ }
+ return true;
+}
+
+bool omx_swvenc::dev_free_buf(void *buf_addr,unsigned port)
+{
+ struct pmem* buf = (struct pmem*)buf_addr;
+ int i = 0;
+ if (port == PORT_INDEX_IN)
+ {
+ for (; i<32;i++)
+ {
+ if (m_pSwVencIpBuffer[i].pBuffer == buf->buffer)
+ {
+ m_pSwVencIpBuffer[i].pBuffer = NULL;
+ // m_pSwVencIpBuffer[i].nSize = 0;
+ }
+ }
+ }
+ else
+ {
+ for (; i<32;i++)
+ {
+ if (m_pSwVencOpBuffer[i].pBuffer == buf->buffer)
+ {
+ m_pSwVencOpBuffer[i].pBuffer = NULL;
+ m_pSwVencOpBuffer[i].nSize = 0;
+ }
+ }
+ }
+ return true;
+}
+
+void dump_buffer(unsigned char* buffer, int stride, int scanlines, int width, int height)
+{
+ static FILE* pFile = NULL;
+ static int count = 0;
+ if (count++ >= 100) return;
+
+ if (pFile == NULL)
+ {
+ pFile = fopen("/data/input.yuv", "wb");
+ }
+ if (buffer)
+ {
+ char *temp = (char *)buffer;
+ int i;
+ int bytes_written = 0;
+ int bytes = 0;
+
+ for (i = 0; i < height; i++) {
+ bytes_written = fwrite(temp, width, 1, pFile);
+ temp += stride;
+ if (bytes_written >0)
+ bytes += bytes_written * width;
+ }
+ temp = (char *)buffer + stride * scanlines;
+ int stride_c = stride;
+ for(i = 0; i < height/2; i++) {
+ bytes_written = fwrite(temp, width, 1, pFile);
+ temp += stride_c;
+ if (bytes_written >0)
+ bytes += bytes_written * width;
+ }
+
+ DEBUG_PRINT_ERROR("stride %d, scanlines %d, frame_height %d bytes_written %d",
+ stride, scanlines, height, bytes);
+ }
+}
+
+static FILE* gYUV = NULL;
+
+bool omx_swvenc::dev_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
+{
+ SWVENC_STATUS status;
+ SWVENC_IPBUFFER ipbuffer;
+ OMX_BUFFERHEADERTYPE *bufHdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+ if (meta_mode_enable)
+ {
+ unsigned int size = 0, offset = 0;
+ encoder_media_buffer_type *meta_buf = NULL;
+ meta_buf = (encoder_media_buffer_type *)bufHdr->pBuffer;
+ if (meta_buf)
+ {
+ if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource)
+ {
+ offset = meta_buf->meta_handle->data[1];
+ size = meta_buf->meta_handle->data[2];
+ }
+ else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
+ {
+ private_handle_t *handle = (private_handle_t *)meta_buf->meta_handle;
+ size = handle->size;
+ }
+ }
+
+ ipbuffer.pBuffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
+ ipbuffer.nFilledLen = size;
+ DEBUG_PRINT_LOW("mapped meta buf fd %d size %d %p", fd, size, ipbuffer.pBuffer);
+ }
+ else
+ {
+ ipbuffer.pBuffer = bufHdr->pBuffer;
+ ipbuffer.nFilledLen = bufHdr->nFilledLen;
+ }
+
+ ipbuffer.nFlags = bufHdr->nFlags;
+ ipbuffer.nIpTimestamp = bufHdr->nTimeStamp;
+ ipbuffer.pClientBufferData = (unsigned char *)bufHdr;
+
+ DEBUG_PRINT_LOW("SwVenc_EmptyThisBuffer index %d pBuffer %p", index, ipbuffer.pBuffer);
+ status = SwVenc_EmptyThisBuffer(m_pSwVenc, &ipbuffer);
+
+ if (status != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("SwVenc_EmptyThisBuffer failed");
+ post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
+ pending_output_buffers--;
+ }
+
+ return status == SWVENC_S_SUCCESS;
+}
+
+bool omx_swvenc::dev_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
+{
+ SWVENC_STATUS status;
+ OMX_BUFFERHEADERTYPE* bufHdr = (OMX_BUFFERHEADERTYPE*)buffer;
+
+ DEBUG_PRINT_LOW("SwVenc_FillThisBuffer index %d pBuffer %p pmem_data_buf %p",
+ index, bufHdr->pBuffer, pmem_data_buf);
+ status = SwVenc_FillThisBuffer(m_pSwVenc, &m_pSwVencOpBuffer[index]);
+
+ if (status != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("SwVenc_FillThisBuffer failed");
+ post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_FBD);
+ pending_output_buffers--;
+ }
+
+ return status == SWVENC_S_SUCCESS;
+}
+
+bool omx_swvenc::dev_get_seq_hdr(void *buffer, unsigned size, unsigned *hdrlen)
+{
+ return false;
+}
+
+bool omx_swvenc::dev_get_capability_ltrcount(OMX_U32 *min, OMX_U32 *max, OMX_U32 *step_size)
+{
+ return true;
+}
+
+bool omx_swvenc::dev_loaded_start()
+{
+ return true;
+}
+
+bool omx_swvenc::dev_loaded_stop()
+{
+ return true;
+}
+
+bool omx_swvenc::dev_loaded_start_done()
+{
+ return true;
+}
+
+bool omx_swvenc::dev_loaded_stop_done()
+{
+ return true;
+}
+
+
+bool omx_swvenc::dev_get_performance_level(OMX_U32 *perflevel)
+{
+ DEBUG_PRINT_ERROR("Get performance level is not supported");
+ return false;
+}
+
+bool omx_swvenc::dev_get_vui_timing_info(OMX_U32 *enabled)
+{
+ DEBUG_PRINT_ERROR("Get vui timing information is not supported");
+ return false;
+}
+
+bool omx_swvenc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
+{
+ DEBUG_PRINT_ERROR("Get peak bitrate is not supported");
+ return false;
+}
+
+bool omx_swvenc::dev_get_buf_req(OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 port)
+{
+ SWVENC_STATUS sRet = SWVENC_S_SUCCESS;
+ SWVENC_PROP property;
+ property.ePropId = (port == 0) ? SWVENC_PROP_ID_IPBUFFREQ : SWVENC_PROP_ID_OPBUFFREQ;
+
+ sRet = SwVenc_GetProperty(m_pSwVenc, &property);
+ if (sRet == SWVENC_S_SUCCESS)
+ {
+ if (port == 0)
+ {
+ *min_buff_count = property.uProperty.sIpBuffReq.nMinCount;
+ *buff_size = property.uProperty.sIpBuffReq.nSize;
+ *actual_buff_count = property.uProperty.sIpBuffReq.nMinCount;
+ DEBUG_PRINT_HIGH("SwVenc input buffer Size =%u Count = %u", *buff_size, *actual_buff_count);
+ }
+ else
+ {
+ *min_buff_count = property.uProperty.sOpBuffReq.nMinCount;
+ *buff_size = property.uProperty.sOpBuffReq.nSize;
+ *actual_buff_count = property.uProperty.sOpBuffReq.nMinCount;
+ DEBUG_PRINT_HIGH("SwVenc output buffer Size =%u Count = %u", property.uProperty.sOpBuffReq.nSize, property.uProperty.sOpBuffReq.nMinCount);
+ }
+ }
+
+ return (sRet == SWVENC_S_SUCCESS);
+}
+
+bool omx_swvenc::dev_set_buf_req(OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 port)
+{
+ SWVENC_PROP property;
+ SWVENC_STATUS sRet = SWVENC_S_SUCCESS;
+
+ if (port != PORT_INDEX_IN || port != PORT_INDEX_OUT) return false;
+ if (*min_buff_count > *actual_buff_count) return false;
+
+ if(port == PORT_INDEX_IN)
+ {
+ property.ePropId = SWVENC_PROP_ID_IPBUFFREQ;
+ property.uProperty.sIpBuffReq.nSize = *buff_size;;
+ property.uProperty.sIpBuffReq.nMaxCount = *actual_buff_count;
+ property.uProperty.sIpBuffReq.nMinCount = *actual_buff_count;
+ DEBUG_PRINT_HIGH("Set SwVenc input Buffer Size =%d Count = %d",property.uProperty.sIpBuffReq.nSize, *actual_buff_count);
+ }
+ else if (port == PORT_INDEX_OUT)
+ {
+ property.ePropId = SWVENC_PROP_ID_OPBUFFREQ;
+ property.uProperty.sOpBuffReq.nSize = *buff_size;
+ property.uProperty.sOpBuffReq.nMaxCount = *actual_buff_count;
+ property.uProperty.sOpBuffReq.nMinCount = *actual_buff_count;
+ DEBUG_PRINT_HIGH("Set SwVenc output Buffer Size =%d and Count = %d",property.uProperty.sOpBuffReq.nSize, *actual_buff_count);
+ }
+
+ sRet = SwVenc_SetProperty(m_pSwVenc, &property);
+ if (sRet != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("Set buffer requirements from ARM codec failed");
+ }
+
+ return sRet == SWVENC_S_SUCCESS;
+}
+
+bool omx_swvenc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height)
+{
+ if (width > 1280 || height > 720) return false;
+ return true;
+}
+
+
+int omx_swvenc::dev_handle_extradata(void *buffer, int index)
+{
+ return SWVENC_S_EUNSUPPORTED;
+}
+
+int omx_swvenc::dev_set_format(int color)
+{
+ return SWVENC_S_SUCCESS;
+}
+
+bool omx_swvenc::dev_color_align(OMX_BUFFERHEADERTYPE *buffer,
+ OMX_U32 width, OMX_U32 height)
+{
+ if(secure_session) {
+ DEBUG_PRINT_ERROR("Cannot align colors in secure session.");
+ return OMX_FALSE;
+ }
+ return true;
+}
+
+bool omx_swvenc::is_secure_session()
+{
+ return secure_session;
+}
+
+bool omx_swvenc::dev_get_output_log_flag()
+{
+ return false;
+}
+
+int omx_swvenc::dev_output_log_buffers(const char *buffer, int bufferlen)
+{
+ return 0;
+}
+
+int omx_swvenc::dev_extradata_log_buffers(char *buffer)
+{
+ return 0;
+}
+
+SWVENC_STATUS omx_swvenc::swvenc_input_buffer_done_cb
+(
+ SWVENC_HANDLE pSwEnc,
+ SWVENC_IPBUFFER *pIpBuffer,
+ void *pClientHandle
+)
+{
+ SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
+ omx_swvenc *omx = reinterpret_cast<omx_swvenc*>(pClientHandle);
+
+ if (pIpBuffer == NULL)
+ {
+ eRet = SWVENC_S_EFAIL;
+ }
+ else
+ {
+ omx->swvenc_input_buffer_done(pIpBuffer);
+ }
+
+ return eRet;
+}
+
+void omx_swvenc::swvenc_input_buffer_done(SWVENC_IPBUFFER *pIpBuffer)
+{
+ OMX_BUFFERHEADERTYPE *bufHdr = (OMX_BUFFERHEADERTYPE *)pIpBuffer->pClientBufferData;
+
+ if (meta_mode_enable)
+ {
+ omx_release_meta_buffer(bufHdr);
+
+ // fd is not dupped, nothing needs to be done here
+ munmap(pIpBuffer->pBuffer, pIpBuffer->nFilledLen);
+ }
+
+ DEBUG_PRINT_LOW("swvenc_empty_buffer_done bufHdr %p pBuffer %p = %p nFilledLen %d nFlags %x",
+ bufHdr, bufHdr->pBuffer, pIpBuffer->pBuffer, pIpBuffer->nFilledLen, pIpBuffer->nFlags);
+
+ post_event((unsigned int)(bufHdr), SWVENC_S_SUCCESS, OMX_COMPONENT_GENERATE_EBD);
+}
+
+SWVENC_STATUS omx_swvenc::swvenc_fill_buffer_done_cb
+(
+ SWVENC_HANDLE pSwEnc,
+ SWVENC_OPBUFFER *m_pSWVencOpBuffer,
+ void *pClientHandle
+)
+{
+ SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
+ omx_swvenc *omx = reinterpret_cast<omx_swvenc*>(pClientHandle);
+
+ if (m_pSWVencOpBuffer == NULL)
+ {
+ eRet = SWVENC_S_EFAIL;
+ }
+ else
+ {
+ omx->swvenc_fill_buffer_done(m_pSWVencOpBuffer);
+ }
+ return eRet;
+}
+
+void omx_swvenc::swvenc_fill_buffer_done(SWVENC_OPBUFFER *pOpBuffer)
+{
+ int index = (int)pOpBuffer->pClientBufferData;
+ OMX_BUFFERHEADERTYPE *bufHdr = m_out_mem_ptr + index;
+
+ bufHdr->nOffset = 0;
+ bufHdr->nFilledLen = pOpBuffer->nFilledLen;
+ bufHdr->nFlags = pOpBuffer->nFlags;
+ bufHdr->nTimeStamp = pOpBuffer->nOpTimestamp;
+
+ if (bufHdr->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ DEBUG_PRINT_ERROR("swvenc output EOS reached\n");
+ }
+
+ /*Use buffer case*/
+ if (output_use_buffer && !m_use_output_pmem &&
+ !output_flush_progress && pOpBuffer->nFilledLen)
+ {
+ DEBUG_PRINT_LOW("memcpy for o/p Heap UseBuffer size %d", pOpBuffer->nFilledLen);
+ memcpy(bufHdr->pBuffer, pOpBuffer->pBuffer, pOpBuffer->nFilledLen);
+ }
+
+ DEBUG_PRINT_LOW("swvenc_fill_buffer_done bufHdr %p pBuffer %p = %p idx %d nFilledLen %d nFlags %x\n",
+ bufHdr, bufHdr->pBuffer, pOpBuffer->pBuffer, index, pOpBuffer->nFilledLen, pOpBuffer->nFlags);
+ post_event((unsigned int)bufHdr, SWVENC_S_SUCCESS, OMX_COMPONENT_GENERATE_FBD);
+}
+
+SWVENC_STATUS omx_swvenc::swvenc_handle_event_cb
+(
+ SWVENC_HANDLE pSwEnc,
+ SWVENC_EVENTHANDLER* pEventHandler,
+ void *pClientHandle
+)
+{
+ omx_swvenc *omx = reinterpret_cast<omx_swvenc*>(pClientHandle);
+ omx->swvenc_handle_event(pEventHandler);
+ return SWVENC_S_SUCCESS;
+}
+
+void omx_swvenc::swvenc_handle_event(SWVENC_EVENTHANDLER *pEvent)
+{
+ switch(pEvent->eEvent)
+ {
+ case SWVENC_FLUSH_DONE:
+ DEBUG_PRINT_HIGH("SWVENC_FLUSH_DONE input_flush_progress %d output_flush_progress %d\n",
+ input_flush_progress, output_flush_progress);
+ if (input_flush_progress)
+ {
+ post_event ((unsigned)NULL, SWVENC_S_SUCCESS, OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
+ }
+ if (output_flush_progress)
+ {
+ post_event ((unsigned)NULL, SWVENC_S_SUCCESS, OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
+ }
+ break;
+ case SWVENC_ERROR:
+ break;
+
+ default:
+ break;
+ }
+
+}
+
+
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp
new file mode 100644
index 0000000..52d5340
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_swvenc_mpeg4.cpp
@@ -0,0 +1,2982 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014-2016, 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_swvenc_mpeg4.h"
+
+/* def: StoreMetaDataInBuffersParams */
+#include <media/hardware/HardwareAPI.h>
+
+/* def: VENUS_BUFFER_SIZE, VENUS_Y_STRIDE etc */
+#include <media/msm_media_info.h>
+
+/* def: private_handle_t*/
+#include <gralloc_priv.h>
+
+
+/*----------------------------------------------------------------------------
+ * 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
+
+#define ENTER_FUNC() DEBUG_PRINT_HIGH("ENTERING: %s",__FUNCTION__)
+#define EXIT_FUNC() DEBUG_PRINT_HIGH("EXITING: %s",__FUNCTION__)
+#define RETURN(x) EXIT_FUNC(); return x;
+#define ALIGN(value,alignment) (((value) + (alignment-1)) & (~(alignment-1)))
+
+#define BUFFER_LOG_LOC "/data/misc/media"
+
+/* factory function executed by the core to create instances */
+void *get_omx_component_factory_fn(void)
+{
+ RETURN((new omx_venc));
+}
+
+omx_venc::omx_venc()
+{
+ ENTER_FUNC();
+
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+
+ memset(&m_debug,0,sizeof(m_debug));
+
+ property_value[0] = '\0';
+ property_get("vidc.debug.level", property_value, "1");
+ debug_level = atoi(property_value);
+
+ property_value[0] = '\0';
+ property_get("vidc.enc.log.in", property_value, "0");
+ m_debug.in_buffer_log = atoi(property_value);
+
+ property_value[0] = '\0';
+ property_get("vidc.enc.log.out", property_value, "0");
+ m_debug.out_buffer_log = atoi(property_value);
+
+ snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
+ property_value[0] = '\0';
+ property_get("vidc.log.loc", property_value, "");
+ if (*property_value)
+ {
+ strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
+ }
+
+ memset(meta_buffer_hdr,0,sizeof(meta_buffer_hdr));
+ 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;
+ m_bSeqHdrRequested = false;
+ format_set = false;
+
+ EXIT_FUNC();
+}
+
+omx_venc::~omx_venc()
+{
+ ENTER_FUNC();
+ get_syntaxhdr_enable = false;
+ EXIT_FUNC();
+}
+
+OMX_ERRORTYPE omx_venc::component_init(OMX_STRING role)
+{
+ ENTER_FUNC();
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_CALLBACK callBackInfo;
+ OMX_VIDEO_CODINGTYPE codec_type;
+ SWVENC_PROPERTY Prop;
+ int fds[2];
+
+ strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE);
+ secure_session = false;
+
+ if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.mpeg4sw",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char *)m_cRole, "video_encoder.mpeg4",\
+ OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingMPEG4;
+ m_codec = SWVENC_CODEC_MPEG4;
+ }
+ else if (!strncmp( (char *)m_nkind,"OMX.qcom.video.encoder.h263sw",
+ OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char *)m_cRole, "video_encoder.h263",\
+ OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingH263;
+ m_codec = SWVENC_CODEC_H263;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unknown Component");
+ eRet = OMX_ErrorInvalidComponentName;
+ RETURN(eRet);
+ }
+
+#ifdef ENABLE_GET_SYNTAX_HDR
+ get_syntaxhdr_enable = true;
+ DEBUG_PRINT_HIGH("Get syntax header enabled");
+#endif
+
+ callBackInfo.pfn_empty_buffer_done = swvenc_empty_buffer_done_cb;
+ callBackInfo.pfn_fill_buffer_done = swvenc_fill_buffer_done_cb;
+ callBackInfo.pfn_event_notification = swvenc_handle_event_cb;
+ callBackInfo.p_client = (void*)this;
+
+ SWVENC_STATUS sRet = swvenc_init(&m_hSwVenc, m_codec, &callBackInfo);
+ if (sRet != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("swvenc_init returned %d, ret insufficient resources",
+ sRet);
+ RETURN(OMX_ErrorInsufficientResources);
+ }
+
+ m_stopped = true;
+
+ //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;
+
+ 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;
+ }
+
+ /* set the profile and level */
+ Ret = swvenc_set_profile_level(m_sParamProfileLevel.eProfile,
+ m_sParamProfileLevel.eLevel);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUndefined);
+ }
+
+ // 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 = (char *)"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_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ m_sInPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+ /* set the frame size */
+ Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
+ Prop.info.frame_size.height = m_sInPortDef.format.video.nFrameHeight;
+ Prop.info.frame_size.width = m_sInPortDef.format.video.nFrameWidth;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ /* set the frame attributes */
+ Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
+ Prop.info.frame_attributes.stride_luma = m_sInPortDef.format.video.nStride;
+ Prop.info.frame_attributes.stride_chroma = m_sInPortDef.format.video.nStride;
+ Prop.info.frame_attributes.offset_luma = 0;
+ Prop.info.frame_attributes.offset_chroma =
+ (m_sInPortDef.format.video.nSliceHeight * m_sInPortDef.format.video.nStride);
+ Prop.info.frame_attributes.size = (Prop.info.frame_attributes.offset_chroma * 3) >> 1;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUndefined);
+ }
+
+ Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ &m_sInPortDef.nBufferAlignment,
+ PORT_INDEX_IN);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
+ Ret);
+ RETURN(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;
+ }
+
+ Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ &m_sOutPortDef.nBufferAlignment,
+ PORT_INDEX_OUT);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
+ Ret);
+ RETURN(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_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ 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;
+ }
+
+ // 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;
+
+ OMX_INIT_STRUCT(&m_sParamInitqp, QOMX_EXTNINDEX_VIDEO_INITIALQP);
+ m_sParamInitqp.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;
+ // 2 second intra period for default outport fps
+ m_sParamMPEG4.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
+ m_sParamMPEG4.bACPred = OMX_TRUE;
+ // delta = 2 @ 15 fps
+ m_sParamMPEG4.nTimeIncRes = 30;
+ // pframe and iframe
+ m_sParamMPEG4.nAllowedPictureTypes = 2;
+ // number of video packet headers per vop
+ m_sParamMPEG4.nHeaderExtension = 1;
+ 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;
+ // 2 second intra period for default outport fps
+ m_sParamH263.nPFrames = (m_sOutPortFormat.xFramerate * 2 - 1);
+ 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;
+
+ m_state = OMX_StateLoaded;
+ m_sExtraData = 0;
+
+ m_capability.max_height = OMX_CORE_FWVGA_HEIGHT;
+ m_capability.max_width = OMX_CORE_FWVGA_WIDTH;
+ m_capability.min_height = 32;
+ m_capability.min_width = 32;
+
+ if (eRet == OMX_ErrorNone)
+ {
+ if (pipe(fds))
+ {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ if ((fds[0] == 0) || (fds[1] == 0))
+ {
+ if (pipe(fds))
+ {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ if (eRet == OMX_ErrorNone)
+ {
+ m_pipe_in = fds[0];
+ m_pipe_out = fds[1];
+ }
+ }
+
+ if (pthread_create(&msg_thread_id,0, message_thread_enc, this) < 0)
+ {
+ eRet = OMX_ErrorInsufficientResources;
+ msg_thread_created = false;
+ }
+ else
+ {
+ msg_thread_created = true;
+ }
+ }
+
+ DEBUG_PRINT_HIGH("Component_init return value = 0x%x", eRet);
+
+ EXIT_FUNC();
+
+ RETURN(eRet);
+}
+
+OMX_ERRORTYPE omx_venc::set_parameter
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_IN OMX_PTR paramData
+)
+{
+ ENTER_FUNC();
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_PROPERTY Prop;
+ bool bResult;
+ unsigned int stride, scanlines;
+
+ (void)hComp;
+
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State");
+ RETURN(OMX_ErrorInvalidState);
+ }
+ if (paramData == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
+ 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");
+ RETURN(OMX_ErrorIncorrectStateOperation);
+ }
+
+ switch ((int)paramIndex)
+ {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
+ (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");
+ omx_report_unsupported_setting();
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+ DEBUG_PRINT_LOW("i/p actual cnt requested = %u", portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("i/p min cnt requested = %u", portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("i/p buffersize requested = %u", portDefn->nBufferSize);
+ if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
+ {
+ DEBUG_PRINT_ERROR("ERROR: (In_PORT) Min buffers (%u) > actual count (%u)",
+ portDefn->nBufferCountMin, portDefn->nBufferCountActual);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ /* set the frame size */
+ Prop.id = SWVENC_PROPERTY_ID_FRAME_SIZE;
+ Prop.info.frame_size.height = portDefn->format.video.nFrameHeight;
+ Prop.info.frame_size.width = portDefn->format.video.nFrameWidth;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ /* set the input frame-rate */
+ if (portDefn->format.video.xFramerate != 0)
+ {
+ Ret = swvenc_set_frame_rate(portDefn->format.video.xFramerate >> 16);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+ }
+
+ /* set the frame attributes */
+ stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
+ scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nSliceHeight);
+ Prop.id = SWVENC_PROPERTY_ID_FRAME_ATTRIBUTES;
+ Prop.info.frame_attributes.stride_luma = stride;
+ Prop.info.frame_attributes.stride_chroma = stride;
+ Prop.info.frame_attributes.offset_luma = 0;
+ Prop.info.frame_attributes.offset_chroma = scanlines * stride;
+ Prop.info.frame_attributes.size =
+ VENUS_BUFFER_SIZE(COLOR_FMT_NV12,
+ portDefn->format.video.nFrameWidth,
+ portDefn->format.video.nFrameHeight);
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ DEBUG_PRINT_LOW("i/p previous actual cnt = %u", m_sInPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("i/p previous min cnt = %u", m_sInPortDef.nBufferCountMin);
+ DEBUG_PRINT_LOW("i/p previous buffersize = %u", m_sInPortDef.nBufferSize);
+
+ memcpy(&m_sInPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+
+ /* update the input buffer requirement */
+ Ret = swvenc_get_buffer_req(&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ &m_sInPortDef.nBufferAlignment,
+ portDefn->nPortIndex);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
+ Ret);
+ RETURN(OMX_ErrorUndefined);
+ }
+
+ if (portDefn->nBufferCountActual > m_sInPortDef.nBufferCountActual)
+ {
+ m_sInPortDef.nBufferCountActual = portDefn->nBufferCountActual;
+ }
+ if (portDefn->nBufferSize > m_sInPortDef.nBufferSize)
+ {
+ m_sInPortDef.nBufferSize = portDefn->nBufferSize;
+ }
+
+ DEBUG_PRINT_LOW("i/p new actual cnt = %u", m_sInPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("i/p new min cnt = %u", m_sInPortDef.nBufferCountMin);
+ DEBUG_PRINT_LOW("i/p new buffersize = %u", m_sInPortDef.nBufferSize);
+ }
+ else if (PORT_INDEX_OUT == portDefn->nPortIndex)
+ {
+ DEBUG_PRINT_LOW("o/p actual cnt requested = %u", portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("o/p min cnt requested = %u", portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("o/p buffersize requested = %u", portDefn->nBufferSize);
+ if (portDefn->nBufferCountMin > portDefn->nBufferCountActual)
+ {
+ DEBUG_PRINT_ERROR("ERROR: (Out_PORT) Min buffers (%u) > actual count (%u)",
+ portDefn->nBufferCountMin, portDefn->nBufferCountActual);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ /* set the output bit-rate */
+ Ret = swvenc_set_bit_rate(portDefn->format.video.nBitrate);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ DEBUG_PRINT_LOW("o/p previous actual cnt = %u", m_sOutPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("o/p previous min cnt = %u", m_sOutPortDef.nBufferCountMin);
+ DEBUG_PRINT_LOW("o/p previous buffersize = %u", m_sOutPortDef.nBufferSize);
+
+ /* set the buffer requirement */
+ bResult = dev_set_buf_req(&portDefn->nBufferCountMin,
+ &portDefn->nBufferCountActual,
+ &portDefn->nBufferSize,
+ portDefn->nPortIndex);
+ if (bResult != true)
+ {
+ DEBUG_PRINT_ERROR("%s, dev_set_buf_req failed",
+ __FUNCTION__);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+ memcpy(&m_sOutPortDef, portDefn,sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
+
+ /* update the output buffer requirement */
+ Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ &m_sOutPortDef.nBufferAlignment,
+ portDefn->nPortIndex);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
+ Ret);
+ RETURN(OMX_ErrorUndefined);
+ }
+
+ if (portDefn->nBufferCountActual > m_sOutPortDef.nBufferCountActual)
+ {
+ m_sOutPortDef.nBufferCountActual = portDefn->nBufferCountActual;
+ }
+ if (portDefn->nBufferSize > m_sOutPortDef.nBufferSize)
+ {
+ m_sOutPortDef.nBufferSize = portDefn->nBufferSize;
+ }
+
+ DEBUG_PRINT_LOW("o/p new actual cnt = %u", m_sOutPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("o/p new min cnt = %u", m_sOutPortDef.nBufferCountMin);
+ DEBUG_PRINT_LOW("o/p new buffersize = %u", m_sOutPortDef.nBufferSize);
+ }
+ 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",
+ portFmt->eColorFormat);
+ SWVENC_COLOR_FORMAT color_format;
+
+ /* set the driver with the corresponding values */
+ if (PORT_INDEX_IN == portFmt->nPortIndex)
+ {
+ if (portFmt->eColorFormat ==
+ ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatAndroidOpaque))
+ {
+ /* meta_mode = 2 (kMetadataBufferTypeGrallocSource) */
+ m_sInPortFormat.eColorFormat =
+ (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar;
+ color_format = SWVENC_COLOR_FORMAT_NV21;
+ if (!mUseProxyColorFormat)
+ {
+ if (!c2d_conv.init())
+ {
+ DEBUG_PRINT_ERROR("C2D init failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_ERROR("C2D init is successful");
+ }
+ mUseProxyColorFormat = true;
+ m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ;
+ }
+ else
+ {
+ m_sInPortFormat.eColorFormat = portFmt->eColorFormat;
+ if ((portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) ||
+ (portFmt->eColorFormat ==
+ ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)))
+ {
+ color_format = SWVENC_COLOR_FORMAT_NV12;
+ }
+ else if (portFmt->eColorFormat ==
+ ((OMX_COLOR_FORMATTYPE) QOMX_COLOR_FormatYVU420SemiPlanar))
+ {
+ color_format = SWVENC_COLOR_FORMAT_NV21;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat %d invalid",
+ __FUNCTION__,
+ portFmt->eColorFormat);
+ RETURN(OMX_ErrorBadParameter);
+ }
+ m_input_msg_id = OMX_COMPONENT_GENERATE_ETB;
+ mUseProxyColorFormat = false;
+ }
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
+ portFmt->eColorFormat);
+ m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
+ /* set the input color format */
+ Prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
+ Prop.info.color_format = color_format;
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ /* set the input frame-rate */
+ if (portFmt->xFramerate != 0)
+ {
+ Ret = swvenc_set_frame_rate(portFmt->xFramerate >> 16);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
+ __FUNCTION__, Ret);
+ //RETURN(OMX_ErrorUnsupportedSetting);
+ }
+ m_sInPortFormat.xFramerate = portFmt->xFramerate;
+ }
+ }
+ break;
+ }
+
+ case OMX_IndexParamVideoInit:
+ {
+ OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData);
+ DEBUG_PRINT_LOW("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 (m_max_allowed_bitrate_check)
+ {
+ //TBD: to add bitrate check
+ }
+
+ /* set the output bit-rate */
+ Ret = swvenc_set_bit_rate(pParam->nTargetBitrate);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ /* set the RC-mode */
+ Ret = swvenc_set_rc_mode(pParam->eControlRate);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ m_sParamBitrate.nTargetBitrate = pParam->nTargetBitrate;
+ m_sParamBitrate.eControlRate = pParam->eControlRate;
+ m_sConfigBitrate.nEncodeBitrate = pParam->nTargetBitrate;
+ m_sInPortDef.format.video.nBitrate = pParam->nTargetBitrate;
+ m_sOutPortDef.format.video.nBitrate = pParam->nTargetBitrate;
+ DEBUG_PRINT_LOW("bitrate = %u", m_sOutPortDef.format.video.nBitrate);
+ break;
+ }
+
+ case OMX_IndexParamVideoMpeg4:
+ {
+ OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
+
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4");
+
+ if (pParam->nBFrames)
+ {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported");
+ }
+
+ /* set the intra period */
+ Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
+ __FUNCTION__, Ret);
+ 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");
+
+ /* set the intra period */
+ Ret = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
+ __FUNCTION__, Ret);
+ 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_IndexParamVideoProfileLevelCurrent:
+ {
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoProfileLevelCurrent");
+
+ /* set the profile and level */
+ Ret = swvenc_set_profile_level(pParam->eProfile,pParam->eLevel);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_rc_mode failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+
+ m_sParamProfileLevel.eProfile = pParam->eProfile;
+ m_sParamProfileLevel.eLevel = pParam->eLevel;
+
+ if (SWVENC_CODEC_MPEG4 == m_codec)
+ {
+ m_sParamMPEG4.eProfile = (OMX_VIDEO_MPEG4PROFILETYPE)m_sParamProfileLevel.eProfile;
+ m_sParamMPEG4.eLevel = (OMX_VIDEO_MPEG4LEVELTYPE)m_sParamProfileLevel.eLevel;
+ DEBUG_PRINT_LOW("MPEG4 profile = %d, level = %d", m_sParamMPEG4.eProfile,
+ m_sParamMPEG4.eLevel);
+ }
+ else if (SWVENC_CODEC_H263 == m_codec)
+ {
+ m_sParamH263.eProfile = (OMX_VIDEO_H263PROFILETYPE)m_sParamProfileLevel.eProfile;
+ m_sParamH263.eLevel = (OMX_VIDEO_H263LEVELTYPE)m_sParamProfileLevel.eLevel;
+ DEBUG_PRINT_LOW("H263 profile = %d, level = %d", m_sParamH263.eProfile,
+ m_sParamH263.eLevel);
+ }
+ 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");
+ RETURN(OMX_ErrorIncorrectStateOperation);
+ }
+
+ if (SWVENC_CODEC_MPEG4 == m_codec)
+ {
+ 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", comp_role->cRole);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else if (SWVENC_CODEC_H263 == m_codec)
+ {
+ 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", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", 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");
+ RETURN(OMX_ErrorIncorrectStateOperation);
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
+ priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
+ 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",
+ bufferSupplierType->eBufferSupplier);
+ if ( (bufferSupplierType->nPortIndex == 0) ||
+ (bufferSupplierType->nPortIndex ==1)
+ )
+ {
+ m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
+ }
+ else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ break;
+
+ }
+
+ case OMX_IndexParamVideoQuantization:
+ {
+ // this is applicable only for RC-off case
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization");
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
+ if (session_qp->nPortIndex == PORT_INDEX_OUT)
+ {
+ Prop.id = SWVENC_PROPERTY_ID_QP;
+ Prop.info.qp.qp_i = session_qp->nQpI;
+ Prop.info.qp.qp_p = session_qp->nQpP;
+ Prop.info.qp.qp_b = session_qp->nQpB;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ m_sSessionQuantization.nQpI = session_qp->nQpI;
+ m_sSessionQuantization.nQpP = session_qp->nQpP;
+ m_sSessionQuantization.nQpB = session_qp->nQpB;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP setting");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoQPRange:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoQPRange");
+ OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData;
+ if (qp_range->nPortIndex == PORT_INDEX_OUT)
+ {
+ if ( (qp_range->minQP > 255) ||
+ (qp_range->maxQP > 255)
+ )
+ {
+ DEBUG_PRINT_ERROR("ERROR: Out of range QP");
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ Prop.id = SWVENC_PROPERTY_ID_QP_RANGE;
+ Prop.info.qp_range.min_qp_packed =
+ (qp_range->minQP << 16) | (qp_range->minQP) | (qp_range->minQP << 8);
+ Prop.info.qp_range.max_qp_packed =
+ (qp_range->maxQP << 16) | (qp_range->maxQP) | (qp_range->maxQP << 8);
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ m_sSessionQPRange.minQP= qp_range->minQP;
+ m_sSessionQPRange.maxQP= qp_range->maxQP;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for QP range setting");
+ 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");
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam =
+ (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
+
+ /* HEC */
+ if (m_codec == SWVENC_CODEC_MPEG4)
+ {
+ Prop.id = SWVENC_PROPERTY_ID_MPEG4_HEC;
+ Prop.info.mpeg4_hec = pParam->bEnableHEC;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUndefined);
+ }
+
+ /* Data partitioning */
+ Prop.id = SWVENC_PROPERTY_ID_MPEG4_DP;
+ Prop.info.mpeg4_dp = pParam->bEnableDataPartitioning;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUndefined);
+ }
+ }
+
+ /* RVLC */
+ if (pParam->bEnableRVLC)
+ {
+ DEBUG_PRINT_ERROR("%s, RVLC not support", __FUNCTION__);
+ }
+
+ /* Re-sync Marker */
+ Prop.id = SWVENC_PROPERTY_ID_SLICE_CONFIG;
+ if ( (m_codec != SWVENC_CODEC_H263) && (pParam->bEnableDataPartitioning) )
+ {
+ DEBUG_PRINT_ERROR("DataPartioning are not Supported for this codec");
+ break;
+ }
+ if ( (m_codec != SWVENC_CODEC_H263) && (pParam->nResynchMarkerSpacing) )
+ {
+ Prop.info.slice_config.mode = SWVENC_SLICE_MODE_BYTE;
+ Prop.info.slice_config.size = pParam->nResynchMarkerSpacing;
+ }
+ else if ( (SWVENC_CODEC_H263 == m_codec) && (pParam->bEnableResync) )
+ {
+ Prop.info.slice_config.mode = SWVENC_SLICE_MODE_GOB;
+ Prop.info.slice_config.size = 0;
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUndefined);
+ }
+ }
+ else
+ {
+ Prop.info.slice_config.mode = SWVENC_SLICE_MODE_OFF;
+ Prop.info.slice_config.size = 0;
+ }
+
+ memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection));
+ break;
+ }
+
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh");
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam =
+ (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
+
+ Ret = swvenc_set_intra_refresh(pParam);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_intra_refresh failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh));
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoMetaBufferMode:
+ {
+ StoreMetaDataInBuffersParams *pParam =
+ (StoreMetaDataInBuffersParams*)paramData;
+ DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoMetaBufferMode: "
+ "port_index = %u, meta_mode = %d", pParam->nPortIndex, pParam->bStoreMetaData);
+
+ if (pParam->nPortIndex == PORT_INDEX_IN)
+ {
+ if (pParam->bStoreMetaData != meta_mode_enable)
+ {
+ meta_mode_enable = pParam->bStoreMetaData;
+ if (!meta_mode_enable)
+ {
+ Ret = swvenc_get_buffer_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ &m_sOutPortDef.nBufferAlignment,
+ m_sOutPortDef.nPortIndex);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, swvenc_get_buffer_req failed (%d)", __FUNCTION__,
+ Ret);
+ eRet = OMX_ErrorUndefined;
+ break;
+ }
+ }
+ }
+ }
+ else if (pParam->nPortIndex == PORT_INDEX_OUT && secure_session)
+ {
+ if (pParam->bStoreMetaData != meta_mode_enable)
+ {
+ meta_mode_enable = pParam->bStoreMetaData;
+ }
+ }
+ else
+ {
+ if (pParam->bStoreMetaData)
+ {
+ DEBUG_PRINT_ERROR("set_parameter: metamode is "
+ "valid for input port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ }
+ break;
+
+ case OMX_QcomIndexParamIndexExtraDataType:
+ {
+ DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType");
+ QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
+ OMX_U32 mask = 0;
+
+ if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
+ {
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ mask = VEN_EXTRADATA_SLICEINFO;
+
+ DEBUG_PRINT_HIGH("SliceInfo extradata %s",
+ ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("set_parameter: Slice information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+ else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo)
+ {
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ mask = VEN_EXTRADATA_MBINFO;
+
+ DEBUG_PRINT_HIGH("MBInfo extradata %s",
+ ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("set_parameter: MB information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)",
+ pParam->nIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+
+ if (pParam->bEnabled == OMX_TRUE)
+ {
+ m_sExtraData |= mask;
+ }
+ else
+ {
+ m_sExtraData &= ~mask;
+ }
+
+ #if 0
+ // TBD: add setprop to swvenc once the support is added
+ if (handle->venc_set_param((OMX_PTR)!!(m_sExtraData & mask),
+ (OMX_INDEXTYPE)pParam->nIndex) != true)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting Extradata (%x) failed", pParam->nIndex);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+ else
+ #endif
+ {
+ m_sOutPortDef.nPortIndex = PORT_INDEX_OUT;
+ bResult = dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+ if (false == bResult)
+ {
+ DEBUG_PRINT_ERROR("dev_get_buf_req failed");
+ eRet = OMX_ErrorUndefined;
+ break;
+ }
+
+ DEBUG_PRINT_HIGH("updated out_buf_req: buffer cnt=%u, "
+ "count min=%u, buffer size=%u",
+ m_sOutPortDef.nBufferCountActual,
+ m_sOutPortDef.nBufferCountMin,
+ m_sOutPortDef.nBufferSize);
+ }
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck:
+ {
+ QOMX_EXTNINDEX_PARAMTYPE* pParam =
+ (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ 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(%u)", pParam->nPortIndex);
+ RETURN(OMX_ErrorBadPortIndex);
+ }
+ break;
+ }
+
+ case OMX_QcomIndexEnableSliceDeliveryMode:
+ {
+ QOMX_EXTNINDEX_PARAMTYPE* pParam =
+ (QOMX_EXTNINDEX_PARAMTYPE*)paramData;
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ //TBD: add setprop to swvenc once the support is added
+ #if 0
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting slice delivery mode failed");
+ RETURN( OMX_ErrorUnsupportedSetting;
+ }
+ #endif
+ {
+ 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(%u)", 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)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed");
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexEnableH263PlusPType "
+ "called on wrong port(%u)", pParam->nPortIndex);
+ RETURN(OMX_ErrorBadPortIndex);
+ }
+ break;
+ }
+
+ case OMX_QcomIndexParamPeakBitrate:
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting peak bitrate");
+ RETURN(OMX_ErrorUnsupportedSetting);
+ break;
+ }
+
+ case QOMX_IndexParamVideoInitialQp:
+ {
+ // TBD: applicable to RC-on case only
+ DEBUG_PRINT_ERROR("ERROR: Setting Initial QP for RC-on case");
+ RETURN(OMX_ErrorNone);
+ break;
+ }
+
+
+ case OMX_QcomIndexParamSetMVSearchrange:
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setting Searchrange");
+ RETURN(OMX_ErrorUnsupportedSetting);
+ break;
+ }
+
+ default:
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+
+ RETURN(eRet);
+}
+
+OMX_ERRORTYPE omx_venc::set_config
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_IN OMX_PTR configData
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS SwStatus;
+
+ (void)hComp;
+
+ 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);
+ }
+
+ switch ((int)configIndex)
+ {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE* pParam =
+ reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", pParam->nEncodeBitrate);
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ SwStatus = swvenc_set_bit_rate(pParam->nEncodeBitrate);
+ if (SwStatus != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_bit_rate failed (%d)",
+ __FUNCTION__, SwStatus);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ m_sConfigBitrate.nEncodeBitrate = pParam->nEncodeBitrate;
+ m_sParamBitrate.nTargetBitrate = pParam->nEncodeBitrate;
+ m_sOutPortDef.format.video.nBitrate = pParam->nEncodeBitrate;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ RETURN(OMX_ErrorBadPortIndex);
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", pParam->xEncodeFramerate);
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ SwStatus = swvenc_set_frame_rate(pParam->xEncodeFramerate >> 16);
+ if (SwStatus != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_frame_rate failed (%d)",
+ __FUNCTION__, SwStatus);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ m_sConfigFramerate.xEncodeFramerate = pParam->xEncodeFramerate;
+ m_sOutPortDef.format.video.xFramerate = pParam->xEncodeFramerate;
+ m_sOutPortFormat.xFramerate = pParam->xEncodeFramerate;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ RETURN(OMX_ErrorBadPortIndex);
+ }
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ QOMX_VIDEO_INTRAPERIODTYPE* pParam =
+ reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): QOMX_IndexConfigVideoIntraperiod");
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+ if (pParam->nBFrames > 0)
+ {
+ DEBUG_PRINT_ERROR("B frames not supported");
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ DEBUG_PRINT_HIGH("Old: P/B frames = %u/%u, New: P/B frames = %u/%u",
+ 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);
+ }
+
+ /* set the intra period */
+ SwStatus = swvenc_set_intra_period(pParam->nPFrames,pParam->nBFrames);
+ if (SwStatus != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_set_intra_period failed (%d)",
+ __FUNCTION__, SwStatus);
+ 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
+ {
+ DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", pParam->nPortIndex);
+ RETURN(OMX_ErrorBadPortIndex);
+ }
+
+ break;
+ }
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoIntraVOPRefresh");
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT)
+ {
+
+ SWVENC_PROPERTY Prop;
+
+ Prop.id = SWVENC_PROPERTY_ID_IFRAME_REQUEST;
+
+ SwStatus = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (SwStatus != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, SwStatus);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+
+ m_sConfigIntraRefreshVOP.IntraRefreshVOP = pParam->IntraRefreshVOP;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", pParam->nPortIndex);
+ RETURN(OMX_ErrorBadPortIndex);
+ }
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ DEBUG_PRINT_ERROR("ERROR: OMX_IndexConfigCommonRotate not supported");
+ RETURN(OMX_ErrorUnsupportedSetting);
+ break;
+ }
+ default:
+ DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ break;
+ }
+
+ EXIT_FUNC();
+
+ RETURN(OMX_ErrorNone);
+}
+
+OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ ENTER_FUNC();
+
+ OMX_U32 i = 0;
+ DEBUG_PRINT_HIGH("omx_venc(): Inside component_deinit()");
+
+ (void)hComp;
+
+ if (OMX_StateLoaded != m_state)
+ {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",
+ m_state);
+ }
+ if (m_out_mem_ptr)
+ {
+ DEBUG_PRINT_LOW("Freeing the Output Memory");
+ 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 && !meta_mode_enable )
+ {
+ DEBUG_PRINT_LOW("Freeing the Input Memory");
+ for (i=0; i<m_sInPortDef.nBufferCountActual; i++)
+ {
+ free_input_buffer (&m_inp_mem_ptr[i]);
+ }
+
+ free(m_inp_mem_ptr);
+ m_inp_mem_ptr = NULL;
+ }
+
+ /* Reset counters in msg queues */
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+
+ /* Clear the strong reference */
+ DEBUG_PRINT_HIGH("Calling m_heap_ptr.clear()");
+ m_heap_ptr.clear();
+
+ DEBUG_PRINT_HIGH("Calling swvenc_deinit()");
+ swvenc_deinit(m_hSwVenc);
+
+ DEBUG_PRINT_HIGH("OMX_Venc:Component Deinit");
+
+ RETURN(OMX_ErrorNone);
+}
+
+OMX_U32 omx_venc::dev_stop(void)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret;
+
+ if (false == m_stopped)
+ {
+ Ret = swvenc_stop(m_hSwVenc);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_stop failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(-1);
+ }
+ format_set = false;
+ m_stopped = true;
+
+ /* post STOP_DONE event as start is synchronus */
+ post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_STOP_DONE);
+ }
+
+ RETURN(0);
+}
+
+OMX_U32 omx_venc::dev_pause(void)
+{
+ ENTER_FUNC();
+ // nothing to be done for sw encoder
+
+ RETURN(true);
+}
+
+OMX_U32 omx_venc::dev_resume(void)
+{
+ ENTER_FUNC();
+ // nothing to be done for sw encoder
+
+ RETURN(true);
+}
+
+OMX_U32 omx_venc::dev_start(void)
+{
+ ENTER_FUNC();
+ SWVENC_STATUS Ret;
+ Ret = swvenc_start(m_hSwVenc);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_start failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(-1);
+ }
+
+ m_stopped = false;
+
+ RETURN(0);
+}
+
+OMX_U32 omx_venc::dev_flush(unsigned port)
+{
+ ENTER_FUNC();
+ SWVENC_STATUS Ret;
+
+ (void)port;
+ Ret = swvenc_flush(m_hSwVenc);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_flush failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(-1);
+ }
+
+ RETURN(0);
+}
+
+OMX_U32 omx_venc::dev_start_done(void)
+{
+ ENTER_FUNC();
+
+ /* post START_DONE event as start is synchronus */
+ post_event (0, OMX_ErrorNone, OMX_COMPONENT_GENERATE_START_DONE);
+
+ RETURN(0);
+}
+
+OMX_U32 omx_venc::dev_set_message_thread_id(pthread_t tid)
+{
+ ENTER_FUNC();
+
+ // nothing to be done for sw encoder
+ (void)tid;
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_use_buf(void *buf_addr,unsigned port,unsigned index)
+{
+ ENTER_FUNC();
+
+ (void)buf_addr;
+ (void)port;
+ (void)index;
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_free_buf(void *buf_addr,unsigned port)
+{
+ ENTER_FUNC();
+
+ (void)buf_addr;
+ (void)port;
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_empty_buf
+(
+ void *buffer,
+ void *pmem_data_buf,
+ unsigned index,
+ unsigned fd
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret;
+ SWVENC_IPBUFFER ipbuffer;
+ OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+ unsigned int size = 0, filled_length, offset = 0;
+ SWVENC_COLOR_FORMAT color_format;
+ SWVENC_PROPERTY prop;
+
+ (void)pmem_data_buf;
+ (void)index;
+
+ if (meta_mode_enable)
+ {
+ LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
+ meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
+ if(!meta_buf)
+ {
+ if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS))
+ {
+ ipbuffer.p_buffer= bufhdr->pBuffer;
+ ipbuffer.size = bufhdr->nAllocLen;
+ ipbuffer.filled_length = bufhdr->nFilledLen;
+ DEBUG_PRINT_LOW("dev_empty_buf: empty EOS buffer");
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
+ {
+ offset = meta_buf->meta_handle->data[1];
+ size = meta_buf->meta_handle->data[2];
+ if (!format_set &&
+ (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 5))
+ {
+ format_set = true;
+ if (((OMX_COLOR_FORMATTYPE) meta_buf->meta_handle->data[5]) !=
+ m_sInPortFormat.eColorFormat)
+ {
+ return false;
+ }
+ }
+ ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
+ if (ipbuffer.p_buffer == MAP_FAILED)
+ {
+ DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
+ RETURN(OMX_ErrorBadParameter);
+ }
+ ipbuffer.size = size;
+ ipbuffer.filled_length = size;
+ }
+ else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
+ {
+ VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)bufhdr->pBuffer;
+ private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
+ size = handle->size;
+ if(!format_set)
+ {
+ format_set = true;
+ DEBUG_PRINT_LOW("color format = 0x%x",handle->format);
+ if (((OMX_COLOR_FORMATTYPE)handle->format) != m_sInPortFormat.eColorFormat)
+ {
+ if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
+ {
+ m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ color_format = SWVENC_COLOR_FORMAT_NV12;
+ m_sInPortDef.format.video.eColorFormat = m_sInPortFormat.eColorFormat;
+ prop.id = SWVENC_PROPERTY_ID_COLOR_FORMAT;
+ prop.info.color_format = color_format;
+ Ret = swvenc_setproperty(m_hSwVenc, &prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(OMX_ErrorUnsupportedSetting);
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("%s: OMX_IndexParamVideoPortFormat 0x%x invalid",
+ __FUNCTION__,handle->format);
+ RETURN(OMX_ErrorBadParameter);
+ }
+ }
+ }
+ ipbuffer.p_buffer = (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, offset);
+ if (ipbuffer.p_buffer == MAP_FAILED)
+ {
+ DEBUG_PRINT_ERROR("mmap() failed for fd %d of size %d",fd,size);
+ RETURN(OMX_ErrorBadParameter);
+ }
+ ipbuffer.size = size;
+ ipbuffer.filled_length = size;
+ }
+ else
+ {
+ //handles the use case for surface encode
+ ipbuffer.p_buffer = bufhdr->pBuffer;
+ ipbuffer.size = bufhdr->nAllocLen;
+ ipbuffer.filled_length = bufhdr->nFilledLen;
+ }
+ }
+ }
+ else
+ {
+ ipbuffer.p_buffer = bufhdr->pBuffer;
+ ipbuffer.size = bufhdr->nAllocLen;
+ ipbuffer.filled_length = bufhdr->nFilledLen;
+ }
+ ipbuffer.flags = 0;
+ if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ ipbuffer.flags |= SWVENC_FLAG_EOS;
+ }
+ ipbuffer.timestamp = bufhdr->nTimeStamp;
+ ipbuffer.p_client_data = (unsigned char *)bufhdr;
+
+ DEBUG_PRINT_LOW("ETB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
+ ipbuffer.p_buffer,
+ ipbuffer.size,
+ ipbuffer.filled_length,
+ (unsigned int)ipbuffer.flags,
+ ipbuffer.timestamp,
+ ipbuffer.p_client_data);
+
+ Ret = swvenc_emptythisbuffer(m_hSwVenc, &ipbuffer);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_emptythisbuffer failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(false);
+ }
+
+ if (m_debug.in_buffer_log)
+ {
+ swvenc_input_log_buffers((const char*)ipbuffer.p_buffer, ipbuffer.filled_length);
+ }
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_fill_buf
+(
+ void *buffer,
+ void *pmem_data_buf,
+ unsigned index,
+ unsigned fd
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret;
+
+ SWVENC_OPBUFFER opbuffer;
+ OMX_BUFFERHEADERTYPE *bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+ (void)pmem_data_buf;
+ (void)index;
+ (void)fd;
+
+ opbuffer.p_buffer = bufhdr->pBuffer;
+ opbuffer.size = bufhdr->nAllocLen;
+ opbuffer.filled_length = bufhdr->nFilledLen;
+ opbuffer.flags = bufhdr->nFlags;
+ opbuffer.p_client_data = (unsigned char *)bufhdr;
+
+ DEBUG_PRINT_LOW("FTB: p_buffer (%p) size (%d) filled_len (%d) flags (0x%X) timestamp (%lld) clientData (%p)",
+ opbuffer.p_buffer,
+ opbuffer.size,
+ opbuffer.filled_length,
+ opbuffer.flags,
+ opbuffer.timestamp,
+ opbuffer.p_client_data);
+
+ if ( false == m_bSeqHdrRequested)
+ {
+ if (dev_get_seq_hdr(opbuffer.p_buffer, opbuffer.size, &opbuffer.filled_length) == 0)
+ {
+ bufhdr->nFilledLen = opbuffer.filled_length;
+ bufhdr->nOffset = 0;
+ bufhdr->nTimeStamp = 0;
+ bufhdr->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
+
+ DEBUG_PRINT_LOW("sending FBD with codec config");
+ m_bSeqHdrRequested = true;
+ post_event ((unsigned long)bufhdr,0,OMX_COMPONENT_GENERATE_FBD);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: couldn't get sequence header");
+ post_event(OMX_EventError,OMX_ErrorUndefined,OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ else
+ {
+ Ret = swvenc_fillthisbuffer(m_hSwVenc, &opbuffer);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_fillthisbuffer failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(false);
+ }
+ }
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_get_seq_hdr
+(
+ void *buffer,
+ unsigned size,
+ unsigned *hdrlen
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret;
+ SWVENC_OPBUFFER Buffer;
+
+ Buffer.p_buffer = (unsigned char*) buffer;
+ Buffer.size = size;
+
+ Ret = swvenc_getsequenceheader(m_hSwVenc, &Buffer);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_flush failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(-1);
+ }
+
+ *hdrlen = Buffer.filled_length;
+
+ RETURN(0);
+}
+
+bool omx_venc::dev_get_capability_ltrcount
+(
+ OMX_U32 *min,
+ OMX_U32 *max,
+ OMX_U32 *step_size
+)
+{
+ ENTER_FUNC();
+
+ (void)min;
+ (void)max;
+ (void)step_size;
+
+ DEBUG_PRINT_ERROR("Get Capability LTR Count is not supported");
+
+ RETURN(false);
+}
+
+bool omx_venc::dev_get_performance_level(OMX_U32 *perflevel)
+{
+ ENTER_FUNC();
+
+ (void)perflevel;
+ DEBUG_PRINT_ERROR("Get performance level is not supported");
+
+ RETURN(false);
+}
+
+bool omx_venc::dev_get_vui_timing_info(OMX_U32 *enabled)
+{
+ ENTER_FUNC();
+
+ (void)enabled;
+ DEBUG_PRINT_ERROR("Get vui timing information is not supported");
+
+ RETURN(false);
+}
+
+bool omx_venc::dev_get_vqzip_sei_info(OMX_U32 *enabled)
+{
+ ENTER_FUNC();
+
+ (void)enabled;
+ DEBUG_PRINT_ERROR("Get vqzip sei info is not supported");
+
+ RETURN(false);
+}
+
+bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
+{
+ //TBD: store the peak bitrate in class and return here;
+ ENTER_FUNC();
+
+ (void)peakbitrate;
+ DEBUG_PRINT_ERROR("Get peak bitrate is not supported");
+
+ RETURN(false);
+}
+
+bool omx_venc::dev_get_batch_size(OMX_U32 *size)
+{
+ ENTER_FUNC();
+
+ (void)size;
+
+ DEBUG_PRINT_ERROR("Get batch size is not supported");
+
+ RETURN(false);
+}
+
+bool omx_venc::dev_loaded_start()
+{
+ ENTER_FUNC();
+ RETURN(true);
+}
+
+bool omx_venc::dev_loaded_stop()
+{
+ ENTER_FUNC();
+ RETURN(true);
+}
+
+bool omx_venc::dev_loaded_start_done()
+{
+ ENTER_FUNC();
+ RETURN(true);
+}
+
+bool omx_venc::dev_loaded_stop_done()
+{
+ ENTER_FUNC();
+ RETURN(true);
+}
+
+bool omx_venc::dev_get_buf_req(OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 port)
+{
+ ENTER_FUNC();
+
+ bool bRet = true;
+ OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
+
+ if (PORT_INDEX_IN == port)
+ {
+ PortDef = &m_sInPortDef;
+ }
+ else if (PORT_INDEX_OUT == port)
+ {
+ PortDef = &m_sOutPortDef;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
+ bRet = false;
+ }
+
+ if (true == bRet)
+ {
+ *min_buff_count = PortDef->nBufferCountMin;
+ *actual_buff_count = PortDef->nBufferCountActual;
+ *buff_size = PortDef->nBufferSize;
+ }
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_set_buf_req
+(
+ OMX_U32 const *min_buff_count,
+ OMX_U32 const *actual_buff_count,
+ OMX_U32 const *buff_size,
+ OMX_U32 port
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret;
+ OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
+
+ (void)min_buff_count;
+ if (PORT_INDEX_IN == port)
+ {
+ PortDef = &m_sInPortDef;
+ }
+ else if (PORT_INDEX_OUT == port)
+ {
+ PortDef = &m_sOutPortDef;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
+ RETURN(false);
+ }
+
+ if (*actual_buff_count < PortDef->nBufferCountMin)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, (actual,min) buffer count (%d, %d)",
+ __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
+ RETURN(false);
+ }
+ if (false == meta_mode_enable)
+ {
+ if (*buff_size < PortDef->nBufferSize)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, (new,old) buffer count (%d, %d)",
+ __FUNCTION__, *actual_buff_count, PortDef->nBufferCountMin);
+ RETURN(false);
+ }
+ }
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_is_video_session_supported(OMX_U32 width, OMX_U32 height)
+{
+ ENTER_FUNC();
+
+ if ( (width * height < m_capability.min_width * m_capability.min_height) ||
+ (width * height > m_capability.max_width * m_capability.max_height)
+ )
+ {
+ DEBUG_PRINT_ERROR(
+ "Unsupported Resolution WxH = (%u)x(%u) Supported Range = min (%d)x(%d) - max (%d)x(%d)",
+ width, height,
+ m_capability.min_width, m_capability.min_height,
+ m_capability.max_width, m_capability.max_height);
+ RETURN(false);
+ }
+
+ RETURN(true);
+}
+
+bool omx_venc::dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer)
+{
+ ENTER_FUNC();
+
+ (void)buffer;
+ RETURN(true);
+}
+int omx_venc::dev_handle_output_extradata(void *buffer, int fd)
+{
+ ENTER_FUNC();
+
+ (void)buffer;
+ (void)fd;
+
+ RETURN(true);
+}
+
+int omx_venc::dev_handle_input_extradata(void *buffer, int fd, int index)
+{
+ ENTER_FUNC();
+
+ (void)buffer;
+ (void)fd;
+ (void)index;
+
+ RETURN(true);
+}
+
+void omx_venc::dev_set_extradata_cookie(void *buffer)
+{
+ ENTER_FUNC();
+
+ (void)buffer;
+}
+
+int omx_venc::dev_set_format(int color)
+{
+ ENTER_FUNC();
+
+ (void)color;
+
+ RETURN(true);
+ //return handle->venc_set_format(color);
+}
+
+bool omx_venc::dev_color_align(OMX_BUFFERHEADERTYPE *buffer,
+ OMX_U32 width, OMX_U32 height)
+{
+ ENTER_FUNC();
+
+ (void)buffer;
+ (void)width;
+ (void)height;
+ if(secure_session) {
+ DEBUG_PRINT_ERROR("Cannot align colors in secure session.");
+ RETURN(OMX_FALSE);
+ }
+
+ RETURN(true);
+ //return handle->venc_color_align(buffer, width,height);
+}
+
+bool omx_venc::is_secure_session()
+{
+ ENTER_FUNC();
+
+ RETURN(secure_session);
+}
+
+bool omx_venc::dev_get_output_log_flag()
+{
+ ENTER_FUNC();
+
+ RETURN(m_debug.out_buffer_log == 1);
+}
+
+int omx_venc::dev_output_log_buffers(const char *buffer, int bufferlen)
+{
+ ENTER_FUNC();
+
+ if (m_debug.out_buffer_log && !m_debug.outfile)
+ {
+ int size = 0;
+ int width = m_sInPortDef.format.video.nFrameWidth;
+ int height = m_sInPortDef.format.video.nFrameHeight;
+ if(SWVENC_CODEC_MPEG4 == m_codec)
+ {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
+ "%s/output_enc_%d_%d_%p.m4v",
+ m_debug.log_loc, width, height, this);
+ }
+ else if(SWVENC_CODEC_H263 == m_codec)
+ {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX,
+ "%s/output_enc_%d_%d_%p.263",
+ m_debug.log_loc, width, height, this);
+ }
+ if ((size > PROPERTY_VALUE_MAX) || (size < 0))
+ {
+ DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d",
+ m_debug.outfile_name, size);
+ RETURN(-1);
+ }
+ DEBUG_PRINT_LOW("output filename = %s", m_debug.outfile_name);
+ m_debug.outfile = fopen(m_debug.outfile_name, "ab");
+ if (!m_debug.outfile)
+ {
+ DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
+ m_debug.outfile_name, errno);
+ m_debug.outfile_name[0] = '\0';
+ RETURN(-1);
+ }
+ }
+ if (m_debug.outfile && buffer && bufferlen)
+ {
+ DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
+ fwrite(buffer, bufferlen, 1, m_debug.outfile);
+ }
+
+ RETURN(0);
+}
+
+int omx_venc::swvenc_input_log_buffers(const char *buffer, int bufferlen)
+{
+ int width = m_sInPortDef.format.video.nFrameWidth;
+ int height = m_sInPortDef.format.video.nFrameHeight;
+ int stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width);
+ int scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height);
+ char *temp = (char*)buffer;
+
+ if (!m_debug.infile)
+ {
+ int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX,
+ "%s/input_enc_%d_%d_%p.yuv",
+ m_debug.log_loc, width, height, this);
+ if ((size > PROPERTY_VALUE_MAX) || (size < 0))
+ {
+ DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d",
+ m_debug.infile_name, size);
+ RETURN(-1);
+ }
+ DEBUG_PRINT_LOW("input filename = %s", m_debug.infile_name);
+ m_debug.infile = fopen (m_debug.infile_name, "ab");
+ if (!m_debug.infile)
+ {
+ DEBUG_PRINT_HIGH("Failed to open input file: %s for logging",
+ m_debug.infile_name);
+ m_debug.infile_name[0] = '\0';
+ RETURN(-1);
+ }
+ }
+ if (m_debug.infile && buffer && bufferlen)
+ {
+ DEBUG_PRINT_LOW("%s buffer length: %d", __func__, bufferlen);
+ for (int i = 0; i < height; i++)
+ {
+ fwrite(temp, width, 1, m_debug.infile);
+ temp += stride;
+ }
+ for(int i = 0; i < height/2; i++)
+ {
+ fwrite(temp, width, 1, m_debug.infile);
+ temp += stride;
+ }
+ }
+
+ RETURN(0);
+}
+
+int omx_venc::dev_extradata_log_buffers(char *buffer)
+{
+ ENTER_FUNC();
+
+ (void)buffer;
+
+ RETURN(true);
+ //return handle->venc_extradata_log_buffers(buffer);
+}
+
+SWVENC_STATUS omx_venc::swvenc_get_buffer_req
+(
+ OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 *buff_alignment,
+ OMX_U32 port
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_PROPERTY Prop;
+ SWVENC_STATUS Ret;
+ OMX_PARAM_PORTDEFINITIONTYPE *PortDef;
+
+ Prop.id = SWVENC_PROPERTY_ID_BUFFER_REQ;
+ if (PORT_INDEX_IN == port)
+ {
+ Prop.info.buffer_req.type = SWVENC_BUFFER_INPUT;
+ }
+ else if (PORT_INDEX_OUT == port)
+ {
+ Prop.info.buffer_req.type = SWVENC_BUFFER_OUTPUT;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, Unsupported parameter", __FUNCTION__);
+ RETURN(SWVENC_S_INVALID_PARAMETERS);
+ }
+
+ Ret = swvenc_getproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s, swvenc_setproperty failed (%d)", __FUNCTION__,
+ Ret);
+ RETURN(SWVENC_S_INVALID_PARAMETERS);
+ }
+
+ *buff_size = Prop.info.buffer_req.size;
+ *min_buff_count = Prop.info.buffer_req.mincount;
+ *actual_buff_count = Prop.info.buffer_req.mincount;
+ *buff_alignment = Prop.info.buffer_req.alignment;
+
+ RETURN(Ret);
+}
+
+SWVENC_STATUS omx_venc::swvenc_empty_buffer_done_cb
+(
+ SWVENC_HANDLE swvenc,
+ SWVENC_IPBUFFER *p_ipbuffer,
+ void *p_client
+)
+{
+ ENTER_FUNC();
+
+ (void)swvenc;
+ SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
+ omx_venc *omx = reinterpret_cast<omx_venc*>(p_client);
+
+ if (p_ipbuffer == NULL)
+ {
+ eRet = SWVENC_S_FAILURE;
+ }
+ else
+ {
+ omx->swvenc_empty_buffer_done(p_ipbuffer);
+ }
+ return eRet;
+}
+
+SWVENC_STATUS omx_venc::swvenc_empty_buffer_done
+(
+ SWVENC_IPBUFFER *p_ipbuffer
+)
+{
+ SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
+ OMX_ERRORTYPE error = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE* omxhdr = NULL;
+
+ //omx_video *omx = reinterpret_cast<omx_video*>(p_client);
+ omxhdr = (OMX_BUFFERHEADERTYPE*)p_ipbuffer->p_client_data;
+
+ DEBUG_PRINT_LOW("EBD: clientData (%p)", p_ipbuffer->p_client_data);
+
+ if ( (omxhdr == NULL) ||
+ ( ((OMX_U32)(omxhdr - m_inp_mem_ptr) >m_sInPortDef.nBufferCountActual) &&
+ ((OMX_U32)(omxhdr - meta_buffer_hdr) >m_sInPortDef.nBufferCountActual)
+ )
+ )
+ {
+ omxhdr = NULL;
+ error = OMX_ErrorUndefined;
+ }
+
+ if (omxhdr != NULL)
+ {
+ // unmap the input buffer->pBuffer
+ omx_release_meta_buffer(omxhdr);
+#ifdef _ANDROID_ICS_
+ if (meta_mode_enable)
+ {
+ LEGACY_CAM_METADATA_TYPE *meta_buf = NULL;
+ unsigned int size = 0;
+ meta_buf = (LEGACY_CAM_METADATA_TYPE *)omxhdr->pBuffer;
+ if (meta_buf)
+ {
+ if (meta_buf->buffer_type == LEGACY_CAM_SOURCE)
+ {
+ size = meta_buf->meta_handle->data[2];
+ }
+ else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource)
+ {
+ VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)omxhdr->pBuffer;
+ private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
+ size = handle->size;
+ }
+ }
+ int status = munmap(p_ipbuffer->p_buffer, size);
+ DEBUG_PRINT_HIGH("Unmapped pBuffer <%p> size <%d> status <%d>", p_ipbuffer->p_buffer, size, status);
+ }
+#endif
+ post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_EBD);
+ }
+
+ RETURN(eRet);
+}
+
+SWVENC_STATUS omx_venc::swvenc_fill_buffer_done_cb
+(
+ SWVENC_HANDLE swvenc,
+ SWVENC_OPBUFFER *p_opbuffer,
+ void *p_client
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
+ OMX_ERRORTYPE error = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE* omxhdr = NULL;
+ omx_video *omx = reinterpret_cast<omx_video*>(p_client);
+
+ (void)swvenc;
+
+ if (p_opbuffer != NULL)
+ {
+ omxhdr = (OMX_BUFFERHEADERTYPE*)p_opbuffer->p_client_data;
+ }
+
+ if ( (p_opbuffer != NULL) &&
+ ((OMX_U32)(omxhdr - omx->m_out_mem_ptr) < omx->m_sOutPortDef.nBufferCountActual)
+ )
+ {
+ DEBUG_PRINT_LOW("FBD: clientData (%p) buffer (%p) filled_lengh (%d) flags (0x%x) ts (%lld)",
+ p_opbuffer->p_client_data,
+ p_opbuffer->p_buffer,
+ p_opbuffer->filled_length,
+ p_opbuffer->flags,
+ p_opbuffer->timestamp);
+
+ if (p_opbuffer->filled_length <= omxhdr->nAllocLen)
+ {
+ omxhdr->pBuffer = p_opbuffer->p_buffer;
+ omxhdr->nFilledLen = p_opbuffer->filled_length;
+ omxhdr->nOffset = 0;
+ omxhdr->nTimeStamp = p_opbuffer->timestamp;
+ omxhdr->nFlags = 0;
+ if (SWVENC_FRAME_TYPE_I == p_opbuffer->frame_type)
+ {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+ }
+ if (SWVENC_FLAG_EOS & p_opbuffer->flags)
+ {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+ if(omxhdr->nFilledLen)
+ {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ }
+ DEBUG_PRINT_LOW("o/p flag = 0x%x", omxhdr->nFlags);
+
+ /* Use buffer case */
+ if (omx->output_use_buffer && !omx->m_use_output_pmem)
+ {
+ DEBUG_PRINT_LOW("memcpy() for o/p Heap UseBuffer");
+ memcpy( omxhdr->pBuffer,
+ (p_opbuffer->p_buffer),
+ p_opbuffer->filled_length );
+ }
+ }
+ else
+ {
+ omxhdr->nFilledLen = 0;
+ }
+
+ }
+ else
+ {
+ omxhdr = NULL;
+ error = OMX_ErrorUndefined;
+ }
+
+ omx->post_event ((unsigned long)omxhdr,error,OMX_COMPONENT_GENERATE_FBD);
+
+ RETURN(eRet);
+}
+
+SWVENC_STATUS omx_venc::swvenc_handle_event_cb
+(
+ SWVENC_HANDLE swvenc,
+ SWVENC_EVENT event,
+ void *p_client
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS eRet = SWVENC_S_SUCCESS;
+ omx_video *omx = reinterpret_cast<omx_video*>(p_client);
+
+ OMX_BUFFERHEADERTYPE* omxhdr = NULL;
+
+ (void)swvenc;
+
+ if (omx == NULL || p_client == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR: %s invalid i/p params", __FUNCTION__);
+ RETURN(SWVENC_S_NULL_POINTER);
+ }
+
+ DEBUG_PRINT_LOW("swvenc_handle_event_cb - event = %d", event);
+
+ switch (event)
+ {
+ case SWVENC_EVENT_FLUSH_DONE:
+ {
+ DEBUG_PRINT_ERROR("SWVENC_EVENT_FLUSH_DONE input_flush_progress %d output_flush_progress %d",
+ omx->input_flush_progress, omx->output_flush_progress);
+ if (omx->input_flush_progress)
+ {
+ omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
+ }
+ if (omx->output_flush_progress)
+ {
+ omx->post_event ((unsigned)NULL, SWVENC_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
+ }
+ break;
+ }
+
+ case SWVENC_EVENT_FATAL_ERROR:
+ {
+ DEBUG_PRINT_ERROR("ERROR: SWVENC_EVENT_FATAL_ERROR");
+ omx->omx_report_error();
+ break;
+ }
+
+ default:
+ DEBUG_PRINT_HIGH("Unknown event received : %d", event);
+ break;
+ }
+
+ RETURN(eRet);
+}
+
+SWVENC_STATUS omx_venc::swvenc_set_rc_mode
+(
+ OMX_VIDEO_CONTROLRATETYPE eControlRate
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_RC_MODE rc_mode;
+ SWVENC_PROPERTY Prop;
+
+ switch (eControlRate)
+ {
+ case OMX_Video_ControlRateDisable:
+ rc_mode = SWVENC_RC_MODE_NONE;
+ break;
+ case OMX_Video_ControlRateVariableSkipFrames:
+ rc_mode = SWVENC_RC_MODE_VBR_VFR;
+ break;
+ case OMX_Video_ControlRateVariable:
+ rc_mode = SWVENC_RC_MODE_VBR_CFR;
+ break;
+ case OMX_Video_ControlRateConstantSkipFrames:
+ rc_mode = SWVENC_RC_MODE_CBR_VFR;
+ break;
+ case OMX_Video_ControlRateConstant:
+ rc_mode = SWVENC_RC_MODE_CBR_CFR;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("ERROR: UNKNOWN RC MODE");
+ Ret = SWVENC_S_FAILURE;
+ break;
+ }
+
+ if (SWVENC_S_SUCCESS == Ret)
+ {
+ Prop.id = SWVENC_PROPERTY_ID_RC_MODE;
+ Prop.info.rc_mode = rc_mode;
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(SWVENC_S_FAILURE);
+ }
+ }
+
+ RETURN(Ret);
+}
+
+SWVENC_STATUS omx_venc::swvenc_set_profile_level
+(
+ OMX_U32 eProfile,
+ OMX_U32 eLevel
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_PROPERTY Prop;
+ SWVENC_PROFILE Profile;
+ SWVENC_LEVEL Level;
+
+ /* set the profile */
+ if (SWVENC_CODEC_MPEG4 == m_codec)
+ {
+ switch (eProfile)
+ {
+ case OMX_VIDEO_MPEG4ProfileSimple:
+ Profile.mpeg4 = SWVENC_PROFILE_MPEG4_SIMPLE;
+ break;
+ case OMX_VIDEO_MPEG4ProfileAdvancedSimple:
+ Profile.mpeg4 = SWVENC_PROFILE_MPEG4_ADVANCED_SIMPLE;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
+ Ret = SWVENC_S_FAILURE;
+ break;
+ }
+ switch (eLevel)
+ {
+ case OMX_VIDEO_MPEG4Level0:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_0;
+ break;
+ case OMX_VIDEO_MPEG4Level0b:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_0B;
+ break;
+ case OMX_VIDEO_MPEG4Level1:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_1;
+ break;
+ case OMX_VIDEO_MPEG4Level2:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_2;
+ break;
+ case OMX_VIDEO_MPEG4Level3:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_3;
+ break;
+ case OMX_VIDEO_MPEG4Level4:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_4;
+ break;
+ case OMX_VIDEO_MPEG4Level4a:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_4A;
+ break;
+ case OMX_VIDEO_MPEG4Level5:
+ Level.mpeg4 = SWVENC_LEVEL_MPEG4_5;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
+ Ret = SWVENC_S_FAILURE;
+ break;
+ }
+ }
+ else if (SWVENC_CODEC_H263 == m_codec)
+ {
+ switch (eProfile)
+ {
+ case OMX_VIDEO_H263ProfileBaseline:
+ Profile.h263 = SWVENC_PROFILE_H263_BASELINE;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("ERROR: UNKNOWN PROFILE");
+ Ret = SWVENC_S_FAILURE;
+ break;
+ }
+ switch (eLevel)
+ {
+ case OMX_VIDEO_H263Level10:
+ Level.h263 = SWVENC_LEVEL_H263_10;
+ break;
+ case OMX_VIDEO_H263Level20:
+ Level.h263 = SWVENC_LEVEL_H263_20;
+ break;
+ case OMX_VIDEO_H263Level30:
+ Level.h263 = SWVENC_LEVEL_H263_30;
+ break;
+ case OMX_VIDEO_H263Level40:
+ Level.h263 = SWVENC_LEVEL_H263_40;
+ break;
+ case OMX_VIDEO_H263Level50:
+ Level.h263 = SWVENC_LEVEL_H263_50;
+ break;
+ case OMX_VIDEO_H263Level60:
+ Level.h263 = SWVENC_LEVEL_H263_60;
+ break;
+ case OMX_VIDEO_H263Level70:
+ Level.h263 = SWVENC_LEVEL_H263_70;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("ERROR: UNKNOWN LEVEL");
+ Ret = SWVENC_S_FAILURE;
+ break;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR: UNSUPPORTED CODEC");
+ Ret = SWVENC_S_FAILURE;
+ }
+
+ if (SWVENC_S_SUCCESS == Ret)
+ {
+ Prop.id = SWVENC_PROPERTY_ID_PROFILE;
+ Prop.info.profile = Profile;
+
+ /* set the profile */
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(SWVENC_S_FAILURE);
+ }
+
+ /* set the level */
+ Prop.id = SWVENC_PROPERTY_ID_LEVEL;
+ Prop.info.level = Level;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ RETURN(SWVENC_S_FAILURE);
+ }
+ }
+
+ RETURN(Ret);
+}
+
+SWVENC_STATUS omx_venc::swvenc_set_intra_refresh
+(
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE *IntraRefresh
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_IR_CONFIG ir_config;
+ SWVENC_PROPERTY Prop;
+
+ switch (IntraRefresh->eRefreshMode)
+ {
+ case OMX_VIDEO_IntraRefreshCyclic:
+ Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC;
+ break;
+ case OMX_VIDEO_IntraRefreshAdaptive:
+ Prop.info.ir_config.mode = SWVENC_IR_MODE_ADAPTIVE;
+ break;
+ case OMX_VIDEO_IntraRefreshBoth:
+ Prop.info.ir_config.mode = SWVENC_IR_MODE_CYCLIC_ADAPTIVE;
+ break;
+ case OMX_VIDEO_IntraRefreshRandom:
+ Prop.info.ir_config.mode = SWVENC_IR_MODE_RANDOM;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("ERROR: UNKNOWN INTRA REFRESH MODE");
+ Ret = SWVENC_S_FAILURE;
+ break;
+ }
+
+ if (SWVENC_S_SUCCESS == Ret)
+ {
+ Prop.id = SWVENC_PROPERTY_ID_IR_CONFIG;
+ Prop.info.ir_config.cir_mbs = IntraRefresh->nCirMBs;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ Ret = SWVENC_S_FAILURE;
+ }
+ }
+
+ RETURN(Ret);
+}
+
+SWVENC_STATUS omx_venc::swvenc_set_frame_rate
+(
+ OMX_U32 nFrameRate
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_PROPERTY Prop;
+
+ Prop.id = SWVENC_PROPERTY_ID_FRAME_RATE;
+ Prop.info.frame_rate = nFrameRate;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ Ret = SWVENC_S_FAILURE;
+ }
+
+ RETURN(Ret);
+}
+
+SWVENC_STATUS omx_venc::swvenc_set_bit_rate
+(
+ OMX_U32 nTargetBitrate
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_PROPERTY Prop;
+
+ Prop.id = SWVENC_PROPERTY_ID_TARGET_BITRATE;
+ Prop.info.target_bitrate = nTargetBitrate;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ Ret = SWVENC_S_FAILURE;
+ }
+
+ RETURN(Ret);
+}
+
+SWVENC_STATUS omx_venc::swvenc_set_intra_period
+(
+ OMX_U32 nPFrame,
+ OMX_U32 nBFrame
+)
+{
+ ENTER_FUNC();
+
+ SWVENC_STATUS Ret = SWVENC_S_SUCCESS;
+ SWVENC_PROPERTY Prop;
+
+ Prop.id = SWVENC_PROPERTY_ID_INTRA_PERIOD;
+ Prop.info.intra_period.pframes = nPFrame;
+ Prop.info.intra_period.bframes = nBFrame;
+
+ Ret = swvenc_setproperty(m_hSwVenc, &Prop);
+ if (Ret != SWVENC_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("%s, swvenc_setproperty failed (%d)",
+ __FUNCTION__, Ret);
+ Ret = SWVENC_S_FAILURE;
+ }
+
+ RETURN(Ret);
+}
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
new file mode 100644
index 0000000..30fcfcd
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -0,0 +1,5402 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2016, 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
+//////////////////////////////////////////////////////////////////////////////
+
+#define __STDC_FORMAT_MACROS //enables the format specifiers in inttypes.h
+#include <inttypes.h>
+#include <string.h>
+#include "omx_video_base.h"
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/prctl.h>
+#ifdef _ANDROID_ICS_
+#include <media/hardware/HardwareAPI.h>
+#include <gralloc_priv.h>
+#endif
+#ifndef _ANDROID_
+#include <glib.h>
+#define strlcpy g_strlcpy
+#endif
+#define H264_SUPPORTED_WIDTH (480)
+#define H264_SUPPORTED_HEIGHT (368)
+
+#define MPEG4_SUPPORTED_WIDTH (480)
+#define MPEG4_SUPPORTED_HEIGHT (368)
+
+#define VC1_SP_MP_START_CODE 0xC5000000
+#define VC1_SP_MP_START_CODE_MASK 0xFF000000
+#define VC1_AP_START_CODE 0x00000100
+#define VC1_AP_START_CODE_MASK 0xFFFFFF00
+#define VC1_STRUCT_C_PROFILE_MASK 0xF0
+#define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
+#define VC1_SIMPLE_PROFILE 0
+#define VC1_MAIN_PROFILE 1
+#define VC1_ADVANCE_PROFILE 3
+#define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
+#define VC1_SIMPLE_PROFILE_MED_LEVEL 2
+#define VC1_STRUCT_C_LEN 4
+#define VC1_STRUCT_C_POS 8
+#define VC1_STRUCT_A_POS 12
+#define VC1_STRUCT_B_POS 24
+#define VC1_SEQ_LAYER_SIZE 36
+
+#define SZ_4K 0x1000
+#define SZ_1M 0x100000
+#define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
+
+#ifndef ION_FLAG_CP_BITSTREAM
+#define ION_FLAG_CP_BITSTREAM 0
+#endif
+
+#ifndef ION_FLAG_CP_PIXEL
+#define ION_FLAG_CP_PIXEL 0
+#endif
+
+#undef MEM_HEAP_ID
+
+#ifdef MASTER_SIDE_CP
+
+#define MEM_HEAP_ID ION_SECURE_HEAP_ID
+#define SECURE_ALIGN SZ_4K
+#define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL)
+#define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM)
+
+#else //SLAVE_SIDE_CP
+
+#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
+#define SECURE_ALIGN SZ_1M
+#define SECURE_FLAGS_INPUT_BUFFER ION_SECURE
+#define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE
+
+#endif
+
+typedef struct OMXComponentCapabilityFlagsType {
+ ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ 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
+
+void* message_thread_enc(void *input)
+{
+ omx_video* omx = reinterpret_cast<omx_video*>(input);
+ unsigned char id;
+ int n;
+
+ fd_set readFds;
+ int res = 0;
+ struct timeval tv;
+
+ DEBUG_PRINT_HIGH("omx_venc: message thread start");
+ prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
+ while (!omx->msg_thread_stop) {
+
+ tv.tv_sec = 2;
+ tv.tv_usec = 0;
+
+ FD_ZERO(&readFds);
+ FD_SET(omx->m_pipe_in, &readFds);
+
+ res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv);
+ if (res < 0) {
+ DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno));
+ continue;
+ } else if (res == 0 /*timeout*/ || omx->msg_thread_stop) {
+ continue;
+ }
+
+ 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)) {
+ DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
+ break;
+ }
+#endif
+ }
+ DEBUG_PRINT_HIGH("omx_venc: message thread stop");
+ return 0;
+}
+
+void post_message(omx_video *omx, unsigned char id)
+{
+ DEBUG_PRINT_LOW("omx_venc: post_message %d", id);
+ int ret_value;
+ ret_value = write(omx->m_pipe_out, &id, 1);
+ if (ret_value <= 0) {
+ DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno));
+ } else {
+ DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
+ }
+}
+
+// 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 long p1, unsigned long p2, unsigned long 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");
+ }
+ return ret;
+}
+
+// omx cmd queue pop
+bool omx_video::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *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():
+ c2d_opened(false),
+ psource_frame(NULL),
+ pdest_frame(NULL),
+ secure_session(false),
+ mEmptyEosBuffer(NULL),
+ m_pipe_in(-1),
+ m_pipe_out(-1),
+ 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_sExtraData(0),
+ m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
+ 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),
+ hw_overload(false),
+ m_graphicbuffer_size(0)
+{
+ DEBUG_PRINT_HIGH("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;
+ msg_thread_stop = false;
+
+ OMX_INIT_STRUCT(&m_blurInfo, OMX_QTI_VIDEO_CONFIG_BLURINFO);
+ m_blurInfo.nPortIndex == (OMX_U32)PORT_INDEX_IN;
+
+ mUsesColorConversion = false;
+ pthread_mutex_init(&m_lock, NULL);
+ pthread_mutex_init(&timestamp.m_lock, NULL);
+ timestamp.is_buffer_pending = false;
+ sem_init(&m_cmd_lock,0,0);
+ DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr);
+
+ memset(m_platform, 0, sizeof(m_platform));
+#ifdef _ANDROID_
+ char platform_name[PROPERTY_VALUE_MAX] = {0};
+ property_get("ro.board.platform", platform_name, "0");
+ strlcpy(m_platform, platform_name, sizeof(m_platform));
+#endif
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::~omx_venc
+
+ DESCRIPTION
+ Destructor
+
+ PARAMETERS
+ None
+
+ RETURN VALUE
+ None.
+ ========================================================================== */
+omx_video::~omx_video()
+{
+ DEBUG_PRINT_HIGH("~omx_video(): Inside Destructor()");
+ if (msg_thread_created) {
+ msg_thread_stop = true;
+ post_message(this, OMX_COMPONENT_CLOSE_MSG);
+ DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit");
+ pthread_join(msg_thread_id,NULL);
+ }
+ close(m_pipe_in);
+ close(m_pipe_out);
+ m_pipe_in = -1;
+ m_pipe_out = -1;
+ DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit");
+ /*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);
+ pthread_mutex_destroy(&timestamp.m_lock);
+ sem_destroy(&m_cmd_lock);
+ DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count,
+ m_fbd_count);
+ DEBUG_PRINT_HIGH("omx_video: Destructor exit");
+ DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ...");
+}
+
+/* ======================================================================
+ 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 long p1; // Parameter - 1
+ unsigned long p2; // Parameter - 2
+ unsigned long ident;
+ unsigned qsize=0; // qsize
+ omx_video *pThis = (omx_video *) ctxt;
+
+ if (!pThis) {
+ DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out");
+ 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", 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("ERROR: OMX_EventError: p2 = %lu", p2);
+ if (p2 == (unsigned)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, 0, 0);
+
+ }
+ break;
+
+ case OMX_CommandPortDisable:
+ DEBUG_PRINT_LOW("Process -> Port %lu set to PORT_STATE_DISABLED" \
+ "state", 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 %lu set PORT_STATE_ENABLED state" \
+ , p2);
+ pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
+ OMX_EventCmdComplete, p1, p2, NULL );
+ break;
+
+ default:
+ DEBUG_PRINT_LOW("process_event_cb forwarding EventCmdComplete %lu", 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");
+ }
+ break;
+ case OMX_COMPONENT_GENERATE_ETB_OPQ:
+ DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ");
+ if (pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("ERROR: ETBProxy() failed!");
+ pThis->omx_report_error ();
+ }
+ break;
+ case OMX_COMPONENT_GENERATE_ETB: {
+ OMX_ERRORTYPE iret;
+ DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB");
+ iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
+ if (iret == OMX_ErrorInsufficientResources) {
+ DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
+ pThis->omx_report_hw_overload ();
+ } else if (iret != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("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("ERROR: FTBProxy() failed!");
+ 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("ERROR: empty_buffer_done() failed!");
+ 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("ERROR: fill_buffer_done() failed!");
+ pThis->omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
+
+ pThis->input_flush_progress = false;
+ DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %" PRIu64, 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("dev_stop called after input flush complete");
+ if (dev_stop() != 0) {
+ DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in i/p flush!");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ }
+
+ break;
+
+ case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
+
+ pThis->output_flush_progress = false;
+ DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %" PRIu64, 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("dev_stop called after Output flush complete");
+ if (!pThis->input_flush_progress) {
+ if (dev_stop() != 0) {
+ DEBUG_PRINT_ERROR("ERROR: dev_stop() failed in o/p flush!");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_START_DONE:
+ DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE msg");
+
+ if (pThis->m_pCallbacks.EventHandler) {
+ DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
+ if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
+ DEBUG_PRINT_LOW("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("ERROR: dev_pause() failed in Start Done!");
+ 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("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
+ }
+ } else {
+ DEBUG_PRINT_LOW("Event Handler callback is NULL");
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_PAUSE_DONE:
+ DEBUG_PRINT_LOW("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");
+ 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("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("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("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
+ }
+ }
+
+ break;
+
+ case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
+ DEBUG_PRINT_ERROR("ERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!");
+ 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
+ case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
+ pThis->omx_report_unsupported_setting();
+ break;
+
+ case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
+ DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
+ pThis->omx_report_hw_overload();
+ break;
+
+ default:
+ DEBUG_PRINT_LOW("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("exited the while loop");
+
+}
+
+
+
+
+/* ======================================================================
+ 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
+ )
+{
+ (void)hComp;
+ (void)componentName;
+ (void)componentVersion;
+ (void)componentUUID;
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: 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_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
+ )
+{
+ (void)hComp;
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) {
+ if ((param1 != (OMX_U32)PORT_INDEX_IN) && (param1 != (OMX_U32)PORT_INDEX_OUT) && (param1 != (OMX_U32)PORT_INDEX_BOTH)) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
+ return OMX_ErrorBadPortIndex;
+ }
+ }
+ if (cmd == OMX_CommandMarkBuffer) {
+ if (param1 != PORT_INDEX_IN) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index");
+ return OMX_ErrorBadPortIndex;
+ }
+ if (!cmdData) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ post_event((unsigned long)cmd,(unsigned long)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
+ )
+{
+ (void)hComp;
+ (void)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");
+ } else {
+ DEBUG_PRINT_LOW("OMXCORE-SM: 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("ERROR: OMXCORE-SM: 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("OMXCORE-SM: Loaded-->WaitForResources");
+ }
+ /* Requesting transition from Loaded to Executing */
+ else if (eState == OMX_StateExecuting) {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing");
+ 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");
+ 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");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled",\
+ 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");
+ if (dev_stop() != 0) {
+ DEBUG_PRINT_ERROR("ERROR: dev_stop() failed at Idle --> Loaded");
+ eRet = OMX_ErrorHardware;
+ }
+ } else {
+ DEBUG_PRINT_LOW("OMXCORE-SM: 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) {
+ if ( dev_start() ) {
+ DEBUG_PRINT_ERROR("ERROR: dev_start() failed in SCP on Idle --> Exe");
+ omx_report_error ();
+ eRet = OMX_ErrorHardware;
+ } else {
+ BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
+ DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing");
+ bFlag = 0;
+ }
+
+ dev_start_done();
+ }
+ /* Requesting transition from Idle to Idle */
+ else if (eState == OMX_StateIdle) {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle");
+ 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");
+ 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("ERROR: dev_start() failed in SCP on Idle --> Pause");
+ omx_report_error ();
+ eRet = OMX_ErrorHardware;
+ } else {
+ BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
+ DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause");
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Idle to Invalid */
+ else if (eState == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled",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("OMXCORE-SM: Executing --> Idle");
+ //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("ERROR: dev_pause() failed in SCP on Exe --> Pause");
+ 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");
+ bFlag = 0;
+ }
+ }
+ /* Requesting transition from Executing to Loaded */
+ else if (eState == OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> Loaded");
+ 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("ERROR: OMXCORE-SM: Executing --> WaitForResources");
+ 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("ERROR: OMXCORE-SM: Executing --> Executing");
+ 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("ERROR: OMXCORE-SM: Executing --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled",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("Pause --> Executing");
+ 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");
+ post_event (0, 0, 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("Pause --> Idle");
+ 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("ERROR: Pause --> loaded");
+ 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("ERROR: Pause --> WaitForResources");
+ 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("ERROR: Pause --> Pause");
+ 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("ERROR: Pause --> Invalid");
+ post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
+ eRet = OMX_ErrorInvalidState;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled",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");
+ }
+ /* Requesting transition from WaitForResources to WaitForResources */
+ else if (eState == OMX_StateWaitForResources) {
+ DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources");
+ 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");
+ 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");
+ 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");
+ 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)",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");
+ 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");
+ 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");
+ 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)",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("execute_omx_flush - %u", (unsigned int)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 long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ /*Generate FBD for all Buffers in the FTBq*/
+ DEBUG_PRINT_LOW("execute_output_flush");
+ 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("ERROR: 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 long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ /*Generate EBD for all Buffers in the ETBq*/
+ DEBUG_PRINT_LOW("execute_input_flush");
+
+ 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 long 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 long)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("ERROR: 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 long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned long ident = 0;
+ bool bRet = true;
+
+ DEBUG_PRINT_LOW("execute_flush_all");
+
+ /*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);
+ } 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 long 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 long)pdest_frame,0,0);
+ pdest_frame = NULL;
+ }
+ }
+
+ /*Generate FBD for all Buffers in the FTBq*/
+ DEBUG_PRINT_LOW("execute_output_flush");
+ 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("ERROR: 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 long p1,
+ unsigned long p2,
+ unsigned long 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("Value of this pointer in post_event %p",this);
+ post_message(this, id);
+ pthread_mutex_unlock(&m_lock);
+
+ return bRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::GetParameter
+
+ DESCRIPTION
+ OMX Get Parameter method implementation
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ Error None if successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_INOUT OMX_PTR paramData)
+{
+ (void)hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned int height=0,width = 0;
+
+ DEBUG_PRINT_LOW("get_parameter:");
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
+ return OMX_ErrorBadParameter;
+ }
+ switch ((int)paramIndex) {
+ case OMX_IndexParamPortDefinition:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
+ if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
+ dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ m_sInPortDef.nPortIndex);
+ DEBUG_PRINT_LOW("m_sInPortDef: size = %u, min cnt = %u, actual cnt = %u",
+ (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountMin,
+ (unsigned int)m_sInPortDef.nBufferCountActual);
+ memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
+#ifdef _ANDROID_ICS_
+ if (meta_mode_enable) {
+ // request size of largest metadata (happens to be NativeHandleSource) since
+ // we do not know the exact metadata-type yet
+ portDefn->nBufferSize = sizeof(LEGACY_CAM_METADATA_TYPE);
+ }
+ if (mUseProxyColorFormat) {
+ portDefn->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
+ }
+#endif
+ } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+ if (m_state != OMX_StateExecuting) {
+ dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+ }
+ DEBUG_PRINT_LOW("m_sOutPortDef: size = %u, min cnt = %u, actual cnt = %u",
+ (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountMin,
+ (unsigned int)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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
+ OMX_PORT_PARAM_TYPE *portParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
+
+ memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
+ break;
+ }
+ case OMX_IndexParamVideoPortFormat:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
+
+ if (portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) {
+ unsigned index = portFmt->nIndex;
+
+#ifdef _UBWC_
+ //we support following formats
+ //index 0 - Compressed (UBWC) Venus flavour of YUV420SP
+ //index 1 - Venus flavour of YUV420SP
+ //index 2 - Compressed (UBWC) Venus flavour of RGBA8888
+ //index 3 - Venus flavour of RGBA8888
+ //index 4 - opaque which internally maps to YUV420SP.
+ //index 5 - vannilla YUV420SP
+ //this can be extended in the future
+ int supportedFormats[] = {
+ [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed,
+ [1] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ [2] = QOMX_COLOR_Format32bitRGBA8888Compressed,
+ [3] = QOMX_COLOR_Format32bitRGBA8888,
+ [4] = QOMX_COLOR_FormatAndroidOpaque,
+ [5] = OMX_COLOR_FormatYUV420SemiPlanar,
+ };
+#else
+ //we support two formats
+ //index 0 - Venus flavour of YUV420SP
+ //index 1 - opaque which internally maps to YUV420SP.
+ //index 2 - vannilla YUV420SP
+ //this can be extended in the future
+ int supportedFormats[] = {
+ [0] = QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+ [1] = QOMX_COLOR_FormatAndroidOpaque,
+ [2] = OMX_COLOR_FormatYUV420SemiPlanar,
+ };
+#endif
+ if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1))
+ eRet = OMX_ErrorNoMore;
+ else {
+ memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
+ portFmt->nIndex = index; //restore index set from client
+ portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)supportedFormats[index];
+ }
+ } 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_BITRATETYPE);
+ OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate");
+
+ 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_MPEG4TYPE);
+ OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4");
+ memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
+ break;
+ }
+ case OMX_IndexParamVideoH263:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_H263TYPE);
+ OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263");
+ memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
+ break;
+ }
+ case OMX_IndexParamVideoAvc:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_AVCTYPE);
+ OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc");
+ memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
+ break;
+ }
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_VP8TYPE);
+ OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoVp8");
+ memcpy(pParam, &m_sParamVP8, sizeof(m_sParamVP8));
+ break;
+ }
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_HEVCTYPE);
+ OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoHevc");
+ memcpy(pParam, &m_sParamHEVC, sizeof(m_sParamHEVC));
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelQuerySupported:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported");
+ eRet = get_supported_profile_level(pParam);
+ if (eRet && eRet != OMX_ErrorNoMore)
+ DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %u, %u",
+ (unsigned int)pParam->eProfile, (unsigned int)pParam->eLevel);
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent");
+ memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
+ break;
+ }
+ case OMX_QcomIndexConfigH264EntropyCodingCabac:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
+ QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam = (QOMX_VIDEO_H264ENTROPYCODINGTYPE*)paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexConfigH264EntropyCodingCabac");
+ memcpy(pParam, &m_sParamEntropy, sizeof(m_sParamEntropy));
+ break;
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamAudioInit:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
+ OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
+ memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
+ break;
+ }
+ /*Component should support this port definition*/
+ case OMX_IndexParamImageInit:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
+ OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
+ 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", paramIndex);
+ eRet =OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ case OMX_IndexParamStandardComponentRole:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
+ 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",paramIndex);
+ strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
+ break;
+ }
+ /* Added for parameter test */
+ case OMX_IndexParamPriorityMgmt:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
+ OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
+ memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
+ break;
+ }
+ /* Added for parameter test */
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
+ 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
+ OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization");
+ memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoQPRange:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE);
+ OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoQPRange");
+ memcpy(qp_range, &m_sSessionQPRange, sizeof(m_sSessionQPRange));
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoIPBQPRange:
+ {
+ OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE");
+ memcpy(qp_range, &m_sSessionIPBQPRange, sizeof(m_sSessionIPBQPRange));
+ break;
+ }
+
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
+ DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
+ errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
+ errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
+ errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
+ DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh");
+ DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET");
+ intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
+ intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
+ break;
+ }
+ case OMX_QcomIndexPortDefn:
+ //TODO
+ break;
+ case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMXComponentCapabilityFlagsType);
+ OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
+ DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX");
+ 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
+ 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 & VENC_EXTRADATA_SLICEINFO);
+ DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled);
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: slice information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo) {
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ pParam->bEnabled =
+ (OMX_BOOL)(m_sExtraData & VENC_EXTRADATA_MBINFO);
+ DEBUG_PRINT_HIGH("MB Info extradata %d", pParam->bEnabled);
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: MB information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataFrameDimension) {
+ if (pParam->nPortIndex == PORT_INDEX_IN) {
+ pParam->bEnabled =
+ (OMX_BOOL)((m_sExtraData & VENC_EXTRADATA_FRAMEDIMENSION) ? 1 : 0);
+ DEBUG_PRINT_HIGH("Frame dimension extradata %d", pParam->bEnabled);
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: frame dimension is "
+ "valid for input 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);
+ 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_RANGETYPE);
+ 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;
+ case OMX_QcomIndexParamVideoLTRCount:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE);
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoLTRCount");
+ OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE *pParam =
+ reinterpret_cast<OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*>(paramData);
+ memcpy(pParam, &m_sParamLTRCount, sizeof(m_sParamLTRCount));
+ break;
+ }
+#endif
+ case QOMX_IndexParamVideoSyntaxHdr:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE);
+ DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
+ QOMX_EXTNINDEX_PARAMTYPE* pParam =
+ reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(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 *)(void *)&pParam->nDataSize)) {
+ DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %u)",
+ (unsigned int)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_QcomIndexHierarchicalStructure:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_HIERARCHICALLAYERS);
+ QOMX_VIDEO_HIERARCHICALLAYERS* hierp = (QOMX_VIDEO_HIERARCHICALLAYERS*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexHierarchicalStructure");
+ memcpy(hierp, &m_sHierLayers, sizeof(m_sHierLayers));
+ break;
+ }
+ case OMX_QcomIndexParamMBIStatisticsMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QOMX_VIDEO_MBI_STATISTICS);
+ OMX_QOMX_VIDEO_MBI_STATISTICS* mbi_mode = (OMX_QOMX_VIDEO_MBI_STATISTICS*) paramData;
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamMBIStatisticsMode");
+ memcpy(mbi_mode, &m_sMBIStatistics, sizeof(m_sMBIStatistics));
+ break;
+ }
+ case OMX_QcomIndexParamPerfLevel:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PERF_LEVEL);
+ OMX_U32 perflevel;
+ OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
+ reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PERF_LEVEL*>(paramData);
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPerfLevel");
+ if (!dev_get_performance_level(&perflevel)) {
+ DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
+ pParam->ePerfLevel);
+ } else {
+ pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamH264VUITimingInfo:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO);
+ OMX_U32 enabled;
+ OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
+ reinterpret_cast<OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO*>(paramData);
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamH264VUITimingInfo");
+ if (!dev_get_vui_timing_info(&enabled)) {
+ DEBUG_PRINT_ERROR("Invalid entry returned from get_vui_Timing_info %d",
+ pParam->bEnable);
+ } else {
+ pParam->bEnable = (OMX_BOOL)enabled;
+ }
+ break;
+ }
+ case OMX_QTIIndexParamVQZIPSEIType:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
+ OMX_U32 enabled;
+ OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
+ reinterpret_cast<OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*>(paramData);
+ DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVQZIPSEIType");
+ if (!dev_get_vqzip_sei_info(&enabled)) {
+ DEBUG_PRINT_ERROR("Invalid entry returned from get_vqzip_sei_type %d",
+ pParam->bEnable);
+ } else {
+ pParam->bEnable = (OMX_BOOL)enabled;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamPeakBitrate:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE);
+ OMX_U32 peakbitrate;
+ OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
+ reinterpret_cast<OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE*>(paramData);
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamPeakBitrate");
+ if (!dev_get_peak_bitrate(&peakbitrate)) {
+ DEBUG_PRINT_ERROR("Invalid entry returned from get_peak_bitrate %u",
+ (unsigned int)pParam->nPeakBitrate);
+ } else {
+ pParam->nPeakBitrate = peakbitrate;
+ }
+ break;
+ }
+ case QOMX_IndexParamVideoInitialQp:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP);
+ QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp =
+ reinterpret_cast<QOMX_EXTNINDEX_VIDEO_INITIALQP *>(paramData);
+ memcpy(initqp, &m_sParamInitqp, sizeof(m_sParamInitqp));
+ break;
+ }
+ case OMX_QcomIndexParamBatchSize:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_U32TYPE);
+ OMX_PARAM_U32TYPE* batch =
+ reinterpret_cast<OMX_PARAM_U32TYPE *>(paramData);
+
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamBatchSize");
+ if (!dev_get_batch_size(&batch->nU32)) {
+ DEBUG_PRINT_ERROR("Invalid entry returned from dev_get_batch_size %u",
+ (unsigned int)batch->nSize);
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ batch->nPortIndex = PORT_INDEX_IN;
+ break;
+ }
+ case OMX_QcomIndexParamSequenceHeaderWithIDR:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, PrependSPSPPSToIDRFramesParams);
+ PrependSPSPPSToIDRFramesParams * pParam =
+ reinterpret_cast<PrependSPSPPSToIDRFramesParams *>(paramData);
+ DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamSequenceHeaderWithIDR");
+ memcpy(pParam, &m_sPrependSPSPPS, sizeof(m_sPrependSPSPPS));
+ break;
+ }
+ case OMX_QcomIndexParamVencAspectRatio:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_SAR);
+ QOMX_EXTNINDEX_VIDEO_VENC_SAR * pParam =
+ reinterpret_cast<QOMX_EXTNINDEX_VIDEO_VENC_SAR *>(paramData);
+ memcpy(pParam, &m_sSar, sizeof(m_sSar));
+ break;
+ }
+ case OMX_QTIIndexParamLowLatencyMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE);
+ QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE * pParam =
+ reinterpret_cast<QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE *>(paramData);
+ memcpy(pParam, &m_slowLatencyMode, sizeof(m_slowLatencyMode));
+ break;
+ }
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pLayerInfo =
+ reinterpret_cast<OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*>(paramData);
+ if (!dev_get_temporal_layer_caps(&m_sParamTemporalLayers.nLayerCountMax,
+ &m_sParamTemporalLayers.nBLayerCountMax)) {
+ DEBUG_PRINT_ERROR("Failed to get temporal layer capabilities");
+ eRet = OMX_ErrorHardware;
+ }
+ memcpy(pLayerInfo, &m_sParamTemporalLayers, sizeof(m_sParamTemporalLayers));
+ break;
+ }
+ case OMX_IndexParamVideoSliceFMO:
+ default:
+ {
+ DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x", paramIndex);
+ eRet =OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+ }
+
+ return eRet;
+
+}
+/* ======================================================================
+ FUNCTION
+ omx_video::GetConfig
+
+ DESCRIPTION
+ OMX Get Config Method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_INOUT OMX_PTR configData)
+{
+ (void)hComp;
+ ////////////////////////////////////////////////////////////////
+ // 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 ((int)configIndex) {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE);
+ OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
+ memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE);
+ OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
+ memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE);
+ OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod");
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE);
+ QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
+ memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
+ break;
+ }
+ case OMX_IndexConfigVideoAVCIntraPeriod:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD);
+ OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam =
+ reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod");
+ memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod));
+ break;
+ }
+ case OMX_IndexConfigCommonDeinterlace:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE);
+ OMX_VIDEO_CONFIG_DEINTERLACE *pParam =
+ reinterpret_cast<OMX_VIDEO_CONFIG_DEINTERLACE*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_IndexConfigCommonDeinterlace");
+ memcpy(pParam, &m_sConfigDeinterlace, sizeof(m_sConfigDeinterlace));
+ break;
+ }
+ case OMX_IndexConfigVideoVp8ReferenceFrame:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE);
+ OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam =
+ reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame");
+ memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame));
+ break;
+ }
+ case OMX_QcomIndexConfigPerfLevel:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
+ OMX_U32 perflevel;
+ OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam =
+ reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel");
+ if (!dev_get_performance_level(&perflevel)) {
+ DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
+ pParam->ePerfLevel);
+ } else {
+ pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigNumHierPLayers:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS);
+ QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS* pParam =
+ reinterpret_cast<QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigNumHierPLayers");
+ memcpy(pParam, &m_sHPlayers, sizeof(m_sHPlayers));
+ break;
+ }
+ case OMX_QcomIndexConfigQp:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_QP);
+ OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
+ reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_QP*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigQp");
+ memcpy(pParam, &m_sConfigQP, sizeof(m_sConfigQP));
+ break;
+ }
+ case OMX_QcomIndexConfigBaseLayerId:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID);
+ OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
+ reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigBaseLayerId");
+ memcpy(pParam, &m_sBaseLayerID, sizeof(m_sBaseLayerID));
+ break;
+ }
+#ifdef SUPPORT_CONFIG_INTRA_REFRESH
+ case OMX_IndexConfigAndroidIntraRefresh:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE);
+ OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam =
+ reinterpret_cast<OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidIntraRefresh");
+ memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh));
+ break;
+ }
+#endif
+ case OMX_QTIIndexConfigVideoBlurResolution:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QTI_VIDEO_CONFIG_BLURINFO);
+ OMX_QTI_VIDEO_CONFIG_BLURINFO* pParam =
+ reinterpret_cast<OMX_QTI_VIDEO_CONFIG_BLURINFO*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigVideoBlurResolution");
+ memcpy(pParam, &m_blurInfo, sizeof(m_blurInfo));
+ break;
+ }
+ case OMX_QTIIndexConfigDescribeColorAspects:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
+ DescribeColorAspectsParams* pParam =
+ reinterpret_cast<DescribeColorAspectsParams*>(configData);
+ DEBUG_PRINT_LOW("get_config: OMX_QTIIndexConfigDescribeColorAspects");
+ if (pParam->bRequestingDataSpace) {
+ DEBUG_PRINT_ERROR("Does not handle dataspace request");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (pParam->bDataSpaceChanged == OMX_TRUE) {
+
+ print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) Client says");
+ // If the dataspace says RGB, recommend 601-limited;
+ // since that is the destination colorspace that C2D or Venus will convert to.
+ if (pParam->nPixelFormat == HAL_PIXEL_FORMAT_RGBA_8888) {
+ DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: Recommend 601-limited for RGBA8888");
+ pParam->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
+ pParam->sAspects.mRange = ColorAspects::RangeLimited;
+ pParam->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
+ pParam->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
+ } else {
+ // For IMPLEMENTATION_DEFINED (or anything else), stick to client's defaults.
+ DEBUG_PRINT_INFO("get_config (dataspace changed): ColorSpace: use client-default for format=%x",
+ pParam->nPixelFormat);
+ }
+ print_debug_color_aspects(&(pParam->sAspects), "get_config (dataspace changed) recommended");
+ } else {
+ memcpy(pParam, &m_sConfigColorAspects, sizeof(m_sConfigColorAspects));
+ print_debug_color_aspects(&(pParam->sAspects), "get_config");
+ }
+ break;
+ }
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
+ OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *layerConfig =
+ (OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE *)configData;
+ DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidVideoTemporalLayering");
+ memcpy(configData, &m_sConfigTemporalLayers, sizeof(m_sConfigTemporalLayers));
+ break;
+ }
+
+ default:
+ DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
+ return OMX_ErrorUnsupportedIndex;
+ }
+ return OMX_ErrorNone;
+
+}
+
+#define extn_equals(param, extn) (!strcmp(param, extn))
+
+/* ======================================================================
+ FUNCTION
+ omx_video::GetExtensionIndex
+
+ DESCRIPTION
+ OMX GetExtensionIndex method implementaion. <TBD>
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if everything successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_STRING paramName,
+ OMX_OUT OMX_INDEXTYPE* indexType)
+{
+ (void)hComp;
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+#ifdef MAX_RES_1080P
+ if (extn_equals(paramName, "OMX.QCOM.index.param.SliceDeliveryMode")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
+ return OMX_ErrorNone;
+ }
+#endif
+#ifdef _ANDROID_ICS_
+ if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
+ return OMX_ErrorNone;
+ }
+#endif
+ if (extn_equals(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.param.video.HierStructure")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexHierarchicalStructure;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRCount")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoLTRCount;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRPeriod")) {
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRUse")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRUse;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRMark")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRMark;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.config.video.hierplayers")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigNumHierPLayers;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.param.video.baselayerid")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.config.video.qp")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigQp;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.param.video.sar")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVencAspectRatio;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QCOM.index.param.video.InputBatch")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamBatchSize;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_SETTIMEDATA)) {
+ *indexType = (OMX_INDEXTYPE)OMX_IndexConfigTimePosition;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableRoiInfo;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiInfo;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_BLURINFO)) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoBlurResolution;
+ return OMX_ErrorNone;
+ }
+
+ if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
+ return OMX_ErrorNone;
+ }
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_video::GetState
+
+ DESCRIPTION
+ Returns the state information back to the caller.<TBD>
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ Error None if everything is successful.
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STATETYPE* state)
+{
+ (void)hComp;
+ *state = m_state;
+ DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_video::ComponentTunnelRequest
+
+ DESCRIPTION
+ OMX Component Tunnel Request method implementation. <TBD>
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ OMX Error None if everything successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_HANDLETYPE peerComponent,
+ OMX_IN OMX_U32 peerPort,
+ OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
+{
+ (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup;
+ DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented");
+ 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)
+{
+ (void) hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ unsigned i = 0;
+ unsigned char *buf_addr = NULL;
+
+ DEBUG_PRINT_HIGH("use_input_buffer: port = %u appData = %p bytes = %u buffer = %p",(unsigned int)port,appData,(unsigned int)bytes,buffer);
+ if (bytes < m_sInPortDef.nBufferSize) {
+ DEBUG_PRINT_ERROR("ERROR: use_input_buffer: Size Mismatch!! "
+ "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)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("ERROR: calloc() Failed for m_inp_mem_ptr");
+ return OMX_ErrorInsufficientResources;
+ }
+ DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
+
+
+ m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
+ if (m_pInput_pmem == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: 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("ERROR: 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 = 0;
+#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,
+ secure_session ? SECURE_FLAGS_INPUT_BUFFER : 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("ERROR: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("ERROR: /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 = NULL;
+ if(!secure_session) {
+ 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("ERROR: mmap() Failed");
+ m_pInput_pmem[i].buffer = NULL;
+ close(m_pInput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pInput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+
+ } else {
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
+ DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (unsigned)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("DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
+ (unsigned int)pParam->pmem_fd, (unsigned int)pParam->offset);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ DEBUG_PRINT_LOW("use_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("ERROR: dev_use_buf() Failed for i/p buf");
+ return OMX_ErrorInsufficientResources;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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)
+{
+ (void)hComp, (void)port;
+ 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("Inside use_output_buffer()");
+ if (bytes < m_sOutPortDef.nBufferSize) {
+ DEBUG_PRINT_ERROR("ERROR: use_output_buffer: Size Mismatch!! "
+ "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)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(%u)",(unsigned int)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("ERROR: 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("ERROR: 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("ERROR: 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",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 = 0;
+#endif
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]",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;
+
+ if (!m_use_output_pmem) {
+#ifdef USE_ION
+#ifdef _MSM8974_
+ align_size = (m_sOutPortDef.nBufferSize + (SZ_4K - 1)) & ~(SZ_4K - 1);
+ 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,
+ secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : 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("ERROR: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("ERROR: /dev/pmem_adsp open() Failed");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
+ m_pOutput_pmem[i].offset = 0;
+
+ m_pOutput_pmem[i].buffer = NULL;
+ if(!secure_session) {
+#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("ERROR: mmap() Failed");
+ m_pOutput_pmem[i].buffer = NULL;
+ close(m_pOutput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pOutput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ } else {
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
+ DEBUG_PRINT_LOW("Inside qcom_ext pParam: %p", pParam);
+
+ if (pParam) {
+ DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (int)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("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;
+ }
+
+ BITMASK_SET(&m_out_bm_count,i);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
+ "index = %u", i);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ return eRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_video::UseBuffer
+
+ DESCRIPTION
+ OMX Use Buffer method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None , if everything successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::use_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State");
+ 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",(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 - ((!meta_mode_enable)?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();
+ opaque_buffer_hdr[index] = NULL;
+ }
+ }
+#endif
+ if (index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat &&
+ dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
+ DEBUG_PRINT_LOW("ERROR: dev_free_buf() Failed for i/p buf");
+ }
+
+ if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) {
+ auto_lock l(m_lock);
+
+ if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) {
+ DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case");
+ if(!secure_session) {
+ munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
+ } else {
+ free(m_pInput_pmem[index].buffer);
+ }
+ m_pInput_pmem[index].buffer = NULL;
+ 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("FreeBuffer:: i/p Heap UseBuffer case");
+ if (dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) {
+ DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf");
+ }
+ if(!secure_session) {
+ munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
+ m_pInput_pmem[index].buffer = NULL;
+ }
+ 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("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("FreeBuffer:: o/p AllocateBuffer case");
+ if(!secure_session) {
+ munmap (m_pOutput_pmem[index].buffer,
+ m_pOutput_pmem[index].size);
+ } else {
+ char *data = (char*) m_pOutput_pmem[index].buffer;
+ native_handle_t *handle = NULL;
+ memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*));
+ native_handle_delete(handle);
+ free(m_pOutput_pmem[index].buffer);
+ }
+ 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("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");
+ }
+ if(!secure_session) {
+ 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("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;
+ // In meta-mode alloc-length is not known conclusively
+ // Allow allocation for atleast gralloc metadata handles
+ // and check for size in ETB
+ if (!bufferHdr || bytes < sizeof(VideoGrallocMetadata)) {
+ DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %u",
+ bufferHdr, (unsigned int)bytes);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_inp_mem_ptr && !mUseProxyColorFormat) {
+ m_inp_mem_ptr = meta_buffer_hdr;
+ DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p",
+ meta_buffer_hdr, m_inp_mem_ptr);
+ }
+ 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 long)opaque_buffer_hdr[index],0,0);
+ DEBUG_PRINT_HIGH("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)
+{
+ (void)hComp, (void)port;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned i = 0;
+
+ DEBUG_PRINT_HIGH("allocate_input_buffer()::");
+ if (bytes < m_sInPortDef.nBufferSize) {
+ DEBUG_PRINT_ERROR("ERROR: Buffer size mismatch error: bytes[%u] < nBufferSize[%u]",
+ (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_inp_mem_ptr) {
+ DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
+ (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)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("ERROR: calloc() Failed for m_inp_mem_ptr");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
+ m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
+
+ if (m_pInput_pmem == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: 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("ERROR: 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 = 0;
+#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;
+ // make fd available to app layer, help with testing
+ (*bufferHdr)->pInputPortPrivate = (OMX_PTR)&m_pInput_pmem[i];
+
+#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,
+ secure_session ? SECURE_FLAGS_INPUT_BUFFER : 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("ERROR: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("ERROR: /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 = NULL;
+ if(!secure_session) {
+ 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("ERROR: mmap FAILED= %d", errno);
+ m_pInput_pmem[i].buffer = NULL;
+ close(m_pInput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pInput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+ } else {
+ //This should only be used for passing reference to source type and
+ //secure handle fd struct native_handle_t*
+ m_pInput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*));
+ if (m_pInput_pmem[i].buffer == NULL) {
+ DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__);
+ return OMX_ErrorInsufficientResources;
+ }
+ (*bufferHdr)->nAllocLen = sizeof(OMX_U32) + sizeof(native_handle_t*);
+ }
+
+ (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer;
+ DEBUG_PRINT_LOW("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("ERROR: dev_use_buf FAILED for i/p buf");
+ return OMX_ErrorInsufficientResources;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: All i/p buffers are allocated, invalid allocate buf call"
+ "for index [%d]", i);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ return eRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::AllocateOutputBuffer
+
+ DESCRIPTION
+ Helper fn for AllocateBuffer in the output pin
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if everything went well.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::allocate_output_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes)
+{
+ (void)hComp, (void)port;
+ 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("allocate_output_buffer()for %u bytes", (unsigned int)bytes);
+ if (!m_out_mem_ptr) {
+ int nBufHdrSize = 0;
+ DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__,
+ (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)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("ERROR: 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("ERROR: 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;
+ // make fd available to app layer, help with testing
+ bufHdr->pOutputPortPrivate = (OMX_PTR)&m_pOutput_pmem[i];
+ 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 = 0;
+#endif
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+
+ DEBUG_PRINT_HIGH("actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferCountActual);
+ for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) {
+ if (BITMASK_ABSENT(&m_out_bm_count,i)) {
+ DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
+ break;
+ }
+ }
+ if (eRet == OMX_ErrorNone) {
+ if (i < m_sOutPortDef.nBufferCountActual) {
+#ifdef USE_ION
+#ifdef _MSM8974_
+ align_size = ALIGN(m_sOutPortDef.nBufferSize, 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,
+ secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : ION_FLAG_CACHED);
+#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("ERROR: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("ERROR: /dev/pmem_adsp open() failed");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
+ m_pOutput_pmem[i].offset = 0;
+
+ m_pOutput_pmem[i].buffer = NULL;
+ *bufferHdr = (m_out_mem_ptr + i );
+
+ if(!secure_session) {
+#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("ERROR: MMAP_FAILED in o/p alloc buffer");
+ m_pOutput_pmem[i].buffer = NULL;
+ close (m_pOutput_pmem[i].fd);
+#ifdef USE_ION
+ free_ion_memory(&m_pOutput_ion[i]);
+#endif
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else {
+ //This should only be used for passing reference to source type and
+ //secure handle fd struct native_handle_t*
+ native_handle_t *handle = native_handle_create(1, 3); //fd, offset, size, alloc length
+ if (!handle) {
+ DEBUG_PRINT_ERROR("ERROR: native handle creation failed");
+ return OMX_ErrorInsufficientResources;
+ }
+ m_pOutput_pmem[i].buffer = malloc(sizeof(output_metabuffer));
+ if (m_pOutput_pmem[i].buffer == NULL) {
+ DEBUG_PRINT_ERROR("%s: Failed to allocate meta buffer", __func__);
+ return OMX_ErrorInsufficientResources;
+ }
+ (*bufferHdr)->nAllocLen = sizeof(output_metabuffer);
+ handle->data[0] = m_pOutput_pmem[i].fd;
+ handle->data[1] = 0;
+ handle->data[2] = 0;
+ handle->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
+ output_metabuffer *buffer = (output_metabuffer*) m_pOutput_pmem[i].buffer;
+ buffer->type = 1;
+ buffer->nh = handle;
+ }
+
+ (*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("ERROR: dev_use_buf FAILED for o/p buf");
+ return OMX_ErrorInsufficientResources;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call"
+ "for index [%d] actual: %u", i, (unsigned int)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("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port);
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
+ 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",(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",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)
+{
+ (void)hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned int nPortIndex;
+
+ DEBUG_PRINT_LOW("In for encoder 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_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
+ (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) {
+ DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)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");
+ 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");
+ post_event(OMX_EventError,
+ OMX_ErrorPortUnpopulated,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+
+ if (port == PORT_INDEX_IN) {
+ // check if the buffer is valid
+ nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
+
+ DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
+ nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
+ if (nPortIndex < m_sInPortDef.nBufferCountActual &&
+ BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
+ // 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()) {
+ input_use_buffer = false;
+ // "m_inp_mem_ptr" may point to "meta_buffer_hdr" in some modes,
+ // in which case, it was not explicitly allocated
+ if (m_inp_mem_ptr && m_inp_mem_ptr != meta_buffer_hdr) {
+ DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr");
+ free (m_inp_mem_ptr);
+ }
+ m_inp_mem_ptr = NULL;
+ if (m_pInput_pmem) {
+ DEBUG_PRINT_LOW("Freeing m_pInput_pmem");
+ free(m_pInput_pmem);
+ m_pInput_pmem = NULL;
+ }
+#ifdef USE_ION
+ if (m_pInput_ion) {
+ DEBUG_PRINT_LOW("Freeing m_pInput_ion");
+ free(m_pInput_ion);
+ m_pInput_ion = NULL;
+ }
+#endif
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid");
+ 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,
+ 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 %u, actual cnt %u",
+ nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
+ if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
+ BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
+ // 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");
+ free (m_out_mem_ptr);
+ m_out_mem_ptr = NULL;
+ }
+ if (m_pOutput_pmem) {
+ DEBUG_PRINT_LOW("Freeing m_pOutput_pmem");
+ free(m_pOutput_pmem);
+ m_pOutput_pmem = NULL;
+ }
+#ifdef USE_ION
+ if (m_pOutput_ion) {
+ DEBUG_PRINT_LOW("Freeing m_pOutput_ion");
+ free(m_pOutput_ion);
+ m_pOutput_ion = NULL;
+ }
+#endif
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid");
+ 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);
+ 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");
+ 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_HIGH("in free buffer, release not done, need to free more buffers output %" PRIx64" input %" PRIx64,
+ 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("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer);
+ if (m_state != OMX_StateExecuting &&
+ m_state != OMX_StatePause &&
+ m_state != OMX_StateIdle) {
+ DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid");
+ return OMX_ErrorVersionMismatch;
+ }
+
+ if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) {
+ DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer");
+ return OMX_ErrorBadPortIndex;
+ }
+ if (!m_sInPortDef.bEnabled) {
+ DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
+
+ if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
+ DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ m_etb_count++;
+ DEBUG_PRINT_LOW("DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
+ post_event ((unsigned long)hComp,(unsigned long)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)
+{
+ (void)hComp;
+ OMX_U8 *pmem_data_buf = NULL;
+ int push_cnt = 0;
+ unsigned nBufIndex = 0;
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ LEGACY_CAM_METADATA_TYPE *media_buffer = NULL;
+
+#ifdef _MSM8974_
+ int fd = 0;
+#endif
+ DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer);
+ if (buffer == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer);
+ return OMX_ErrorBadParameter;
+ }
+
+ // Buffer sanity checks
+ if (meta_mode_enable && !mUsesColorConversion) {
+ //For color-conversion case, we have an internal buffer and not a meta buffer
+ bool met_error = false;
+ nBufIndex = buffer - meta_buffer_hdr;
+ if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
+ DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex);
+ return OMX_ErrorBadParameter;
+ }
+ media_buffer = (LEGACY_CAM_METADATA_TYPE *)meta_buffer_hdr[nBufIndex].pBuffer;
+ if (!media_buffer) {
+ DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
+ return OMX_ErrorBadParameter;
+ }
+ if ((media_buffer->buffer_type == LEGACY_CAM_SOURCE)
+ && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
+ DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
+ buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
+ met_error = true;
+ } else if (media_buffer) {
+ if (media_buffer->buffer_type != LEGACY_CAM_SOURCE &&
+ media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
+ met_error = true;
+ } else {
+ if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
+ if (media_buffer->meta_handle == NULL)
+ met_error = true;
+ else {
+ int nFds = media_buffer->meta_handle->numFds,
+ nInt = media_buffer->meta_handle->numInts;
+ met_error = ((nFds == 1 && nInt >= 2) /*normal*/ ||
+ (nFds < 16 && nInt >= nFds*3) /*batch*/) ? false : true;
+ if (met_error) {
+ DEBUG_PRINT_ERROR("Unbalanced fds in handle: fds=%d ints=%d",
+ nFds, nInt);
+ }
+ }
+ }
+ }
+ } else
+ met_error = true;
+ if (met_error) {
+ DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call");
+ post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorBadParameter;
+ }
+ } else {
+ nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
+ if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
+ DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex);
+ return OMX_ErrorBadParameter;
+ }
+ }
+
+ pending_input_buffers++;
+ if (input_flush_progress == true) {
+ post_event ((unsigned long)buffer,0,
+ OMX_COMPONENT_GENERATE_EBD);
+ DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress");
+ return OMX_ErrorNone;
+ }
+#ifdef _MSM8974_
+ if (!meta_mode_enable) {
+ fd = m_pInput_pmem[nBufIndex].fd;
+ }
+#endif
+#ifdef _ANDROID_ICS_
+ if (meta_mode_enable && !mUsesColorConversion) {
+ // Camera or Gralloc-source meta-buffers queued with encodeable color-format
+ struct pmem Input_pmem_info;
+ if (!media_buffer) {
+ DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
+ return OMX_ErrorBadParameter;
+ }
+ if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
+ 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 (meta-Camera) fd = %d, offset = %d, size = %d",
+ Input_pmem_info.fd, Input_pmem_info.offset,
+ Input_pmem_info.size);
+ } else {
+ VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)meta_buffer_hdr[nBufIndex].pBuffer;
+ private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
+ 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;
+ DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
+ Input_pmem_info.fd, Input_pmem_info.offset,
+ Input_pmem_info.size);
+ }
+ if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,nBufIndex) != true) {
+ DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
+ post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorBadParameter;
+ }
+ } else if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
+#else
+ if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
+#endif
+ {
+ DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");
+
+ auto_lock l(m_lock);
+ pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
+ if (pmem_data_buf) {
+ memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
+ buffer->nFilledLen);
+ }
+ DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
+ } else if (mUseProxyColorFormat) {
+ // Gralloc-source buffers with color-conversion
+ fd = m_pInput_pmem[nBufIndex].fd;
+ DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u",
+ fd, (unsigned int)buffer->nFilledLen);
+ } else if (m_sInPortDef.format.video.eColorFormat ==
+ OMX_COLOR_FormatYUV420SemiPlanar) {
+ //For the case where YUV420SP buffers are qeueued to component
+ //by sources other than camera (Apps via MediaCodec), conversion
+ //to vendor flavoured NV12 color format is required.
+ if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth,
+ m_sInPortDef.format.video.nFrameHeight)) {
+ DEBUG_PRINT_ERROR("Failed to adjust buffer color");
+ post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorUndefined;
+ }
+ }
+#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("ERROR: ETBProxy: dev_empty_buf failed");
+#ifdef _ANDROID_ICS_
+ omx_release_meta_buffer(buffer);
+#endif
+ post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
+ /*Generate an async error and move to invalid state*/
+ pending_input_buffers--;
+ if (hw_overload) {
+ return OMX_ErrorInsufficientResources;
+ }
+ 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("FTB: buffer->pBuffer[%p]", buffer->pBuffer);
+ if (m_state != OMX_StateExecuting &&
+ m_state != OMX_StatePause &&
+ m_state != OMX_StateIdle) {
+ DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid");
+ return OMX_ErrorVersionMismatch;
+ }
+
+ if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index");
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (!m_sOutPortDef.bEnabled) {
+ DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ post_event((unsigned long) hComp, (unsigned long)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)
+{
+ (void)hComp;
+ OMX_U8 *pmem_data_buf = NULL;
+ OMX_ERRORTYPE nRet = OMX_ErrorNone;
+
+ DEBUG_PRINT_LOW("FTBProxy: bufferAdd->pBuffer[%p]", bufferAdd->pBuffer);
+
+ if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) {
+ DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params");
+ 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("o/p port is Disabled or Flush in Progress");
+ post_event ((unsigned long)bufferAdd,0,
+ OMX_COMPONENT_GENERATE_FBD);
+ return OMX_ErrorNone;
+ }
+
+ if (output_use_buffer && !m_use_output_pmem) {
+ DEBUG_PRINT_LOW("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("ERROR: dev_fill_buf() Failed");
+ post_event ((unsigned long)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)
+{
+ (void)hComp;
+ m_pCallbacks = *callbacks;
+ DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
+ m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
+ m_app_data = appData;
+ return OMX_ErrorNotImplemented;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::UseEGLImage
+
+ DESCRIPTION
+ OMX Use EGL Image method implementation <TBD>.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ Not Implemented error.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN void* eglImage)
+{
+ (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage;
+ DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented");
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::ComponentRoleEnum
+
+ DESCRIPTION
+ OMX Component Role Enum method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if everything is successful.
+ ========================================================================== */
+OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_U8* role,
+ OMX_IN OMX_U32 index)
+{
+ (void)hComp;
+ 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",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",role);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: No more roles");
+ 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",role);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: No more roles");
+ 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",role);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: No more roles");
+ 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",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",role);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: No more roles");
+ 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",role);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: No more roles");
+ 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",role);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: No more roles");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+#endif
+ else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
+ if ((0 == index) && role) {
+ strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s", role);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: No more roles");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else {
+ DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+ return eRet;
+}
+
+
+
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::AllocateDone
+
+ DESCRIPTION
+ Checks if entire buffer pool is allocated by IL Client or not.
+ Need this to move to IDLE state.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false.
+
+ ========================================================================== */
+bool omx_video::allocate_done(void)
+{
+ bool bRet = false;
+ bool bRet_In = false;
+ bool bRet_Out = false;
+
+ bRet_In = allocate_input_done();
+ bRet_Out = allocate_output_done();
+
+ if (bRet_In && bRet_Out) {
+ bRet = true;
+ }
+
+ return bRet;
+}
+/* ======================================================================
+ FUNCTION
+ omx_venc::AllocateInputDone
+
+ DESCRIPTION
+ Checks if I/P buffer pool is allocated by IL Client or not.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false.
+
+ ========================================================================== */
+bool omx_video::allocate_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0;
+
+ if (m_inp_mem_ptr == NULL) {
+ return bRet;
+ }
+ if (m_inp_mem_ptr ) {
+ for (; i<m_sInPortDef.nBufferCountActual; i++) {
+ if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
+ break;
+ }
+ }
+ }
+ if (i==m_sInPortDef.nBufferCountActual) {
+ bRet = true;
+ }
+ if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) {
+ m_sInPortDef.bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+/* ======================================================================
+ FUNCTION
+ omx_venc::AllocateOutputDone
+
+ DESCRIPTION
+ Checks if entire O/P buffer pool is allocated by IL Client or not.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false.
+
+ ========================================================================== */
+bool omx_video::allocate_output_done(void)
+{
+ bool bRet = false;
+ unsigned j=0;
+
+ if (m_out_mem_ptr == NULL) {
+ return bRet;
+ }
+
+ if (m_out_mem_ptr ) {
+ for (; j<m_sOutPortDef.nBufferCountActual; j++) {
+ if (BITMASK_ABSENT(&m_out_bm_count,j)) {
+ break;
+ }
+ }
+ }
+
+ if (j==m_sOutPortDef.nBufferCountActual) {
+ bRet = true;
+ }
+
+ if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) {
+ m_sOutPortDef.bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::ReleaseDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_video::release_done(void)
+{
+ bool bRet = false;
+ DEBUG_PRINT_LOW("Inside release_done()");
+ if (release_input_done()) {
+ if (release_output_done()) {
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::ReleaseOutputDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_video::release_output_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Inside release_output_done()");
+ if (m_out_mem_ptr) {
+ for (; j<m_sOutPortDef.nBufferCountActual; j++) {
+ if (BITMASK_PRESENT(&m_out_bm_count,j)) {
+ break;
+ }
+ }
+ if (j==m_sOutPortDef.nBufferCountActual) {
+ bRet = true;
+ }
+ } else {
+ bRet = true;
+ }
+ return bRet;
+}
+/* ======================================================================
+ FUNCTION
+ omx_venc::ReleaseInputDone
+
+ DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+ PARAMETERS
+ None.
+
+ RETURN VALUE
+ true/false
+
+ ========================================================================== */
+bool omx_video::release_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("Inside release_input_done()");
+ if (m_inp_mem_ptr) {
+ for (; j<m_sInPortDef.nBufferCountActual; j++) {
+ if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
+ break;
+ }
+ }
+ if (j==m_sInPortDef.nBufferCountActual) {
+ bRet = true;
+ }
+ } else {
+ bRet = true;
+ }
+ return bRet;
+}
+
+OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+#ifdef _MSM8974_
+ int index = buffer - m_out_mem_ptr;
+#endif
+ DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %u",
+ buffer->pBuffer, (unsigned)buffer->nFlags, (unsigned int)buffer->nFilledLen);
+ if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) {
+ return OMX_ErrorBadParameter;
+ }
+
+ pending_output_buffers--;
+
+ if (secure_session && m_pCallbacks.FillBufferDone) {
+ if (buffer->nFilledLen > 0)
+ m_fbd_count++;
+ m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
+ return OMX_ErrorNone;
+ }
+ if(!secure_session) {
+ 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++;
+
+ if (dev_get_output_log_flag()) {
+ dev_output_log_buffers((const char*)buffer->pBuffer, buffer->nFilledLen);
+ }
+ }
+ if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
+ if (!dev_handle_output_extradata((void *)buffer, index))
+ DEBUG_PRINT_ERROR("Failed to parse output extradata");
+
+ dev_extradata_log_buffers((char *)(((unsigned long)buffer->pBuffer + buffer->nOffset +
+ buffer->nFilledLen + 3) & (~3)));
+ }
+ 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;
+
+ buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
+ DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer);
+ if (buffer == NULL ||
+ ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
+ DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
+ return OMX_ErrorBadParameter;
+ }
+
+ pending_input_buffers--;
+
+ if (mUseProxyColorFormat &&
+ (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
+ if (!pdest_frame && !input_flush_progress && mUsesColorConversion) {
+ pdest_frame = buffer;
+ DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
+ return push_input_buffer(hComp);
+ }
+ //check if empty-EOS-buffer is being returned, treat this same as the
+ //color-conversion case as we queued a color-conversion buffer to encoder
+ bool handleEmptyEosBuffer = (mEmptyEosBuffer == buffer);
+ if (mUsesColorConversion || handleEmptyEosBuffer) {
+ if (handleEmptyEosBuffer) {
+ mEmptyEosBuffer = NULL;
+ }
+ // return color-conversion buffer back to the pool
+ DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer);
+ if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) {
+ DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full");
+ return OMX_ErrorBadParameter;
+ }
+ } else {
+ // We are not dealing with color-conversion, Buffer being returned
+ // here is client's buffer, return it back to client
+ if (m_pCallbacks.EmptyBufferDone && buffer) {
+ m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
+ DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
+ }
+ }
+ } 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 long p1;
+ unsigned long p2;
+ unsigned long 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("ERROR: empty_buffer_done() failed!");
+ omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FBD:
+ if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
+ DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
+ 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",
+ (int)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", (int)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", (int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %d", (int)profileLevelType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d",
+ (int)profileLevelType->eProfile, (int)profileLevelType->eLevel);
+ return eRet;
+}
+#endif
+
+#ifdef MAX_RES_1080P
+OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if (!profileLevelType)
+ return OMX_ErrorBadParameter;
+
+ if (profileLevelType->nPortIndex == 1) {
+ if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) {
+#if defined _MSM8974_ && !defined _MSM8226_
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel52;
+ } else if (profileLevelType->nProfileIndex == 1) {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel52;
+ } else if (profileLevelType->nProfileIndex == 2) {
+ profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel52;
+ } else if (profileLevelType->nProfileIndex == 3) {
+ profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel52;
+ } else if (profileLevelType->nProfileIndex == 4) {
+ profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel52;
+ } else {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)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;
+#ifdef _MSM8226_
+ } else if (profileLevelType->nProfileIndex == 3) {
+ profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
+ profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
+#endif
+ } else {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
+ (int)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 %u", (unsigned int)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 %u", (unsigned int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) {
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
+ profileLevelType->eLevel = OMX_VIDEO_VP8Level_Version0;
+ } else if (profileLevelType->nProfileIndex == 1) {
+ profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
+ profileLevelType->eLevel = OMX_VIDEO_VP8Level_Version1;
+ } else {
+ DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC) {
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
+ profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel52;
+ } else if (profileLevelType->nProfileIndex == 1) {
+ profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10;
+ profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel52;
+ } else {
+ DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ eRet = OMX_ErrorNoMore;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore");
+ eRet = OMX_ErrorNoMore;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u",
+ (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel);
+ return eRet;
+}
+#endif
+
+#ifdef USE_ION
+int omx_video::alloc_map_ion_memory(int size,
+ struct ion_allocation_data *alloc_data,
+ struct ion_fd_data *fd_data,int flag)
+{
+ struct venc_ion buf_ion_info;
+ int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
+ if (size <=0 || !alloc_data || !fd_data) {
+ DEBUG_PRINT_ERROR("Invalid 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("ERROR: ION Device open() Failed");
+ return ion_device_fd;
+ }
+
+ if(secure_session) {
+ alloc_data->len = (size + (SECURE_ALIGN - 1)) & ~(SECURE_ALIGN - 1);
+ alloc_data->align = SECURE_ALIGN;
+ alloc_data->flags = flag;
+ alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
+ if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
+ alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
+ }
+ DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u align %u flags %x",
+ (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
+ alloc_data->flags);
+ } else {
+ alloc_data->len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
+ alloc_data->align = SZ_4K;
+ alloc_data->flags = (flag & ION_FLAG_CACHED ? ION_FLAG_CACHED : 0);
+#ifdef MAX_RES_720P
+ alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
+#else
+ alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
+ ION_HEAP(ION_IOMMU_HEAP_ID));
+#endif
+ DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u align %u flags %x",
+ (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
+ alloc_data->flags);
+ }
+
+ rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
+ if (rc || !alloc_data->handle) {
+ DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc);
+ alloc_data->handle = 0;
+ 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("ION MAP failed ");
+ buf_ion_info.ion_alloc_data = *alloc_data;
+ buf_ion_info.ion_device_fd = ion_device_fd;
+ buf_ion_info.fd_ion_data = *fd_data;
+ free_ion_memory(&buf_ion_info);
+ fd_data->fd =-1;
+ ion_device_fd =-1;
+ }
+ return ion_device_fd;
+}
+
+void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
+{
+ if (!buf_ion_info) {
+ DEBUG_PRINT_ERROR("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("ION free failed ");
+ return;
+ }
+ close(buf_ion_info->ion_device_fd);
+ buf_ion_info->ion_alloc_data.handle = 0;
+ 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) {
+ LEGACY_CAM_METADATA_TYPE *media_ptr;
+ struct pmem Input_pmem;
+ unsigned int index_pmem = 0;
+ bool meta_error = false;
+
+ index_pmem = (buffer - m_inp_mem_ptr);
+ if (mUsesColorConversion &&
+ (index_pmem < m_sInPortDef.nBufferCountActual)) {
+ if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) {
+ DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed");
+ }
+ } else {
+ media_ptr = (LEGACY_CAM_METADATA_TYPE *) buffer->pBuffer;
+ if (media_ptr && media_ptr->meta_handle) {
+ if (media_ptr->buffer_type == LEGACY_CAM_SOURCE &&
+ 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) {
+ VideoGrallocMetadata *media_ptr = (VideoGrallocMetadata *)buffer->pBuffer;
+ private_handle_t *handle = (private_handle_t *)media_ptr->pHandle;
+ Input_pmem.buffer = media_ptr;
+ Input_pmem.fd = handle->fd;
+ Input_pmem.offset = 0;
+ Input_pmem.size = handle->size;
+ } else {
+ meta_error = true;
+ }
+ if (!meta_error)
+ meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
+ if (meta_error) {
+ DEBUG_PRINT_HIGH("In batchmode or dev_free_buf failed, flush %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("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("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("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,
+ unsigned int flags)
+{
+ bool status = false;
+ pthread_mutex_lock(&c_lock);
+ if (!c2dcc) {
+ c2dcc = mConvertOpen(width, height, width, height,
+ src, dest, flags, src_stride);
+ if (c2dcc) {
+ src_format = src;
+ status = true;
+ } else
+ DEBUG_PRINT_ERROR("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_HIGH("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("Status of getbuffer is %d", cret);
+ ret = (cret)?false:true;
+ buf_size = bufferreq.size;
+ }
+ return ret;
+}
+
+bool omx_video::is_conv_needed(int hal_fmt, int hal_flags)
+{
+ bool bRet = false;
+
+ if (!strncmp(m_platform, "msm8996", 7)) {
+ bRet = hal_fmt == HAL_PIXEL_FORMAT_RGBA_8888 &&
+ !(hal_flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED);
+ } else {
+ bRet = hal_fmt == HAL_PIXEL_FORMAT_RGBA_8888;
+ }
+
+#ifdef _HW_RGBA
+ bRet = false;
+#endif
+ DEBUG_PRINT_LOW("RGBA conversion %s", bRet ? "Needed":"Not-Needed");
+ return bRet;
+}
+
+void omx_video::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
+ DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
+ prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
+}
+
+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;
+ VideoGrallocMetadata *media_buffer; // This method primarily assumes gralloc-metadata
+ private_handle_t *handle = NULL;
+ DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer);
+
+ if (buffer == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!dev_buffer_ready_to_queue(buffer)) {
+ DEBUG_PRINT_HIGH("Info: ETBProxyA: buffer[%p] is deffered", buffer);
+ return OMX_ErrorNone;
+ }
+
+ nBufIndex = buffer - meta_buffer_hdr;
+ if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
+ DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u",
+ nBufIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ media_buffer = (VideoGrallocMetadata *)buffer->pBuffer;
+ if (!media_buffer) {
+ DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
+ return OMX_ErrorBadParameter;
+ }
+ if ((media_buffer->eType == LEGACY_CAM_SOURCE)
+ && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
+ DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
+ buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
+ return OMX_ErrorBadParameter;
+ }
+
+ if (media_buffer && media_buffer->eType == LEGACY_CAM_SOURCE) {
+ return empty_this_buffer_proxy(hComp, buffer);
+ }
+
+ if ((!media_buffer || !media_buffer->pHandle || media_buffer->eType != kMetadataBufferTypeGrallocSource) &&
+ !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
+ DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
+ media_buffer);
+ m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
+ return OMX_ErrorBadParameter;
+ } else if (media_buffer) {
+ handle = (private_handle_t *)media_buffer->pHandle;
+ }
+
+ /*Enable following code once private handle color format is
+ updated correctly*/
+
+ if (buffer->nFilledLen > 0 && handle) {
+ if (c2d_opened && handle->format != c2d_conv.get_src_format()) {
+ c2d_conv.close();
+ c2d_opened = false;
+ }
+
+ if (!c2d_opened) {
+ mUsesColorConversion = is_conv_needed(handle->format, handle->flags);
+ if (mUsesColorConversion) {
+ DEBUG_PRINT_INFO("open Color conv forW: %u, H: %u",
+ (unsigned int)m_sInPortDef.format.video.nFrameWidth,
+ (unsigned int)m_sInPortDef.format.video.nFrameHeight);
+ if (!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
+ m_sInPortDef.format.video.nFrameWidth,
+ RGBA8888, NV12_128m, handle->width, handle->flags)) {
+ m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
+ DEBUG_PRINT_ERROR("Color conv open failed");
+ return OMX_ErrorBadParameter;
+ }
+ c2d_opened = true;
+#ifdef _MSM8974_
+ if (!dev_set_format(NV12_128m))
+ DEBUG_PRINT_ERROR("cannot set color format");
+#endif
+ }
+ }
+ }
+ if (input_flush_progress == true) {
+ m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
+ DEBUG_PRINT_ERROR("ERROR: 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 long)buffer,0,0)) {
+ DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full");
+ m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
+ ret = OMX_ErrorBadParameter;
+ }
+ }
+ return ret;
+}
+
+OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp,
+ struct pmem &Input_pmem_info)
+{
+
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ unsigned long address = 0,p2,id;
+
+ DEBUG_PRINT_LOW("In queue Meta Buffer");
+ if (!psource_frame || !pdest_frame) {
+ DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (psource_frame->nFilledLen > 0) {
+ if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
+ DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
+ post_event ((unsigned long)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;
+ }
+ } else {
+ // there has been an error and source frame has been scheduled for an EBD
+ psource_frame = NULL;
+ }
+ return ret;
+}
+
+OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
+ struct pmem &Input_pmem_info,unsigned long &index)
+{
+
+ unsigned char *uva;
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ unsigned long address = 0,p2,id;
+
+ DEBUG_PRINT_LOW("In Convert and queue Meta Buffer");
+ if (!psource_frame || !pdest_frame) {
+ DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
+ return OMX_ErrorBadParameter;
+ }
+ if (secure_session) {
+ DEBUG_PRINT_ERROR("cannot convert buffer during secure session");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (!psource_frame->nFilledLen) {
+ if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
+ pdest_frame->nFilledLen = psource_frame->nFilledLen;
+ pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
+ pdest_frame->nFlags = psource_frame->nFlags;
+ DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer "
+ "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen);
+ } else {
+ pdest_frame->nOffset = 0;
+ pdest_frame->nFilledLen = 0;
+ pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
+ pdest_frame->nFlags = psource_frame->nFlags;
+ DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
+ pdest_frame, (unsigned int)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("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("Buffer header %p Filled len size %u",
+ pdest_frame, (unsigned int)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("ERROR: in dev_use_buf");
+ post_event ((unsigned long)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("pdest_frame pop address is %p",pdest_frame);
+ }
+ } else {
+ // there has been an error and source frame has been scheduled for an EBD
+ psource_frame = NULL;
+ }
+ return ret;
+}
+
+OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
+{
+ unsigned long address = 0,p2,id, index = 0;
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+ DEBUG_PRINT_LOW("In push input buffer");
+ 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;
+ LEGACY_CAM_METADATA_TYPE *media_buffer;
+ index = pdest_frame - m_inp_mem_ptr;
+ if (index >= m_sInPortDef.nBufferCountActual) {
+ DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u",
+ (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual);
+ return OMX_ErrorBadParameter;
+ }
+
+ //Meta-Buffer with empty filled-length can contain garbage handle
+ //Some clients queue such buffers to signal EOS. Handle this case
+ // separately by queueing an intermediate color-conversion buffer
+ // and propagate the EOS.
+ if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
+ return push_empty_eos_buffer(hComp, psource_frame);
+ }
+ media_buffer = (LEGACY_CAM_METADATA_TYPE *)psource_frame->pBuffer;
+ /*Will enable to verify camcorder in current TIPS can be removed*/
+ if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
+ 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];
+ m_graphicbuffer_size = Input_pmem_info.size;
+ 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 {
+ VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)psource_frame->pBuffer;
+ private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
+ Input_pmem_info.buffer = media_buffer;
+ Input_pmem_info.fd = handle->fd;
+ Input_pmem_info.offset = 0;
+ Input_pmem_info.size = handle->size;
+ m_graphicbuffer_size = Input_pmem_info.size;
+ if (is_conv_needed(handle->format, handle->flags))
+ ret = convert_queue_buffer(hComp,Input_pmem_info,index);
+ else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
+ handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
+ handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
+ handle->format == HAL_PIXEL_FORMAT_RGBA_8888 ||
+ handle->format == QOMX_COLOR_Format32bitRGBA8888Compressed)
+ ret = queue_meta_buffer(hComp,Input_pmem_info);
+ else
+ ret = OMX_ErrorBadParameter;
+ }
+ }
+ return ret;
+}
+
+OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer) {
+ OMX_BUFFERHEADERTYPE* opqBuf = NULL;
+ OMX_ERRORTYPE retVal = OMX_ErrorNone;
+ unsigned index = 0;
+
+ DEBUG_PRINT_LOW("In push empty eos buffer");
+ do {
+ if (mUsesColorConversion) {
+ if (pdest_frame) {
+ //[1] use a checked out conversion buffer, if one is available
+ opqBuf = pdest_frame;
+ pdest_frame = NULL;
+ } else if (m_opq_pmem_q.m_size) {
+ //[2] else pop out one from the queue, if available
+ unsigned long address = 0, p2, id;
+ m_opq_pmem_q.pop_entry(&address,&p2,&id);
+ opqBuf = (OMX_BUFFERHEADERTYPE* ) address;
+ }
+ index = opqBuf - m_inp_mem_ptr;
+ } else {
+ opqBuf = (OMX_BUFFERHEADERTYPE* ) buffer;
+ index = opqBuf - meta_buffer_hdr;
+ }
+
+ if (!opqBuf || index >= m_sInPortDef.nBufferCountActual) {
+ DEBUG_PRINT_ERROR("push_empty_eos_buffer: Could not find a "
+ "color-conversion buffer to queue ! defer until available");
+ //[3] else, returning back will defer calling this function again
+ //until a conversion buffer is returned by the encoder and also
+ //hold on to the client's buffer
+ return OMX_ErrorNone;
+ }
+ struct pmem Input_pmem_info;
+ Input_pmem_info.buffer = opqBuf;
+ Input_pmem_info.fd = m_pInput_pmem[index].fd;
+ Input_pmem_info.offset = 0;
+ Input_pmem_info.size = m_pInput_pmem[index].size;
+
+ if (dev_use_buf(&Input_pmem_info, PORT_INDEX_IN, 0) != true) {
+ DEBUG_PRINT_ERROR("ERROR: in dev_use_buf for empty eos buffer");
+ retVal = OMX_ErrorBadParameter;
+ break;
+ }
+
+ //Queue with null pBuffer, as pBuffer in client's hdr can be junk
+ //Clone the color-conversion buffer to avoid overwriting original buffer
+ OMX_BUFFERHEADERTYPE emptyEosBufHdr;
+ memcpy(&emptyEosBufHdr, opqBuf, sizeof(OMX_BUFFERHEADERTYPE));
+ emptyEosBufHdr.nFilledLen = 0;
+ emptyEosBufHdr.nTimeStamp = buffer->nTimeStamp;
+ emptyEosBufHdr.nFlags = buffer->nFlags;
+ emptyEosBufHdr.pBuffer = NULL;
+ if (!mUsesColorConversion)
+ emptyEosBufHdr.nAllocLen =
+ m_graphicbuffer_size ? m_graphicbuffer_size : m_sInPortDef.nBufferSize;
+
+ if (dev_empty_buf(&emptyEosBufHdr, 0, index, m_pInput_pmem[index].fd) != true) {
+ DEBUG_PRINT_ERROR("ERROR: in dev_empty_buf for empty eos buffer");
+ dev_free_buf(&Input_pmem_info, PORT_INDEX_IN);
+ retVal = OMX_ErrorBadParameter;
+ break;
+ }
+ mEmptyEosBuffer = opqBuf;
+ } while(false);
+
+ //return client's buffer regardless since intermediate color-conversion
+ //buffer is sent to the the encoder
+ m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
+ --pending_input_buffers;
+ return retVal;
+}
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
new file mode 100644
index 0000000..6c087ff
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -0,0 +1,2698 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2016, 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 <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <dlfcn.h>
+#ifdef _ANDROID_ICS_
+#include <media/hardware/HardwareAPI.h>
+#endif
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#endif
+#ifndef _ANDROID_
+#include <glib.h>
+#define strlcpy g_strlcpy
+#endif
+
+extern int m_pipe;
+static int bframes;
+static int entropy;
+static int perfmode;
+static int lowlatency;
+// factory function executed by the core to create instances
+void *get_omx_component_factory_fn(void)
+{
+ return(new omx_venc);
+}
+
+omx_venc::perf_control::perf_control()
+{
+ m_perf_lib = NULL;
+ m_perf_lock_acquire = NULL;
+ m_perf_lock_release = NULL;
+ m_perf_handle = 0;
+}
+
+omx_venc::perf_control::~perf_control()
+{
+ if (m_perf_handle != 0 && m_perf_lock_release) {
+ m_perf_lock_release(m_perf_handle);
+ }
+ if (m_perf_lib) {
+ dlclose(m_perf_lib);
+ }
+}
+
+void omx_venc::perf_control::send_hint_to_mpctl(bool state)
+{
+ if (load_lib() == false) {
+ return;
+ }
+ /* 0x4601 maps to video encode callback in
+ * perflock, 46 is the enum number, 01 is
+ * the state being sent when perflock
+ * acquire succeeds
+ */
+ int arg = 0x4601;
+
+ if (m_perf_lock_acquire && state == true) {
+ m_perf_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int));
+ DEBUG_PRINT_INFO("Video encode perflock acquired,handle=%d",m_perf_handle);
+ } else if (m_perf_lock_release && state == false) {
+ m_perf_lock_release(m_perf_handle);
+ DEBUG_PRINT_INFO("Video encode perflock released");
+ }
+}
+
+bool omx_venc::perf_control::load_lib()
+{
+ char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
+ if (m_perf_lib)
+ return true;
+
+ if ((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
+ DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
+ goto handle_err;
+ }
+ if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
+ DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
+ goto handle_err;
+ } else {
+ m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
+ if (m_perf_lock_acquire == NULL) {
+ DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
+ goto handle_err;
+ }
+ m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
+ if (m_perf_lock_release == NULL) {
+ DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
+ goto handle_err;
+ }
+ }
+ return true;
+
+handle_err:
+ if(m_perf_lib != NULL) {
+ dlclose(m_perf_lib);
+ }
+ return false;
+}
+
+//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
+ bframes = entropy = 0;
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+ property_get("vidc.debug.level", property_value, "1");
+ debug_level = atoi(property_value);
+ property_value[0] = '\0';
+ property_get("vidc.debug.bframes", property_value, "0");
+ bframes = atoi(property_value);
+ property_value[0] = '\0';
+ property_get("vidc.debug.entropy", property_value, "1");
+ entropy = !!atoi(property_value);
+ property_value[0] = '\0';
+ property_get("vidc.debug.perf.mode", property_value, "0");
+ perfmode = atoi(property_value);
+ property_value[0] = '\0';
+ handle = NULL;
+ property_get("vidc.debug.lowlatency", property_value, "0");
+ lowlatency = atoi(property_value);
+ property_value[0] = '\0';
+ m_perf_control.send_hint_to_mpctl(true);
+}
+
+omx_venc::~omx_venc()
+{
+ get_syntaxhdr_enable = false;
+ m_perf_control.send_hint_to_mpctl(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("omx_venc(): Inside component_init()");
+ // Copy the role information which provides the decoder m_nkind
+ strlcpy((char *)m_nkind,role,OMX_MAX_STRINGNAME_SIZE);
+ secure_session = false;
+
+ if (!strncmp((char *)m_nkind,"OMX.qcom.video.encoder.mpeg4",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_encoder.mpeg4",\
+ OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingMPEG4;
+ } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.h263",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingH263;
+ } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingAVC;
+ } else if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc.secure",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingAVC;
+ secure_session = true;
+ }
+#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_CodingVP8;
+ }
+#endif
+ else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc", \
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingHEVC;
+ } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc.secure", \
+ OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char *)m_cRole, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
+ codec_type = OMX_VIDEO_CodingHEVC;
+ secure_session = true;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unknown Component");
+ 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("ERROR: handle is NULL");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ if (handle->venc_open(codec_type) != true) {
+ DEBUG_PRINT_ERROR("ERROR: venc_open failed");
+ eRet = OMX_ErrorInsufficientResources;
+ goto init_error;
+ }
+
+ //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_OUT;
+ m_sConfigFrameRotation.nRotation = 0;
+
+ OMX_INIT_STRUCT(&m_sConfigAVCIDRPeriod, OMX_VIDEO_CONFIG_AVCINTRAPERIOD);
+ m_sConfigAVCIDRPeriod.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+
+ OMX_INIT_STRUCT(&m_sPrependSPSPPS, PrependSPSPPSToIDRFramesParams);
+ m_sPrependSPSPPS.bEnable = OMX_FALSE;
+
+ 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);
+ OMX_INIT_STRUCT(&m_sSessionIPBQPRange, OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE);
+ m_sSessionQPRange.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sSessionIPBQPRange.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;
+ }
+ m_sSessionIPBQPRange.minIQP =
+ m_sSessionIPBQPRange.minPQP =
+ m_sSessionIPBQPRange.minBQP = m_sSessionQPRange.minQP;
+ m_sSessionIPBQPRange.maxIQP =
+ m_sSessionIPBQPRange.maxPQP =
+ m_sSessionIPBQPRange.maxBQP = m_sSessionQPRange.maxQP;
+ 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;
+
+#ifdef SUPPORT_CONFIG_INTRA_REFRESH
+ OMX_INIT_STRUCT(&m_sConfigIntraRefresh, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE);
+ m_sConfigIntraRefresh.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sConfigIntraRefresh.nRefreshPeriod = 0;
+#endif
+
+ OMX_INIT_STRUCT(&m_sConfigColorAspects, DescribeColorAspectsParams);
+ m_sConfigColorAspects.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sConfigColorAspects.sAspects.mRange = ColorAspects::RangeUnspecified;
+ m_sConfigColorAspects.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
+ m_sConfigColorAspects.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
+ m_sConfigColorAspects.sAspects.mTransfer = ColorAspects::TransferUnspecified;
+
+ 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;
+ } else if (codec_type == OMX_VIDEO_CodingVP8) {
+ m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_VP8ProfileMain;
+ m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_VP8Level_Version0;
+ } else if (codec_type == OMX_VIDEO_CodingHEVC) {
+ m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_HEVCProfileMain;
+ m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_HEVCMainTierLevel1;
+ }
+
+ OMX_INIT_STRUCT(&m_sParamEntropy, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
+ m_sParamEntropy.bCabac = OMX_FALSE;
+
+ // 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 = (char *)"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_FORMATTYPE)
+ QOMX_DEFAULT_COLOR_FMT;
+ 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;
+ goto init_error;
+ }
+
+ // 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 if (codec_type == OMX_VIDEO_CodingAVC) {
+ m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ } else if (codec_type == OMX_VIDEO_CodingVP8) {
+ m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8;
+ } else if (codec_type == OMX_VIDEO_CodingHEVC) {
+ m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingHEVC;
+ }
+
+ 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_FORMATTYPE)
+ QOMX_DEFAULT_COLOR_FMT;
+ 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 if (codec_type == OMX_VIDEO_CodingAVC) {
+ m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingAVC;
+ } else if (codec_type == OMX_VIDEO_CodingVP8) {
+ m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingVP8;
+ } else if (codec_type == OMX_VIDEO_CodingHEVC) {
+ m_sOutPortFormat.eCompressionFormat = OMX_VIDEO_CodingHEVC;
+ }
+
+ // 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;
+
+ OMX_INIT_STRUCT(&m_sParamInitqp, QOMX_EXTNINDEX_VIDEO_INITIALQP);
+ m_sParamInitqp.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.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;
+
+ // VP8 specific init
+ OMX_INIT_STRUCT(&m_sParamVP8, OMX_VIDEO_PARAM_VP8TYPE);
+ m_sParamVP8.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamVP8.eProfile = OMX_VIDEO_VP8ProfileMain;
+ m_sParamVP8.eLevel = OMX_VIDEO_VP8Level_Version0;
+ m_sParamVP8.nDCTPartitions = 0;
+ m_sParamVP8.bErrorResilientMode = OMX_FALSE;
+
+ // HEVC specific init
+ OMX_INIT_STRUCT(&m_sParamHEVC, OMX_VIDEO_PARAM_HEVCTYPE);
+ m_sParamHEVC.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamHEVC.eProfile = OMX_VIDEO_HEVCProfileMain;
+ m_sParamHEVC.eLevel = OMX_VIDEO_HEVCMainTierLevel1;
+
+ 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;
+
+ OMX_INIT_STRUCT(&m_sParamLTRCount, QOMX_VIDEO_PARAM_LTRCOUNT_TYPE);
+ m_sParamLTRCount.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sParamLTRCount.nCount = 0;
+
+ OMX_INIT_STRUCT(&m_sConfigDeinterlace, OMX_VIDEO_CONFIG_DEINTERLACE);
+ m_sConfigDeinterlace.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sConfigDeinterlace.nEnable = OMX_FALSE;
+
+ OMX_INIT_STRUCT(&m_sHierLayers, QOMX_VIDEO_HIERARCHICALLAYERS);
+ m_sHierLayers.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sHierLayers.nNumLayers = 0;
+ m_sHierLayers.eHierarchicalCodingType = QOMX_HIERARCHICALCODING_P;
+
+ OMX_INIT_STRUCT(&m_sMBIStatistics, OMX_QOMX_VIDEO_MBI_STATISTICS);
+ m_sMBIStatistics.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+ m_sMBIStatistics.eMBIStatisticsType = QOMX_MBI_STATISTICS_MODE_DEFAULT;
+
+ OMX_INIT_STRUCT(&m_slowLatencyMode, QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE);
+ m_slowLatencyMode.bLowLatencyMode = OMX_FALSE;
+
+ OMX_INIT_STRUCT(&m_sParamTemporalLayers, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ m_sParamTemporalLayers.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+
+ OMX_INIT_STRUCT(&m_sConfigTemporalLayers, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
+
+ m_state = OMX_StateLoaded;
+ m_sExtraData = 0;
+
+ if (eRet == OMX_ErrorNone) {
+ if (pipe(fds)) {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
+ eRet = OMX_ErrorInsufficientResources;
+ } else {
+ if (fds[0] == 0 || fds[1] == 0) {
+ if (pipe(fds)) {
+ DEBUG_PRINT_ERROR("ERROR: pipe creation failed");
+ 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_enc, 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);
+ }
+ }
+
+ if (perfmode) {
+ QOMX_EXTNINDEX_VIDEO_PERFMODE pParam;
+ pParam.nPerfMode = perfmode;
+ DEBUG_PRINT_LOW("Perfmode = 0x%x", pParam.nPerfMode);
+ if (!handle->venc_set_config(&pParam, (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoVencPerfMode))
+ DEBUG_PRINT_ERROR("Failed setting PerfMode to %d", pParam.nPerfMode);
+ }
+
+ if (lowlatency)
+ {
+ QOMX_ENABLETYPE low_latency;
+ low_latency.bEnable = OMX_TRUE;
+ DEBUG_PRINT_LOW("Enable lowlatency mode");
+ if (!handle->venc_set_param(&low_latency,
+ (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoVencLowLatencyMode)) {
+ DEBUG_PRINT_ERROR("Failed enabling low latency mode");
+ }
+ }
+ DEBUG_PRINT_INFO("Component_init : %s : return = 0x%x", m_nkind, eRet);
+ return eRet;
+init_error:
+ handle->venc_close();
+ delete handle;
+ handle = NULL;
+ return eRet;
+}
+
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::Setparameter
+
+ DESCRIPTION
+ OMX Set Parameter method implementation.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_venc::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_IN OMX_PTR paramData)
+{
+ (void)hComp;
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+
+ if (m_state == OMX_StateInvalid) {
+ DEBUG_PRINT_ERROR("ERROR: Set Param in Invalid State");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData");
+ 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");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ switch ((int)paramIndex) {
+ case OMX_IndexParamPortDefinition:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
+ (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");
+ omx_report_unsupported_setting();
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_LOW("i/p actual cnt requested = %u", (unsigned int)portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("i/p min cnt requested = %u", (unsigned int)portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("i/p buffersize requested = %u", (unsigned int)portDefn->nBufferSize);
+ if (portDefn->nBufferCountActual > MAX_NUM_INPUT_BUFFERS) {
+ DEBUG_PRINT_ERROR("ERROR: (In_PORT) actual count (%u) exceeds max(%u)",
+ (unsigned int)portDefn->nBufferCountActual, (unsigned int)MAX_NUM_INPUT_BUFFERS);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (m_inp_mem_ptr &&
+ (portDefn->nBufferCountActual != m_sInPortDef.nBufferCountActual ||
+ portDefn->nBufferSize != m_sInPortDef.nBufferSize)) {
+ DEBUG_PRINT_ERROR("ERROR: (In_PORT) buffer count/size can change only if port is unallocated !");
+ return OMX_ErrorInvalidState;
+ }
+ if (portDefn->nBufferCountMin > portDefn->nBufferCountActual) {
+ DEBUG_PRINT_ERROR("ERROR: (In_PORT) Min buffers (%u) > actual count (%u)",
+ (unsigned int)portDefn->nBufferCountMin, (unsigned int)portDefn->nBufferCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) {
+ DEBUG_PRINT_ERROR("ERROR: venc_set_param input failed");
+ return handle->hw_overload ? OMX_ErrorInsufficientResources :
+ OMX_ErrorUnsupportedSetting;
+ }
+
+ DEBUG_PRINT_LOW("i/p previous actual cnt = %u", (unsigned int)m_sInPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("i/p previous min cnt = %u", (unsigned int)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_FORMATTYPE)
+ QOMX_DEFAULT_COLOR_FMT;
+ if (!mUseProxyColorFormat) {
+ if (!c2d_conv.init()) {
+ DEBUG_PRINT_ERROR("C2D init failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_HIGH("C2D 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("o/p actual cnt requested = %u", (unsigned int)portDefn->nBufferCountActual);
+ DEBUG_PRINT_LOW("o/p min cnt requested = %u", (unsigned int)portDefn->nBufferCountMin);
+ DEBUG_PRINT_LOW("o/p buffersize requested = %u", (unsigned int)portDefn->nBufferSize);
+
+ if (portDefn->nBufferCountActual > MAX_NUM_OUTPUT_BUFFERS) {
+ DEBUG_PRINT_ERROR("ERROR: (Out_PORT) actual count (%u) exceeds max(%u)",
+ (unsigned int)portDefn->nBufferCountActual, (unsigned int)MAX_NUM_OUTPUT_BUFFERS);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (m_out_mem_ptr &&
+ (portDefn->nBufferCountActual != m_sOutPortDef.nBufferCountActual ||
+ portDefn->nBufferSize != m_sOutPortDef.nBufferSize)) {
+ DEBUG_PRINT_ERROR("ERROR: (Out_PORT) buffer count/size can change only if port is unallocated !");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (portDefn->nBufferCountMin > portDefn->nBufferCountActual) {
+ DEBUG_PRINT_ERROR("ERROR: (Out_PORT) Min buffers (%u) > actual count (%u)",
+ (unsigned int)portDefn->nBufferCountMin, (unsigned int)portDefn->nBufferCountActual);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (handle->venc_set_param(paramData,OMX_IndexParamPortDefinition) != true) {
+ DEBUG_PRINT_ERROR("ERROR: venc_set_param output failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sOutPortDef,portDefn,sizeof(struct OMX_PARAM_PORTDEFINITIONTYPE));
+#ifdef _MSM8974_
+ /*Query ouput Buffer Requirements*/
+ dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
+ &m_sOutPortDef.nBufferCountActual,
+ &m_sOutPortDef.nBufferSize,
+ m_sOutPortDef.nPortIndex);
+#endif
+ update_profile_level(); //framerate , bitrate
+
+ DEBUG_PRINT_LOW("o/p previous actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferCountActual);
+ DEBUG_PRINT_LOW("o/p previous min cnt = %u", (unsigned int)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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
+ OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
+ (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d",
+ 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",
+ portFmt->eColorFormat);
+ update_profile_level(); //framerate
+
+#ifdef _ANDROID_ICS_
+ if (portFmt->eColorFormat ==
+ (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque) {
+ m_sInPortFormat.eColorFormat = (OMX_COLOR_FORMATTYPE)
+ QOMX_DEFAULT_COLOR_FMT;
+ if (!mUseProxyColorFormat) {
+ if (!c2d_conv.init()) {
+ DEBUG_PRINT_ERROR("C2D init failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ DEBUG_PRINT_HIGH("C2D init is successful");
+ }
+ mUseProxyColorFormat = true;
+ m_input_msg_id = OMX_COMPONENT_GENERATE_ETB_OPQ;
+ } else
+#endif
+ {
+ m_sInPortFormat.eColorFormat = portFmt->eColorFormat;
+ m_sInPortDef.format.video.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
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
+ OMX_PORT_PARAM_TYPE* pParam = (OMX_PORT_PARAM_TYPE*)(paramData);
+ DEBUG_PRINT_LOW("Set OMX_IndexParamVideoInit called");
+ break;
+ }
+
+ case OMX_IndexParamVideoBitrate:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_BITRATETYPE);
+ 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;
+ /* RC mode chan chage buffer requirements on Input port */
+ dev_get_buf_req(&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ m_sInPortDef.nPortIndex);
+ DEBUG_PRINT_LOW("bitrate = %u", (unsigned int)m_sOutPortDef.format.video.nBitrate);
+ break;
+ }
+ case OMX_IndexParamVideoMpeg4:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_MPEG4TYPE);
+ 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 _MSM8974_
+ if (pParam->nBFrames || bframes)
+ mp4_param.nBFrames = 1;
+ else
+ mp4_param.nBFrames = 0;
+ DEBUG_PRINT_HIGH("MPEG4: %u BFrames are being set", (unsigned int)mp4_param.nBFrames);
+#endif
+ } else {
+ if (pParam->nBFrames) {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported");
+ 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;
+ if (pParam->nBFrames || bframes)
+ m_sIntraperiod.nBFrames = m_sParamMPEG4.nBFrames = mp4_param.nBFrames;
+ else
+ 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_AVCTYPE);
+ 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");
+
+ avc_param.nBFrames = 0;
+ if ((pParam->eProfile == OMX_VIDEO_AVCProfileHigh)||
+ (pParam->eProfile == OMX_VIDEO_AVCProfileMain)) {
+
+ if (pParam->nBFrames) {
+ avc_param.nBFrames = pParam->nBFrames;
+ DEBUG_PRINT_LOW("B frames set using Client setparam to %d",
+ avc_param.nBFrames);
+ }
+
+ if (bframes ) {
+ avc_param.nBFrames = bframes;
+ DEBUG_PRINT_LOW("B frames set using setprop to %d",
+ avc_param.nBFrames);
+ }
+
+ DEBUG_PRINT_HIGH("AVC: BFrames: %u", (unsigned int)avc_param.nBFrames);
+ avc_param.bEntropyCodingCABAC = (OMX_BOOL)(avc_param.bEntropyCodingCABAC && entropy);
+ avc_param.nCabacInitIdc = entropy ? avc_param.nCabacInitIdc : 0;
+ } else {
+ if (pParam->nBFrames) {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported");
+ }
+ }
+
+ 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;
+ if (pParam->nBFrames || bframes)
+ m_sIntraperiod.nBFrames = m_sParamAVC.nBFrames = avc_param.nBFrames;
+ else
+ m_sIntraperiod.nBFrames = m_sParamAVC.nBFrames;
+ break;
+ }
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_VP8TYPE);
+ OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
+ OMX_VIDEO_PARAM_VP8TYPE vp8_param;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoVp8");
+ if (pParam->nDCTPartitions != m_sParamVP8.nDCTPartitions ||
+ pParam->bErrorResilientMode != m_sParamVP8.bErrorResilientMode) {
+ DEBUG_PRINT_ERROR("VP8 doesn't support nDCTPartitions or bErrorResilientMode");
+ }
+ memcpy(&vp8_param, pParam, sizeof( struct OMX_VIDEO_PARAM_VP8TYPE));
+ if (handle->venc_set_param(&vp8_param, (OMX_INDEXTYPE)OMX_IndexParamVideoVp8) != true) {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamVP8,pParam, sizeof(struct OMX_VIDEO_PARAM_VP8TYPE));
+ break;
+ }
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_HEVCTYPE);
+ OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
+ OMX_VIDEO_PARAM_HEVCTYPE hevc_param;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoHevc");
+ memcpy(&hevc_param, pParam, sizeof( struct OMX_VIDEO_PARAM_HEVCTYPE));
+ if (handle->venc_set_param(&hevc_param, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc) != true) {
+ DEBUG_PRINT_ERROR("Failed : set_parameter: OMX_IndexParamVideoHevc");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamHEVC, pParam, sizeof(struct OMX_VIDEO_PARAM_HEVCTYPE));
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
+ 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: %u "
+ "Level :%u", (unsigned int)pParam->eProfile, (unsigned int)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("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("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("AVC profile = %d, level = %d", m_sParamAVC.eProfile,
+ m_sParamAVC.eLevel);
+ } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc.secure",\
+ 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);
+ }
+ else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ m_sParamVP8.eProfile = (OMX_VIDEO_VP8PROFILETYPE)m_sParamProfileLevel.eProfile;
+ m_sParamVP8.eLevel = (OMX_VIDEO_VP8LEVELTYPE)m_sParamProfileLevel.eLevel;
+ DEBUG_PRINT_LOW("VP8 profile = %d, level = %d", m_sParamVP8.eProfile,
+ m_sParamVP8.eLevel);
+ }
+ else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ m_sParamHEVC.eProfile = (OMX_VIDEO_HEVCPROFILETYPE)m_sParamProfileLevel.eProfile;
+ m_sParamHEVC.eLevel = (OMX_VIDEO_HEVCLEVELTYPE)m_sParamProfileLevel.eLevel;
+ DEBUG_PRINT_LOW("HEVC profile = %d, level = %d", m_sParamHEVC.eProfile,
+ m_sParamHEVC.eLevel);
+ }
+
+ break;
+ }
+ case OMX_IndexParamStandardComponentRole:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
+ 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");
+ 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", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc.secure",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", 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", 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", comp_role->cRole);
+ eRet =OMX_ErrorUnsupportedSetting;
+ }
+ }
+#endif
+ else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc",OMX_MAX_STRINGNAME_SIZE)) {
+ if (!strncmp((const char*)comp_role->cRole,"video_encoder.hevc",OMX_MAX_STRINGNAME_SIZE)) {
+ strlcpy((char*)m_cRole,"video_encoder.hevc",OMX_MAX_STRINGNAME_SIZE);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ }
+
+ else {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", m_nkind);
+ eRet = OMX_ErrorInvalidComponentName;
+ }
+ break;
+ }
+
+ case OMX_IndexParamPriorityMgmt:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt");
+ if (m_state != OMX_StateLoaded) {
+ DEBUG_PRINT_ERROR("ERROR: Set Parameter called in Invalid State");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
+ (unsigned int)priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
+ (unsigned int)priorityMgmtype->nGroupPriority);
+
+ m_sPriorityMgmt.nGroupID = priorityMgmtype->nGroupID;
+ m_sPriorityMgmt.nGroupPriority = priorityMgmtype->nGroupPriority;
+
+ break;
+ }
+
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier");
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
+ bufferSupplierType->eBufferSupplier);
+ if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
+ m_sInBufSupplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
+
+ else
+
+ eRet = OMX_ErrorBadPortIndex;
+
+ break;
+
+ }
+ case OMX_IndexParamVideoQuantization:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoQuantization");
+ 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;
+ m_sSessionQuantization.nQpB = session_qp->nQpB;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port Index for Session QP setting");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoQPRange:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_QPRANGETYPE);
+ DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoQPRange");
+ 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("ERROR: Unsupported port Index for QP range setting");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoIPBQPRange:
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE");
+ OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *qp_range = (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE*) paramData;
+ if (qp_range->nPortIndex == PORT_INDEX_OUT) {
+ if (handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexParamVideoIPBQPRange) != true) {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sSessionIPBQPRange.minIQP = qp_range->minIQP;
+ m_sSessionIPBQPRange.maxIQP = qp_range->maxIQP;
+ m_sSessionIPBQPRange.minPQP = qp_range->minPQP;
+ m_sSessionIPBQPRange.maxPQP = qp_range->maxPQP;
+ m_sSessionIPBQPRange.minBQP = qp_range->minBQP;
+ m_sSessionIPBQPRange.maxBQP = qp_range->maxBQP;
+ } else {
+ DEBUG_PRINT_ERROR("Unsupported port Index for IPB QP range setting");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_QcomIndexPortDefn:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
+ 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE);
+ DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection");
+ OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* pParam =
+ (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
+ if (!handle->venc_set_param(paramData, OMX_IndexParamVideoErrorCorrection)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting Error Resilience failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sErrorCorrection,pParam, sizeof(m_sErrorCorrection));
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_INTRAREFRESHTYPE);
+ DEBUG_PRINT_LOW("set_param:OMX_IndexParamVideoIntraRefresh");
+ OMX_VIDEO_PARAM_INTRAREFRESHTYPE* pParam =
+ (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
+ if (!handle->venc_set_param(paramData,OMX_IndexParamVideoIntraRefresh)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra refresh failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sIntraRefresh, pParam, sizeof(m_sIntraRefresh));
+ break;
+ }
+#ifdef _ANDROID_ICS_
+ case OMX_QcomIndexParamVideoMetaBufferMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
+ StoreMetaDataInBuffersParams *pParam =
+ (StoreMetaDataInBuffersParams*)paramData;
+ DEBUG_PRINT_HIGH("set_parameter:OMX_QcomIndexParamVideoMetaBufferMode: "
+ "port_index = %u, meta_mode = %d", (unsigned int)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("ERROR: set Metabuffer mode %d fail",
+ pParam->bStoreMetaData);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ meta_mode_enable = pParam->bStoreMetaData;
+ if (meta_mode_enable) {
+ m_sInPortDef.nBufferCountActual = m_sInPortDef.nBufferCountMin;
+ if (handle->venc_set_param(&m_sInPortDef,OMX_IndexParamPortDefinition) != true) {
+ DEBUG_PRINT_ERROR("ERROR: 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 if (pParam->nPortIndex == PORT_INDEX_OUT && secure_session) {
+ 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;
+ }
+ } 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
+ DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamIndexExtraDataType");
+ QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
+ bool enable = false;
+ OMX_U32 mask = 0;
+
+ if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) {
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ mask = VENC_EXTRADATA_SLICEINFO;
+
+ DEBUG_PRINT_HIGH("SliceInfo extradata %s",
+ ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
+ } else {
+ DEBUG_PRINT_ERROR("set_parameter: Slice information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderMBInfo) {
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ mask = VENC_EXTRADATA_MBINFO;
+
+ DEBUG_PRINT_HIGH("MBInfo extradata %s",
+ ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
+ } else {
+ DEBUG_PRINT_ERROR("set_parameter: MB information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataFrameDimension) {
+ if (pParam->nPortIndex == PORT_INDEX_IN) {
+ mask = VENC_EXTRADATA_FRAMEDIMENSION;
+ DEBUG_PRINT_HIGH("Frame dimension extradata %s",
+ ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
+ } else {
+ DEBUG_PRINT_ERROR("set_parameter: Frame Dimension is "
+ "valid for input port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ } else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_QTIIndexParamVQZipSEIExtraData) {
+ if (pParam->nPortIndex == PORT_INDEX_IN) {
+ mask = VENC_EXTRADATA_VQZIP;
+ DEBUG_PRINT_HIGH("VQZIP extradata %s",
+ ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
+ } else {
+ DEBUG_PRINT_ERROR("set_parameter: VQZIP is "
+ "valid for input port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+
+#ifndef _MSM8974_
+ else if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoLTRInfo) {
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ if (pParam->bEnabled == OMX_TRUE)
+ mask = VEN_EXTRADATA_LTRINFO;
+
+ DEBUG_PRINT_HIGH("LTRInfo extradata %s",
+ ((pParam->bEnabled == OMX_TRUE) ? "enabled" : "disabled"));
+ } else {
+ DEBUG_PRINT_ERROR("set_parameter: LTR information is "
+ "valid for output port only");
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ }
+#endif
+ else {
+ DEBUG_PRINT_ERROR("set_parameter: unsupported extrdata index (%x)",
+ pParam->nIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+
+
+ if (pParam->bEnabled == OMX_TRUE)
+ m_sExtraData |= mask;
+ else
+ m_sExtraData &= ~mask;
+
+ enable = !!(m_sExtraData & mask);
+ if (handle->venc_set_param(&enable,
+ (OMX_INDEXTYPE)pParam->nIndex) != true) {
+ DEBUG_PRINT_ERROR("ERROR: Setting Extradata (%x) failed", pParam->nIndex);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ if (pParam->nPortIndex == PORT_INDEX_IN) {
+ m_sInPortDef.nPortIndex = PORT_INDEX_IN;
+ dev_get_buf_req(&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ m_sInPortDef.nPortIndex);
+ DEBUG_PRINT_HIGH("updated in_buf_req: buffer cnt=%u, "
+ "count min=%u, buffer size=%u",
+ (unsigned int)m_sOutPortDef.nBufferCountActual,
+ (unsigned int)m_sOutPortDef.nBufferCountMin,
+ (unsigned int)m_sOutPortDef.nBufferSize);
+
+ } 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=%u, "
+ "count min=%u, buffer size=%u",
+ (unsigned int)m_sOutPortDef.nBufferCountActual,
+ (unsigned int)m_sOutPortDef.nBufferCountMin,
+ (unsigned int)m_sOutPortDef.nBufferSize);
+ }
+ break;
+ }
+ case QOMX_IndexParamVideoLTRMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_PARAM_LTRMODE_TYPE);
+ 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("ERROR: Setting LTR mode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamLTRMode, pParam, sizeof(m_sParamLTRMode));
+ break;
+ }
+ case QOMX_IndexParamVideoLTRCount:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_PARAM_LTRCOUNT_TYPE);
+ 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("ERROR: Setting LTR count failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamLTRCount, pParam, sizeof(m_sParamLTRCount));
+ break;
+ }
+#endif
+ case OMX_QcomIndexParamVideoMaxAllowedBitrateCheck:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE);
+ 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(%u)", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+#ifdef MAX_RES_1080P
+ case OMX_QcomIndexEnableSliceDeliveryMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE);
+ 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(%u)", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+#endif
+ case OMX_QcomIndexEnableH263PlusPType:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_PARAMTYPE);
+ 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(%u)", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamSequenceHeaderWithIDR:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, PrependSPSPPSToIDRFramesParams);
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR)) {
+ DEBUG_PRINT_ERROR("%s: %s",
+ "OMX_QComIndexParamSequenceHeaderWithIDR:",
+ "request for inband sps/pps failed.");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sPrependSPSPPS, paramData, sizeof(m_sPrependSPSPPS));
+ break;
+ }
+ case OMX_QcomIndexParamH264AUDelimiter:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_CONFIG_H264_AUD);
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexParamH264AUDelimiter)) {
+ DEBUG_PRINT_ERROR("%s: %s",
+ "OMX_QComIndexParamh264AUDelimiter:",
+ "request for AU Delimiters failed.");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamMBIStatisticsMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QOMX_VIDEO_MBI_STATISTICS);
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexParamMBIStatisticsMode)) {
+ DEBUG_PRINT_ERROR("%s: %s",
+ "OMX_QcomIndexParamMBIStatisticsMode:",
+ "MBI Statistics mode setting failed.");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexHierarchicalStructure:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_HIERARCHICALLAYERS);
+ QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
+ (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
+ DEBUG_PRINT_LOW("OMX_QcomIndexHierarchicalStructure");
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexHierarchicalStructure)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if((pParam->eHierarchicalCodingType == QOMX_HIERARCHICALCODING_B) && pParam->nNumLayers)
+ hier_b_enabled = true;
+ m_sHierLayers.nNumLayers = pParam->nNumLayers;
+ m_sHierLayers.eHierarchicalCodingType = pParam->eHierarchicalCodingType;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: OMX_QcomIndexHierarchicalStructure called on wrong port(%u)",
+ (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+
+ }
+ case OMX_QcomIndexParamPerfLevel:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PERF_LEVEL);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE) OMX_QcomIndexParamPerfLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting performance level");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamH264VUITimingInfo:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE) OMX_QcomIndexParamH264VUITimingInfo)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting VUI timing info");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamPeakBitrate:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE) OMX_QcomIndexParamPeakBitrate)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting peak bitrate");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case QOMX_IndexParamVideoInitialQp:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_INITIALQP);
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)QOMX_IndexParamVideoInitialQp)) {
+ DEBUG_PRINT_ERROR("Request to Enable initial QP failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sParamInitqp, paramData, sizeof(m_sParamInitqp));
+ break;
+ }
+ case OMX_QcomIndexParamSetMVSearchrange:
+ {
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE) OMX_QcomIndexParamSetMVSearchrange)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting Searchrange");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamVideoHybridHierpMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE);
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexParamVideoHybridHierpMode)) {
+ DEBUG_PRINT_ERROR("Request to Enable Hybrid Hier-P failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamBatchSize:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_U32TYPE);
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexParamBatchSize)) {
+ DEBUG_PRINT_ERROR("Attempting to set batch size failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigH264EntropyCodingCabac:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexConfigH264EntropyCodingCabac)) {
+ DEBUG_PRINT_ERROR("Attempting to set Entropy failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QTIIndexParamVQZIPSEIType:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE) OMX_QTIIndexParamVQZIPSEIType)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting VQZIP SEI type");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sExtraData |= VENC_EXTRADATA_VQZIP;
+ break;
+ }
+ case OMX_QcomIndexParamVencAspectRatio:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTNINDEX_VIDEO_VENC_SAR);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexParamVencAspectRatio)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sSar, paramData, sizeof(m_sSar));
+ break;
+ }
+ case OMX_QTIIndexParamLowLatencyMode:
+ {
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamLowLatencyMode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_slowLatencyMode, paramData, sizeof(m_slowLatencyMode));
+ break;
+ }
+ case OMX_QcomIndexConfigVideoVencLowLatencyMode:
+ {
+ if(!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoVencLowLatencyMode)) {
+ DEBUG_PRINT_ERROR("Request to Enable Low latency mode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QTIIndexParamVideoEnableRoiInfo:
+ {
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableRoiInfo)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sExtraData |= VENC_EXTRADATA_ROI;
+ break;
+ }
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE);
+ if (!handle->venc_set_param(paramData,
+ (OMX_INDEXTYPE)OMX_IndexParamAndroidVideoTemporalLayering)) {
+ DEBUG_PRINT_ERROR("Failed to configure temporal layers");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ // save the actual configuration applied
+ memcpy(&m_sParamTemporalLayers, paramData, sizeof(m_sParamTemporalLayers));
+ // keep the config data in sync
+ m_sConfigTemporalLayers.ePattern = m_sParamTemporalLayers.ePattern;
+ m_sConfigTemporalLayers.nBLayerCountActual = m_sParamTemporalLayers.nBLayerCountActual;
+ m_sConfigTemporalLayers.nPLayerCountActual = m_sParamTemporalLayers.nPLayerCountActual;
+ m_sConfigTemporalLayers.bBitrateRatiosSpecified = m_sParamTemporalLayers.bBitrateRatiosSpecified;
+ memcpy(&m_sConfigTemporalLayers.nBitrateRatios[0],
+ &m_sParamTemporalLayers.nBitrateRatios[0],
+ OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS * sizeof(OMX_U32));
+ break;
+ }
+ case OMX_IndexParamVideoSliceFMO:
+ default:
+ {
+ DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %d", 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("Failed to update the profile_level");
+ 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("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("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("AVC profile = %d, level = %d", m_sParamAVC.eProfile,
+ m_sParamAVC.eLevel);
+ } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc.secure",\
+ 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);
+ }
+ else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.vp8",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ m_sParamVP8.eProfile = (OMX_VIDEO_VP8PROFILETYPE)eProfile;
+ m_sParamVP8.eLevel = (OMX_VIDEO_VP8LEVELTYPE)eLevel;
+ DEBUG_PRINT_LOW("VP8 profile = %d, level = %d", m_sParamVP8.eProfile,
+ m_sParamVP8.eLevel);
+ }
+ else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc",\
+ OMX_MAX_STRINGNAME_SIZE)) {
+ m_sParamHEVC.eProfile = (OMX_VIDEO_HEVCPROFILETYPE)eProfile;
+ m_sParamHEVC.eLevel = (OMX_VIDEO_HEVCLEVELTYPE)eLevel;
+ DEBUG_PRINT_LOW("HEVC profile = %d, level = %d", m_sParamHEVC.eProfile,
+ m_sParamHEVC.eLevel);
+ }
+
+ return true;
+}
+/* ======================================================================
+ FUNCTION
+ omx_video::SetConfig
+
+ DESCRIPTION
+ OMX Set Config method implementation
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if successful.
+ ========================================================================== */
+OMX_ERRORTYPE omx_venc::set_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_IN OMX_PTR configData)
+{
+ (void)hComp;
+ 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 ((int)configIndex) {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE);
+ OMX_VIDEO_CONFIG_BITRATETYPE* pParam =
+ reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoBitrate (%u)", (unsigned int)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: %u", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE);
+ OMX_CONFIG_FRAMERATETYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
+ DEBUG_PRINT_HIGH("set_config(): OMX_IndexConfigVideoFramerate (0x%x)", (unsigned int)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;
+ /*
+ * Frame rate can change buffer requirements. If query is not allowed,
+ * failure is not FATAL here.
+ */
+ dev_get_buf_req(&m_sInPortDef.nBufferCountMin,
+ &m_sInPortDef.nBufferCountActual,
+ &m_sInPortDef.nBufferSize,
+ m_sInPortDef.nPortIndex);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE);
+ QOMX_VIDEO_INTRAPERIODTYPE* pParam =
+ reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(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");
+ return OMX_ErrorUnsupportedSetting;
+ }
+#endif
+ DEBUG_PRINT_HIGH("Old: P/B frames = %u/%u, New: P/B frames = %u/%u",
+ (unsigned int)m_sIntraperiod.nPFrames, (unsigned int)m_sIntraperiod.nBFrames,
+ (unsigned int)pParam->nPFrames, (unsigned int)pParam->nBFrames);
+ if (m_sIntraperiod.nBFrames != pParam->nBFrames) {
+ if(hier_b_enabled && m_state == OMX_StateLoaded) {
+ DEBUG_PRINT_INFO("B-frames setting is supported if HierB is enabled");
+ }
+ else {
+ 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.eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline))
+ m_sParamAVC.nBFrames = pParam->nBFrames;
+ else
+ m_sParamAVC.nBFrames = 0;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: (QOMX_IndexConfigVideoIntraperiod) Unsupported port index: %u", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+
+ case OMX_IndexConfigVideoIntraVOPRefresh:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_INTRAREFRESHVOPTYPE);
+ OMX_CONFIG_INTRAREFRESHVOPTYPE* pParam =
+ reinterpret_cast<OMX_CONFIG_INTRAREFRESHVOPTYPE*>(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: %u", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE);
+ OMX_CONFIG_ROTATIONTYPE *pParam =
+ reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ OMX_S32 nRotation;
+
+ if (pParam->nPortIndex != PORT_INDEX_OUT) {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ if ( pParam->nRotation == 0 ||
+ pParam->nRotation == 90 ||
+ pParam->nRotation == 180 ||
+ pParam->nRotation == 270 ) {
+ DEBUG_PRINT_HIGH("set_config: Rotation Angle %u", (unsigned int)pParam->nRotation);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: un supported Rotation %u", (unsigned int)pParam->nRotation);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ nRotation = pParam->nRotation - m_sConfigFrameRotation.nRotation;
+ if (nRotation < 0)
+ nRotation = -nRotation;
+
+ DEBUG_PRINT_HIGH("set_config: updating device Dims");
+
+ if (handle->venc_set_config(configData,
+ OMX_IndexConfigCommonRotate) != true) {
+ DEBUG_PRINT_ERROR("ERROR: Set OMX_IndexConfigCommonRotate failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ if (nRotation == 90 || nRotation == 270) {
+ OMX_U32 nFrameWidth;
+ OMX_U32 nFrameHeight;
+
+ DEBUG_PRINT_HIGH("set_config: updating port Dims Rotation angle = %d",
+ pParam->nRotation);
+ nFrameWidth = m_sOutPortDef.format.video.nFrameWidth;
+ nFrameHeight = m_sOutPortDef.format.video.nFrameHeight;
+ m_sOutPortDef.format.video.nFrameWidth = nFrameHeight;
+ m_sOutPortDef.format.video.nFrameHeight = nFrameWidth;
+ }
+ m_sConfigFrameRotation.nRotation = pParam->nRotation;
+ break;
+ }
+ case OMX_QcomIndexConfigVideoFramePackingArrangement:
+ {
+ DEBUG_PRINT_HIGH("set_config(): OMX_QcomIndexConfigVideoFramePackingArrangement");
+ if (m_sOutPortFormat.eCompressionFormat == OMX_VIDEO_CodingAVC) {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
+ 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:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_CONFIG_LTRPERIOD_TYPE);
+ 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("ERROR: Setting LTR period failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sConfigLTRPeriod, pParam, sizeof(m_sConfigLTRPeriod));
+ break;
+ }
+
+ case OMX_IndexConfigVideoVp8ReferenceFrame:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE);
+ OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE) OMX_IndexConfigVideoVp8ReferenceFrame)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting VP8 reference frame");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sConfigVp8ReferenceFrame, pParam, sizeof(m_sConfigVp8ReferenceFrame));
+ break;
+ }
+
+ case QOMX_IndexConfigVideoLTRUse:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_CONFIG_LTRUSE_TYPE);
+ QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRUse)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting LTR use failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sConfigLTRUse, pParam, sizeof(m_sConfigLTRUse));
+ break;
+ }
+ case QOMX_IndexConfigVideoLTRMark:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_CONFIG_LTRMARK_TYPE);
+ QOMX_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRMark)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting LTR mark failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoAVCIntraPeriod:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD);
+ 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;
+ }
+ case OMX_IndexConfigCommonDeinterlace:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE);
+ OMX_VIDEO_CONFIG_DEINTERLACE *pParam = (OMX_VIDEO_CONFIG_DEINTERLACE*) configData;
+ DEBUG_PRINT_LOW("set_config: OMX_IndexConfigCommonDeinterlace");
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_IndexConfigCommonDeinterlace)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigCommonDeinterlace failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sConfigDeinterlace, pParam, sizeof(m_sConfigDeinterlace));
+ break;
+ }
+ case OMX_QcomIndexConfigVideoVencPerfMode:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_PERFMODE);
+ QOMX_EXTNINDEX_VIDEO_PERFMODE* pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE*)configData;
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoVencPerfMode)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexConfigVideoVencPerfMode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigNumHierPLayers:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS);
+ QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS* pParam =
+ (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS*)configData;
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_QcomIndexConfigNumHierPLayers)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexConfigNumHierPLayers failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sHPlayers, pParam, sizeof(m_sHPlayers));
+ break;
+ }
+ case OMX_QcomIndexConfigBaseLayerId:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID);
+ OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
+ (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexConfigBaseLayerId failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sBaseLayerID, pParam, sizeof(m_sBaseLayerID));
+ break;
+ }
+ case OMX_QcomIndexConfigQp:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_QP);
+ OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
+ (OMX_SKYPE_VIDEO_CONFIG_QP*) configData;
+ if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_QcomIndexConfigQp)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexConfigQp failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sConfigQP, pParam, sizeof(m_sConfigQP));
+ break;
+ }
+ case OMX_IndexConfigPriority:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_PARAM_U32TYPE);
+ if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_IndexConfigPriority)) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_IndexConfigPriority");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_IndexConfigOperatingRate:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_PARAM_U32TYPE);
+ if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_IndexConfigOperatingRate)) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_IndexConfigOperatingRate");
+ return handle->hw_overload ? OMX_ErrorInsufficientResources :
+ OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QTIIndexConfigVideoRoiInfo:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QTI_VIDEO_CONFIG_ROIINFO);
+ if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiInfo)) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_QTIIndexConfigVideoRoiInfo");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_IndexConfigTimePosition:
+ {
+ OMX_TIME_CONFIG_TIMESTAMPTYPE* pParam =
+ (OMX_TIME_CONFIG_TIMESTAMPTYPE*) configData;
+ pthread_mutex_lock(&timestamp.m_lock);
+ timestamp.m_TimeStamp = (OMX_U64)pParam->nTimestamp;
+ DEBUG_PRINT_LOW("Buffer = %p, Timestamp = %llu", timestamp.pending_buffer, (OMX_U64)pParam->nTimestamp);
+ if (timestamp.is_buffer_pending && (OMX_U64)timestamp.pending_buffer->nTimeStamp == timestamp.m_TimeStamp) {
+ DEBUG_PRINT_INFO("Queueing back pending buffer %p", timestamp.pending_buffer);
+ this->post_event((unsigned long)hComp,(unsigned long)timestamp.pending_buffer,m_input_msg_id);
+ timestamp.pending_buffer = NULL;
+ timestamp.is_buffer_pending = false;
+ }
+ pthread_mutex_unlock(&timestamp.m_lock);
+ break;
+ }
+#ifdef SUPPORT_CONFIG_INTRA_REFRESH
+ case OMX_IndexConfigAndroidIntraRefresh:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE);
+ OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam =
+ (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*) configData;
+ if (m_state == OMX_StateLoaded
+ || m_sInPortDef.bEnabled == OMX_FALSE
+ || m_sOutPortDef.bEnabled == OMX_FALSE) {
+ if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_IndexConfigAndroidIntraRefresh)) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_IndexConfigVideoIntraRefreshType");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ m_sConfigIntraRefresh.nRefreshPeriod = pParam->nRefreshPeriod;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_IndexConfigAndroidIntraRefresh supported only at start of session");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+#endif
+ case OMX_QTIIndexConfigVideoBlurResolution:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_QTI_VIDEO_CONFIG_BLURINFO);
+ OMX_QTI_VIDEO_CONFIG_BLURINFO* pParam =
+ (OMX_QTI_VIDEO_CONFIG_BLURINFO*) configData;
+ if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoBlurResolution)) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_QTIIndexConfigVideoBlurResolution");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_blurInfo, pParam, sizeof(m_blurInfo));
+ break;
+ }
+ case OMX_QcomIndexConfigH264Transform8x8:
+ {
+ if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_QcomIndexConfigH264Transform8x8)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexConfigH264Transform8x8 failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QTIIndexConfigDescribeColorAspects:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
+ DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
+ print_debug_color_aspects(&(params->sAspects), "set_config");
+ if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects)) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_QTIIndexConfigDescribeColorAspects");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ memcpy(&m_sConfigColorAspects, configData, sizeof(m_sConfigColorAspects));
+ break;
+ }
+ case OMX_IndexConfigAndroidVideoTemporalLayering:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_TEMPORALLAYERINGTYPE);
+ DEBUG_PRINT_ERROR("Setting/modifying Temporal layers at run-time is not supported !");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ default:
+ DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
+ break;
+ }
+
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+ FUNCTION
+ omx_venc::ComponentDeInit
+
+ DESCRIPTION
+ Destroys the component and release memory allocated to the heap.
+
+ PARAMETERS
+ <TBD>.
+
+ RETURN VALUE
+ OMX Error None if everything successful.
+
+ ========================================================================== */
+OMX_ERRORTYPE omx_venc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ (void) hComp;
+ OMX_U32 i = 0;
+ DEBUG_PRINT_HIGH("omx_venc(): Inside component_deinit()");
+ if (OMX_StateLoaded != m_state) {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
+ m_state);
+ }
+ if (m_out_mem_ptr) {
+ DEBUG_PRINT_LOW("Freeing the Output Memory");
+ for (i=0; i< m_sOutPortDef.nBufferCountActual; i++ ) {
+ if (BITMASK_PRESENT(&m_out_bm_count, i)) {
+ BITMASK_CLEAR(&m_out_bm_count, i);
+ free_output_buffer (&m_out_mem_ptr[i]);
+ }
+
+ if (release_output_done()) {
+ break;
+ }
+ }
+ 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");
+ for (i=0; i<m_sInPortDef.nBufferCountActual; i++ ) {
+ if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
+ BITMASK_CLEAR(&m_inp_bm_count, i);
+ free_input_buffer (&m_inp_mem_ptr[i]);
+ }
+
+ if (release_input_done()) {
+ break;
+ }
+ }
+
+
+ free(m_inp_mem_ptr);
+ m_inp_mem_ptr = NULL;
+ }
+
+ // Reset counters in mesg queues
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+
+#ifdef _ANDROID_
+ // Clear the strong reference
+ DEBUG_PRINT_HIGH("Calling m_heap_ptr.clear()");
+ m_heap_ptr.clear();
+#endif // _ANDROID_
+ DEBUG_PRINT_HIGH("Calling venc_close()");
+ if (handle) {
+ handle->venc_close();
+ DEBUG_PRINT_HIGH("Deleting HANDLE[%p]", handle);
+ delete (handle);
+ handle = NULL;
+ }
+ DEBUG_PRINT_INFO("Component Deinit");
+ 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_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer)
+{
+ bool bRet = true;
+
+ pthread_mutex_lock(&timestamp.m_lock);
+
+ if ((!m_slowLatencyMode.bLowLatencyMode) || ((OMX_U64)buffer->nTimeStamp == (OMX_U64)timestamp.m_TimeStamp)) {
+ DEBUG_PRINT_LOW("ETB is ready to be queued");
+ } else {
+ DEBUG_PRINT_INFO("ETB is defeffed due to timeStamp mismatch");
+ timestamp.is_buffer_pending = true;
+ timestamp.pending_buffer = buffer;
+ bRet = false;
+ }
+ pthread_mutex_unlock(&timestamp.m_lock);
+ return bRet;
+}
+
+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)
+{
+ bool bret = false;
+ bret = handle->venc_empty_buf(buffer, pmem_data_buf,index,fd);
+ hw_overload = handle->hw_overload;
+ return bret;
+}
+
+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_
+ (void) min;
+ (void) max;
+ (void) step_size;
+ 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_get_performance_level(OMX_U32 *perflevel)
+{
+#ifdef _MSM8974_
+ return handle->venc_get_performance_level(perflevel);
+#else
+ DEBUG_PRINT_ERROR("Get performance level is not supported");
+ return false;
+#endif
+}
+
+bool omx_venc::dev_get_vui_timing_info(OMX_U32 *enabled)
+{
+#ifdef _MSM8974_
+ return handle->venc_get_vui_timing_info(enabled);
+#else
+ DEBUG_PRINT_ERROR("Get vui timing information is not supported");
+ return false;
+#endif
+}
+
+bool omx_venc::dev_get_vqzip_sei_info(OMX_U32 *enabled)
+{
+ return handle->venc_get_vqzip_sei_info(enabled);
+}
+
+bool omx_venc::dev_get_peak_bitrate(OMX_U32 *peakbitrate)
+{
+#ifdef _MSM8974_
+ return handle->venc_get_peak_bitrate(peakbitrate);
+#else
+ DEBUG_PRINT_ERROR("Get peak bitrate is not supported");
+ return false;
+#endif
+}
+
+bool omx_venc::dev_get_batch_size(OMX_U32 *size)
+{
+#ifdef _MSM8974_
+ return handle->venc_get_batch_size(size);
+#else
+ DEBUG_PRINT_ERROR("Get batch size is not supported");
+ return false;
+#endif
+}
+
+bool omx_venc::dev_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
+ OMX_U32 *nMaxBLayers) {
+ return handle->venc_get_temporal_layer_caps(nMaxLayers, nMaxBLayers);
+}
+
+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
+}
+
+int omx_venc::dev_handle_output_extradata(void *buffer, int index)
+{
+ return handle->handle_output_extradata(buffer, index);
+}
+
+int omx_venc::dev_set_format(int color)
+{
+ return handle->venc_set_format(color);
+}
+
+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;
+ native_handle_t *nh = NULL;
+
+ if (context == NULL || message == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: omx_venc::async_message_process invalid i/p params");
+ return -1;
+ }
+ m_sVenc_msg = (struct venc_msg *)message;
+
+ omx = reinterpret_cast<omx_video*>(context);
+
+ if (m_sVenc_msg->statuscode != VEN_S_SUCCESS) {
+ DEBUG_PRINT_ERROR("ERROR: async_msg_process() - Error statuscode = %lu",
+ m_sVenc_msg->statuscode);
+ if(m_sVenc_msg->msgcode == VEN_MSG_HW_OVERLOAD) {
+ omx->post_event (0, m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
+ } else {
+ omx->post_event (0, m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+ }
+ }
+
+ DEBUG_PRINT_LOW("omx_venc::async_message_process- msgcode = %lu",
+ m_sVenc_msg->msgcode);
+ switch (m_sVenc_msg->msgcode) {
+ case VEN_MSG_START:
+ omx->post_event (0,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_START_DONE);
+ break;
+ case VEN_MSG_STOP:
+ omx->post_event (0,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_STOP_DONE);
+ break;
+ case VEN_MSG_RESUME:
+ omx->post_event (0,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_RESUME_DONE);
+ break;
+ case VEN_MSG_PAUSE:
+ omx->post_event (0,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_PAUSE_DONE);
+ break;
+ case VEN_MSG_FLUSH_INPUT_DONE:
+
+ omx->post_event (0,m_sVenc_msg->statuscode,\
+ OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
+ break;
+ case VEN_MSG_FLUSH_OUPUT_DONE:
+ omx->post_event (0,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 long)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 (!omx->is_secure_session() && (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("o/p TS = %u", (unsigned int)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 && !omx->is_secure_session()) {
+ DEBUG_PRINT_LOW("memcpy() for o/p Heap UseBuffer");
+ memcpy(omxhdr->pBuffer,
+ (m_sVenc_msg->buf.ptrbuffer),
+ m_sVenc_msg->buf.len);
+ }
+ } else if (omx->is_secure_session()) {
+ output_metabuffer *meta_buf = (output_metabuffer *)(omxhdr->pBuffer);
+ native_handle_t *nh = meta_buf->nh;
+ nh->data[1] = m_sVenc_msg->buf.offset;
+ nh->data[2] = m_sVenc_msg->buf.len;
+ omxhdr->nFilledLen = sizeof(output_metabuffer);
+ omxhdr->nTimeStamp = m_sVenc_msg->buf.timestamp;
+ omxhdr->nFlags = m_sVenc_msg->buf.flags;
+ } else {
+ omxhdr->nFilledLen = 0;
+ }
+
+ } else {
+ omxhdr = NULL;
+ m_sVenc_msg->statuscode = VEN_S_EFAIL;
+ }
+ omx->post_event ((unsigned long)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:
+ DEBUG_PRINT_HIGH("Unknown msg received : %lu", m_sVenc_msg->msgcode);
+ break;
+ }
+ return 0;
+}
+
+bool omx_venc::dev_color_align(OMX_BUFFERHEADERTYPE *buffer,
+ OMX_U32 width, OMX_U32 height)
+{
+ if(secure_session) {
+ DEBUG_PRINT_ERROR("Cannot align colors in secure session.");
+ return OMX_FALSE;
+ }
+ return handle->venc_color_align(buffer, width,height);
+}
+
+bool omx_venc::is_secure_session()
+{
+ return secure_session;
+}
+
+bool omx_venc::dev_get_output_log_flag()
+{
+ return handle->venc_get_output_log_flag();
+}
+
+int omx_venc::dev_output_log_buffers(const char *buffer, int bufferlen)
+{
+ return handle->venc_output_log_buffers(buffer, bufferlen);
+}
+
+int omx_venc::dev_extradata_log_buffers(char *buffer)
+{
+ return handle->venc_extradata_log_buffers(buffer);
+}
diff --git a/msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp b/msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp
new file mode 100644
index 0000000..855c79f
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device.cpp
@@ -0,0 +1,3149 @@
+/*--------------------------------------------------------------------------
+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<string.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include<unistd.h>
+#include <fcntl.h>
+#include "video_encoder_device.h"
+#include "omx_video_encoder.h"
+#include <linux/android_pmem.h>
+#ifdef USE_ION
+#include <linux/msm_ion.h>
+#endif
+
+#define MPEG4_SP_START 0
+#define MPEG4_ASP_START (MPEG4_SP_START + 8)
+#define MPEG4_720P_LEVEL 6
+#define H263_BP_START 0
+#define H264_BP_START 0
+#define H264_HP_START (H264_BP_START + 13)
+#define H264_MP_START (H264_BP_START + 26)
+
+/* MPEG4 profile and level table*/
+static const unsigned int mpeg4_profile_level_table[][5]= {
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
+ {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
+ {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
+ {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
+ {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
+ {0,0,0,0,0},
+
+ {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
+ {0,0,0,0,0},
+};
+
+/* H264 profile and level table*/
+static const unsigned int h264_profile_level_table[][5]= {
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
+ {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
+ {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
+ {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
+ {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
+ {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
+ {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
+ {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
+ {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
+ {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
+ {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
+ {0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
+ {0,0,0,0,0}
+
+};
+
+/* H263 profile and level table*/
+static const unsigned int h263_profile_level_table[][5]= {
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
+ {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
+ {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
+ {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
+ {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
+ {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
+ {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
+ {0,0,0,0,0}
+};
+
+#define Log2(number, power) { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) && power < 16) { temp >>=0x1; power++; } }
+#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power); num = q >> power; den = 0x1 << (16 - power); }
+
+#define BUFFER_LOG_LOC "/data/misc/media"
+
+//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);
+ memset(&m_debug,0,sizeof(m_debug));
+
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+ property_value[0] = '\0';
+ property_get("vidc.enc.log.in", property_value, "0");
+ m_debug.in_buffer_log = atoi(property_value);
+
+ property_value[0] = '\0';
+ property_get("vidc.enc.log.out", property_value, "0");
+ m_debug.out_buffer_log = atoi(property_value);
+ snprintf(m_debug.log_loc, PROPERTY_VAL_MAX,
+ "%s", BUFFER_LOG_LOC);
+
+ DEBUG_PRINT_LOW("venc_dev constructor");
+}
+
+venc_dev::~venc_dev()
+{
+ pthread_cond_destroy(&loaded_start_stop_cond);
+ pthread_mutex_destroy(&loaded_start_stop_mlock);
+ DEBUG_PRINT_LOW("venc_dev distructor");
+}
+
+void* async_venc_message_thread (void *input)
+{
+ struct venc_ioctl_msg ioctl_msg ={NULL,NULL};
+ struct venc_timeout timeout;
+ struct venc_msg venc_msg;
+ int error_code = 0;
+ omx_venc *omx = reinterpret_cast<omx_venc*>(input);
+
+ prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
+ timeout.millisec = VEN_TIMEOUT_INFINITE;
+
+ while (1) {
+ ioctl_msg.in = NULL;
+ ioctl_msg.out = (void*)&venc_msg;
+
+ /*Wait for a message from the video decoder driver*/
+ error_code = ioctl(omx->handle->m_nDriver_fd,VEN_IOCTL_CMD_READ_NEXT_MSG,(void *)&ioctl_msg);
+
+ if (error_code == -512) { // ERESTARTSYS
+ DEBUG_PRINT_ERROR("ERESTARTSYS received in ioctl read next msg!");
+ } else if (error_code <0) {
+ DEBUG_PRINT_LOW("ioctl VEN_IOCTL_CMD_READ_NEXT_MSG failed");
+ break;
+ } else if (omx->async_message_process(input,&venc_msg) < 0) {
+ DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
+ break;
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
+ return NULL;
+}
+
+int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
+{
+ return OMX_ErrorUnsupportedSetting;
+}
+
+int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
+{
+ if (m_debug.out_buffer_log && !m_debug.outfile) {
+ int size = 0;
+ if(m_sVenc_cfg.codectype == VEN_CODEC_MPEG4) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.m4v",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == VEN_CODEC_H264) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.264",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == VENC_CODEC_H263) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.263",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == VENC_CODEC_VP8) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%d_%d_%p.ivf",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ }
+ if ((size > PROPERTY_VALUE_MAX) || (size < 0)) {
+ DEBUG_PRINT_ERROR("Failed to open output file: %s for logging as size:%d",
+ m_debug.outfile_name, size);
+ return -1;
+ }
+ m_debug.outfile = fopen(m_debug.outfile_name, "ab");
+ if (!m_debug.outfile) {
+ DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
+ m_debug.outfile_name, errno);
+ m_debug.outfile_name[0] = '\0';
+ return -1;
+ }
+ }
+ if (m_debug.outfile && buffer_len) {
+ DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
+ fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
+ }
+ return 0;
+}
+
+bool venc_dev::venc_get_output_log_flag()
+{
+ return (m_debug.out_buffer_log == 1);
+}
+
+int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, void *pmem_data_buf, int framelen) {
+ if (!m_debug.infile) {
+ int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%d_%d_%p.yuv",
+ m_debug.log_loc, m_sVenc_cfg.input_width,
+ m_sVenc_cfg.input_height, this);
+ if ((size > PROPERTY_VALUE_MAX) || (size < 0)) {
+ DEBUG_PRINT_ERROR("Failed to open input file: %s for logging size:%d",
+ m_debug.infile_name, size);
+ return -1;
+ }
+ m_debug.infile = fopen (m_debug.infile_name, "ab");
+ if (!m_debug.infile) {
+ DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile);
+ m_debug.infile_name[0] = '\0';
+ return -1;
+ }
+ }
+ if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
+#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("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
+ buf_addr = (OMX_U8 *)pmem_data_buf;
+ } else {
+ DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ buf_addr = (unsigned char *)mmap(NULL,
+ ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[2],
+ PROT_READ|PROT_WRITE, MAP_SHARED,
+ ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[0], 0);
+ }
+
+ if (m_debug.infile) {
+ fwrite((const char *)buf_addr, y_size, 1, m_debug.infile);
+ fwrite((const char *)(buf_addr + c_offset), (y_size>>1), 1, m_debug.infile);
+ }
+
+ if (!pmem_data_buf) {
+ munmap (buf_addr, ((encoder_media_buffer_type *)pbuffer->pBuffer)->meta_handle->data[2]);
+ }
+#else
+ if (m_debug.infile) {
+ OMX_U8* ptrbuffer = NULL;
+ if (pmem_data_buf) {
+ DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
+ ptrbuffer = (OMX_U8 *)pmem_data_buf;
+ } else {
+ DEBUG_PRINT_LOW("Shared PMEM addr for i/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ ptrbuffer = (OMX_U8 *)bufhdr->pBuffer;
+ }
+ fwrite((const char *)ptrbuffer, framelen, 1, m_debug.infile);
+ }
+
+#endif
+ }
+ return 0;
+}
+
+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");
+ 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");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("m_nDriver_fd = %d", 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("ERROR: Request number of encoder instances failed");
+ } else if (num_instances > 1) {
+ DEBUG_PRINT_ERROR("Second 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;
+ } 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;
+ }
+
+ 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;
+ }
+
+ 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("ERROR: Request for setting base configuration failed");
+ return false;
+ }
+
+ // 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("ERROR: 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("ERROR: 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("%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("venc_close: fd = %d", m_nDriver_fd);
+
+ if ((int)m_nDriver_fd >= 0) {
+ DEBUG_PRINT_HIGH("venc_close(): Calling VEN_IOCTL_CMD_STOP_READ_MSG");
+ (void)ioctl(m_nDriver_fd, VEN_IOCTL_CMD_STOP_READ_MSG,
+ NULL);
+ DEBUG_PRINT_LOW("Calling close()");
+ close(m_nDriver_fd);
+ m_nDriver_fd = -1;
+ }
+
+ if (m_debug.infile) {
+ fclose(m_debug.infile);
+ m_debug.infile = NULL;
+ }
+ if (m_debug.outfile) {
+ fclose(m_debug.outfile);
+ m_debug.outfile = NULL;
+ }
+
+}
+
+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("ERROR: Request for setting i/p buffer requirement failed");
+ m_sInput_buff_property.actualcount = temp_count;
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("I/P Count set to %lu", *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("ERROR: Request for setting o/p buffer requirement failed");
+ m_sOutput_buff_property.actualcount = temp_count;
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("O/P Count set to %lu", *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("ERROR: 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("ERROR: 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");
+
+ 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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: Request for setting i/p buffer requirements failed");
+ return false;
+ }
+ }
+
+ if (m_sInput_buff_property.datasize != portDefn->nBufferSize) {
+ DEBUG_PRINT_ERROR("WARNING: 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("ERROR: ioctl VEN_IOCTL_SET_OUTPUT_BUFFER_REQ failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Setting Output buffer requirements failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+
+ 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("ERROR: 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");
+
+ if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+ if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
+ DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
+ return false;
+ }
+
+ if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
+ DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+
+ if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+ if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
+ DEBUG_PRINT_ERROR("ERROR: 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("ERROR: 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");
+ bFrames = 0;
+ }
+ }
+ }
+
+#endif
+
+ if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+
+ if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+ 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("ERROR: Unsuccessful in updating Profile and level");
+ return false;
+ }
+
+ if (pParam->nBFrames)
+ DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
+
+ if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoAvc:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
+ 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",
+ pParam->eProfile,pParam->eLevel);
+
+ m_profile_set = false;
+ m_level_set = false;
+
+ if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+ bFrames = 0;
+ }
+ }
+ }
+
+#endif
+
+ if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+
+ if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
+ return false;
+ }
+
+ if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
+ return false;
+ }
+
+ if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
+ DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+ 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("ERROR: Setting Intra refresh failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
+ 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("ERROR: Setting Intra refresh failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
+ 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("WARNING: Unsuccessful in updating Profile and level");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoQuantization:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
+ 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("ERROR: Setting Session QP failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
+ }
+
+ break;
+ }
+
+ case OMX_QcomIndexParamVideoQPRange:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
+ 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("ERROR: Setting QP Range failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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("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("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("ERROR: Setting Target Bit rate failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
+ }
+
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
+ configData;
+ DEBUG_PRINT_LOW("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("ERROR: Setting Encode Framerate failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
+ 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("ERROR: 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("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("ERROR: Setting Encode Framerate failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ OMX_CONFIG_ROTATIONTYPE *config_rotation =
+ reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ venc_ioctl_msg ioctl_msg = {NULL,NULL};
+ OMX_U32 nFrameWidth;
+
+ DEBUG_PRINT_HIGH("venc_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("ERROR: 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("%s(): Check Profile/Level set in driver before start",
+ __func__);
+
+ if (!venc_set_profile_level(0, 0)) {
+ DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
+ __func__);
+ } else {
+ DEBUG_PRINT_HIGH("%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");
+ 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", 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("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",
+ 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");
+ 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("ERROR: ION Device open() Failed");
+ return -1;
+ }
+
+ recon_buff[count].alloc_data.len = size;
+#ifdef MAX_RES_720P
+ recon_buff[count].alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
+#else
+ recon_buff[count].alloc_data.heap_id_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("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("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("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("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",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("Allocated virt:%p, FD: %d of size %d", 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");
+ 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("Allocated virt:%p, FD: %d of size %d at index: %d", 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("cleaning Index %d of size %d",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("ENC_CONFIG: Codec: %d, Profile %d, level : %d",
+ m_sVenc_cfg.codectype, codec_profile.profile, profile_level.level);
+
+ DEBUG_PRINT_HIGH("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("ENC_CONFIG: Bitrate: %d, RC: %d, I-Period: %d",
+ bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %d, qpP: %d, qpb: 0",
+ session_qp.iframeqp, session_qp.pframqp);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %d, maxQP: %d",
+ qp_range.minqp, qp_range.maxqp);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %d, Slice-Mode: %d, Slize_Size: %d",
+ voptimecfg.voptime_resolution, multislice.mslice_mode,
+ multislice.mslice_size);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %d",
+ entropy.longentropysel, entropy.cabacmodel);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %d, alpha: %d, Beta: %d",
+ dbkfilter.db_mode, dbkfilter.slicealpha_offset,
+ dbkfilter.slicebeta_offset);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %d, HEC: %d",
+ 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("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("ERROR: 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("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("ERROR: 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("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("ERROR: venc_use_buf:set output buffer failed ");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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("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("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("ERROR: 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("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("ERROR: venc_free_buf: free output buffer failed ");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
+ OMX_U32 width, OMX_U32 height)
+{
+ DEBUG_PRINT_ERROR("%s not implemented!", __func__);
+ return OMX_ErrorUnsupportedSetting;
+}
+
+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("ERROR: venc_etb: buffer is NULL");
+ return false;
+ }
+
+ bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+ DEBUG_PRINT_LOW("Input buffer length %d",bufhdr->nFilledLen);
+
+ if (pmem_data_buf) {
+ DEBUG_PRINT_LOW("Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
+ frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
+ } else {
+ DEBUG_PRINT_LOW("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("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;
+ }
+
+ if (m_debug.in_buffer_log) {
+ venc_input_log_buffers(bufhdr, pmem_data_bufr, frameinfo.len);
+ }
+
+ 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("Internal PMEM addr for o/p Heap UseBuf: %p", pmem_data_buf);
+ frameinfo.ptrbuffer = (OMX_U8 *)pmem_data_buf;
+ } else {
+ DEBUG_PRINT_LOW("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("ERROR: 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*)&ltr_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*)&ltr_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*)&ltr_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*)&ltr_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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: 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("MPEG4 Level 6 is set for 720p resolution");
+ requested_level.level = VEN_LEVEL_MPEG4_6;
+ } else {
+ DEBUG_PRINT_LOW("MPEG4 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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: 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("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("Invalid 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("ERROR: 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("%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("ERROR: 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("ERROR: 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("ERROR: 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("ERROR: Request for setting HEader Error correction failed");
+ return false;
+ }
+
+ hec.header_extension = error_resilience->bEnableHEC;
+ }
+
+ if (error_resilience->bEnableRVLC) {
+ DEBUG_PRINT_ERROR("RVLC is not Supported");
+ return false;
+ }
+
+ if (( m_sVenc_cfg.codectype != OMX_VIDEO_CodingH263) &&
+ (error_resilience->bEnableDataPartitioning)) {
+ DEBUG_PRINT_ERROR("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("%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("ERROR: 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("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("ERROR: 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("ERROR: 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",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("ERROR: 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("WARNING: 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("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("ERROR: 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("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("ERROR: Request for setting Intra VOP Refresh failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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("ERROR: 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("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("%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("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;
+#ifndef _MSM8610_
+ case VEN_PROFILE_H264_MAIN:
+ *eProfile = OMX_VIDEO_AVCProfileMain;
+ break;
+ case VEN_PROFILE_H264_HIGH:
+ *eProfile = OMX_VIDEO_AVCProfileHigh;
+ break;
+#endif
+ default:
+ DEBUG_PRINT_LOW("%s(): Unsupported profile %x", __func__, codec_profile.profile);
+ 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("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("%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("Unsupported H.263 profile type %lu", *eProfile);
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_LOW("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("Appropriate profile/level found %d/%d", new_profile, new_level);
+ break;
+ }
+ }
+ }
+
+ profile_tbl = profile_tbl + 5;
+ } while (profile_tbl[0] != 0);
+
+ if (profile_level_found != true) {
+ DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
+ 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/msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
new file mode 100644
index 0000000..b2a00cd
--- /dev/null
+++ b/msmcobalt/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -0,0 +1,8199 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2016, 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 <string.h>
+#include <sys/ioctl.h>
+#include <sys/prctl.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "video_encoder_device_v4l2.h"
+#include "omx_video_encoder.h"
+#include <media/msm_vidc.h>
+#ifdef USE_ION
+#include <linux/msm_ion.h>
+#endif
+#include <math.h>
+#include <media/msm_media_info.h>
+#include <cutils/properties.h>
+#include <media/hardware/HardwareAPI.h>
+
+#ifdef _ANDROID_
+#include <media/hardware/HardwareAPI.h>
+#include <gralloc_priv.h>
+#endif
+
+#include <qdMetaData.h>
+
+#define YUV_STATS_LIBRARY_NAME "libgpustats.so" // UBWC case: use GPU library
+
+#define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
+#define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
+#define MAXDPB 16
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+#define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
+#define MAX_PROFILE_PARAMS 6
+#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 + 18)
+#define H264_MP_START (H264_BP_START + 36)
+#define HEVC_MAIN_START 0
+#define HEVC_MAIN10_START (HEVC_MAIN_START + 13)
+#define POLL_TIMEOUT 1000
+#define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
+
+#define SZ_4K 0x1000
+#define SZ_1M 0x100000
+#define MAX_FPS_PQ 60
+
+/* MPEG4 profile and level table*/
+static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= {
+ /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
+ {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+ {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+ /* Please update MPEG4_ASP_START accordingly, while adding new element */
+ {0,0,0,0,0,0},
+
+ {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+ {0,0,0,0,0,0},
+};
+
+/* H264 profile and level table*/
+static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= {
+ /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768},
+ {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768},
+ {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816},
+ {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400},
+ {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320},
+ /* Please update H264_HP_START accordingly, while adding new element */
+ {0,0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1, QOMX_VIDEO_AVCProfileConstrainedBaseline,396},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b, QOMX_VIDEO_AVCProfileConstrainedBaseline,396},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11, QOMX_VIDEO_AVCProfileConstrainedBaseline,900},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12, QOMX_VIDEO_AVCProfileConstrainedBaseline,2376},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13, QOMX_VIDEO_AVCProfileConstrainedBaseline,2376},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2, QOMX_VIDEO_AVCProfileConstrainedBaseline,2376},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21, QOMX_VIDEO_AVCProfileConstrainedBaseline,4752},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22, QOMX_VIDEO_AVCProfileConstrainedBaseline,8100},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3, QOMX_VIDEO_AVCProfileConstrainedBaseline,8100},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31, QOMX_VIDEO_AVCProfileConstrainedBaseline,18000},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32, QOMX_VIDEO_AVCProfileConstrainedBaseline,20480},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4, QOMX_VIDEO_AVCProfileConstrainedBaseline,32768},
+ {8192,245760,50000000,OMX_VIDEO_AVCLevel41, QOMX_VIDEO_AVCProfileConstrainedBaseline,32768},
+ {8704,522240,50000000,OMX_VIDEO_AVCLevel42, QOMX_VIDEO_AVCProfileConstrainedBaseline,34816},
+ {22080,589824,135000000,OMX_VIDEO_AVCLevel5, QOMX_VIDEO_AVCProfileConstrainedBaseline,110400},
+ {36864,983040,240000000,OMX_VIDEO_AVCLevel51, QOMX_VIDEO_AVCProfileConstrainedBaseline,184320},
+ /* Please update H264_HP_START accordingly, while adding new element */
+ {0,0,0,0,0,0},
+
+ {99,1485,80000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396},
+ {99,1485,200000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396},
+ {396,3000,300000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900},
+ {396,6000,600000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376},
+ {396,11880,1200000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376},
+ {396,11880,3125000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376},
+ {792,19800,6250000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752},
+ {1620,20250,6250000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100},
+ {1620,40500,15625000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100},
+ {3600,108000,21875000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000},
+ {5120,216000,31250000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480},
+ {8192,245760,31250000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768},
+ {8192,245760,62500000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768},
+ {8704,522240,62500000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816},
+ {22080,589824,168750000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400},
+ {36864,983040,300000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320},
+ /* Please update H264_MP_START accordingly, while adding new element */
+ {0,0,0,0,0,0},
+
+ {99,1485,80000,OMX_VIDEO_AVCLevel1,QOMX_VIDEO_AVCProfileConstrainedHigh,396},
+ {99,1485,200000,OMX_VIDEO_AVCLevel1b, QOMX_VIDEO_AVCProfileConstrainedHigh,396},
+ {396,3000,300000,OMX_VIDEO_AVCLevel11, QOMX_VIDEO_AVCProfileConstrainedHigh,900},
+ {396,6000,600000,OMX_VIDEO_AVCLevel12, QOMX_VIDEO_AVCProfileConstrainedHigh,2376},
+ {396,11880,1200000,OMX_VIDEO_AVCLevel13, QOMX_VIDEO_AVCProfileConstrainedHigh,2376},
+ {396,11880,3125000,OMX_VIDEO_AVCLevel2, QOMX_VIDEO_AVCProfileConstrainedHigh,2376},
+ {792,19800,6250000,OMX_VIDEO_AVCLevel21, QOMX_VIDEO_AVCProfileConstrainedHigh,4752},
+ {1620,20250,6250000,OMX_VIDEO_AVCLevel22, QOMX_VIDEO_AVCProfileConstrainedHigh,8100},
+ {1620,40500,15625000,OMX_VIDEO_AVCLevel3, QOMX_VIDEO_AVCProfileConstrainedHigh,8100},
+ {3600,108000,21875000,OMX_VIDEO_AVCLevel31, QOMX_VIDEO_AVCProfileConstrainedHigh,18000},
+ {5120,216000,31250000,OMX_VIDEO_AVCLevel32, QOMX_VIDEO_AVCProfileConstrainedHigh,20480},
+ {8192,245760,31250000,OMX_VIDEO_AVCLevel4, QOMX_VIDEO_AVCProfileConstrainedHigh,32768},
+ {8192,245760,62500000,OMX_VIDEO_AVCLevel41, QOMX_VIDEO_AVCProfileConstrainedHigh,32768},
+ {8704,522240,62500000,OMX_VIDEO_AVCLevel42, QOMX_VIDEO_AVCProfileConstrainedHigh,34816},
+ {22080,589824,168750000,OMX_VIDEO_AVCLevel5, QOMX_VIDEO_AVCProfileConstrainedHigh,110400},
+ {36864,983040,300000000,OMX_VIDEO_AVCLevel51, QOMX_VIDEO_AVCProfileConstrainedHigh,184320},
+ /* Please update H264_MP_START accordingly, while adding new element */
+ {0,0,0,0,0,0},
+
+ {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396},
+ {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396},
+ {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900},
+ {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376},
+ {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376},
+ {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376},
+ {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752},
+ {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100},
+ {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100},
+ {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000},
+ {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480},
+ {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768},
+ {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768},
+ {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816},
+ {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400},
+ {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320},
+ {0,0,0,0,0,0}
+
+};
+
+/* H263 profile and level table*/
+static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= {
+ /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
+ {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0},
+ {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0},
+ {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0},
+ {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0},
+ {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0},
+ {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0},
+ {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0},
+ {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
+ {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
+ {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
+ {0,0,0,0,0,0}
+};
+
+/* HEVC profile and level table*/
+static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= {
+ /*max mb per frame, max mb per sec, max bitrate, level, profile*/
+ {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0},
+ {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0},
+ {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0},
+ {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0},
+ {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0},
+ {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0},
+ {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
+ {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
+ {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
+ {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
+ {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
+ {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
+ {138240,4147200,240000000,OMX_VIDEO_HEVCHighTierLevel52,OMX_VIDEO_HEVCProfileMain,0},
+ /* Please update HEVC_MAIN_START accordingly, while adding new element */
+ {0,0,0,0,0},
+
+ {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0},
+ {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0},
+ {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0},
+ {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0},
+ {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0},
+ {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0},
+ {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
+ {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
+ {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
+ {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
+ {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
+ {138240,4147200,160000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
+ {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); }
+
+#define BUFFER_LOG_LOC "/data/misc/media"
+
+//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;
+ m_poll_efd = -1;
+
+ struct v4l2_control control;
+ for (i = 0; i < MAX_PORT; i++)
+ streaming[i] = false;
+
+ stopped = 1;
+ paused = false;
+ async_thread_created = false;
+ async_thread_force_stop = false;
+ color_format = 0;
+ hw_overload = false;
+ mBatchSize = 0;
+ deinterlace_enabled = false;
+ pthread_mutex_init(&pause_resume_mlock, NULL);
+ pthread_cond_init(&pause_resume_cond, NULL);
+ memset(&input_extradata_info, 0, sizeof(input_extradata_info));
+ memset(&output_extradata_info, 0, sizeof(output_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(&session_ipb_qp_values, 0, sizeof(session_ipb_qp_values));
+ 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));
+ memset(&m_debug,0,sizeof(m_debug));
+ memset(&hier_layers,0,sizeof(hier_layers));
+ is_searchrange_set = false;
+ enable_mv_narrow_searchrange = false;
+ supported_rc_modes = RC_ALL;
+ memset(&vqzip_sei_info, 0, sizeof(vqzip_sei_info));
+ memset(&ltrinfo, 0, sizeof(ltrinfo));
+ memset(&fd_list, 0, sizeof(fd_list));
+ memset(&hybrid_hp, 0, sizeof(hybrid_hp));
+ memset(&roi, 0, sizeof(roi));
+ sess_priority.priority = 1;
+ operating_rate = 0;
+ low_latency_mode = OMX_FALSE;
+ memset(&color_space, 0x0, sizeof(color_space));
+ memset(&temporal_layers_config, 0x0, sizeof(temporal_layers_config));
+
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+ property_get("vidc.enc.log.in", property_value, "0");
+ m_debug.in_buffer_log = atoi(property_value);
+
+ property_get("vidc.enc.log.out", property_value, "0");
+ m_debug.out_buffer_log = atoi(property_value);
+
+ property_get("vidc.enc.log.extradata", property_value, "0");
+ m_debug.extradata_log = atoi(property_value);
+
+#ifdef _UBWC_
+ property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
+ if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
+ !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
+ is_gralloc_source_ubwc = 0;
+ } else {
+ is_gralloc_source_ubwc = 1;
+ }
+#else
+ is_gralloc_source_ubwc = 0;
+#endif
+
+ property_get("persist.vidc.enc.csc.enable", property_value, "0");
+ if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
+ !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
+ is_csc_enabled = 1;
+ } else {
+ is_csc_enabled = 0;
+ }
+
+ is_pq_force_disable = 0;
+#ifdef _PQ_
+ property_get("vidc.enc.disable.pq", property_value, "0");
+ if(!(strncmp(property_value, "1", PROPERTY_VALUE_MAX)) ||
+ !(strncmp(property_value, "true", PROPERTY_VALUE_MAX))) {
+ is_pq_force_disable = 1;
+ } else {
+ is_pq_force_disable = 0;
+ }
+#endif // _PQ_
+
+ snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX,
+ "%s", BUFFER_LOG_LOC);
+}
+
+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<omx_venc*>(input);
+ omx_venc_base = reinterpret_cast<omx_video*>(input);
+ OMX_BUFFERHEADERTYPE* omxhdr = NULL;
+
+ prctl(PR_SET_NAME, (unsigned long)"VideoEncCallBackThread", 0, 0, 0);
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ struct pollfd pfds[2];
+ struct v4l2_buffer v4l2_buf;
+ struct v4l2_event dqevent;
+ struct statistics stats;
+ pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
+ pfds[1].events = POLLIN | POLLERR;
+ pfds[0].fd = omx->handle->m_nDriver_fd;
+ pfds[1].fd = omx->handle->m_poll_efd;
+ int error_code = 0,rc=0;
+
+ memset(&stats, 0, sizeof(statistics));
+ memset(&v4l2_buf, 0, sizeof(v4l2_buf));
+
+ while (!omx->handle->async_thread_force_stop) {
+ 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("ERROR: 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("ERROR: Failed to process resume msg");
+ pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
+ break;
+ }
+ memset(&stats, 0, sizeof(statistics));
+ }
+
+ pthread_mutex_unlock(&omx->handle->pause_resume_mlock);
+
+ rc = poll(pfds, 2, POLL_TIMEOUT);
+
+ if (!rc) {
+ DEBUG_PRINT_HIGH("Poll timedout, pipeline stalled due to client/firmware ETB: %d, EBD: %d, FTB: %d, FBD: %d",
+ omx->handle->etb, omx->handle->ebd, omx->handle->ftb, omx->handle->fbd);
+ continue;
+ } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
+ DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
+ break;
+ }
+
+ if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
+ DEBUG_PRINT_ERROR("async_venc_message_thread interrupted to be exited");
+ break;
+ }
+
+ if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ v4l2_buf.memory = V4L2_MEMORY_USERPTR;
+ v4l2_buf.length = omx->handle->num_output_planes;
+ v4l2_buf.m.planes = plane;
+
+ while (!ioctl(pfds[0].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 = v4l2_buf.m.planes->data_offset;
+ 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_QCOM_BUF_FLAG_EOS)
+ venc_msg.buf.flags |= OMX_BUFFERFLAG_EOS;
+
+ if (omx->handle->num_output_planes > 1 && v4l2_buf.m.planes->bytesused)
+ venc_msg.buf.flags |= OMX_BUFFERFLAG_EXTRADATA;
+
+ if (omxhdr->nFilledLen)
+ venc_msg.buf.flags |= OMX_BUFFERFLAG_ENDOFFRAME;
+
+ omx->handle->fbd++;
+ stats.bytes_generated += venc_msg.buf.len;
+
+ if (omx->async_message_process(input,&venc_msg) < 0) {
+ DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
+ break;
+ }
+ }
+ }
+
+ if ((pfds[0].revents & POLLOUT) || (pfds[0].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 = omx->handle->num_input_planes;
+
+ while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
+ venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
+ venc_msg.statuscode=VEN_S_SUCCESS;
+ omx->handle->ebd++;
+
+ if (omx->handle->mBatchSize) {
+ int bufIndex = omx->handle->mBatchInfo.retrieveBufferAt(v4l2_buf.index);
+ if (bufIndex < 0) {
+ DEBUG_PRINT_ERROR("Retrieved invalid buffer %d", v4l2_buf.index);
+ break;
+ }
+ if (omx->handle->mBatchInfo.isPending(bufIndex)) {
+ DEBUG_PRINT_LOW(" EBD for %d [v4l2-id=%d].. batch still pending",
+ bufIndex, v4l2_buf.index);
+ //do not return to client yet
+ continue;
+ }
+ v4l2_buf.index = bufIndex;
+ }
+ if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
+ omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
+ else
+ omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
+
+ venc_msg.buf.clientdata=(void*)omxhdr;
+
+ DEBUG_PRINT_LOW("sending EBD %p [id=%d]", omxhdr, v4l2_buf.index);
+ if (omx->async_message_process(input,&venc_msg) < 0) {
+ DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
+ break;
+ }
+ }
+ }
+
+ if (pfds[0].revents & POLLPRI) {
+ rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
+
+ 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("ERROR: 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("ERROR: Wrong ioctl message");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
+ DEBUG_PRINT_ERROR("HW Overload received");
+ venc_msg.statuscode = VEN_S_EFAIL;
+ venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
+
+ if (omx->async_message_process(input,&venc_msg) < 0) {
+ DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
+ break;
+ }
+ } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR){
+ DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
+ venc_msg.msgcode = VEN_MSG_INDICATION;
+ venc_msg.statuscode=VEN_S_EFAIL;
+
+ if (omx->async_message_process(input,&venc_msg) < 0) {
+ DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
+ break;
+ }
+ }
+ }
+
+ /* calc avg. fps, bitrate */
+ struct timeval tv;
+ gettimeofday(&tv,NULL);
+ OMX_U64 time_diff = (OMX_U32)((tv.tv_sec * 1000000 + tv.tv_usec) -
+ (stats.prev_tv.tv_sec * 1000000 + stats.prev_tv.tv_usec));
+ if (time_diff >= 5000000) {
+ if (stats.prev_tv.tv_sec) {
+ OMX_U32 num_fbd = omx->handle->fbd - stats.prev_fbd;
+ float framerate = num_fbd * 1000000/(float)time_diff;
+ OMX_U32 bitrate = (stats.bytes_generated * 8/num_fbd) * framerate;
+ DEBUG_PRINT_HIGH("stats: avg. fps %0.2f, bitrate %d",
+ framerate, bitrate);
+ }
+ stats.prev_tv = tv;
+ stats.bytes_generated = 0;
+ stats.prev_fbd = omx->handle->fbd;
+ }
+
+ }
+
+ DEBUG_PRINT_HIGH("omx_venc: Async Thread exit");
+ return NULL;
+}
+
+static const int event_type[] = {
+ V4L2_EVENT_MSM_VIDC_FLUSH_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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", 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)
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
+ }
+
+ eRet = OMX_ErrorNotImplemented;
+ }
+
+ return eRet;
+}
+
+int venc_dev::append_mbi_extradata(void *dst, struct msm_vidc_extradata_header* src)
+{
+ OMX_QCOM_EXTRADATA_MBINFO *mbi = (OMX_QCOM_EXTRADATA_MBINFO *)dst;
+
+ if (!dst || !src)
+ return 0;
+
+ /* TODO: Once Venus 3XX target names are known, nFormat should 2 for those
+ * targets, since the payload format will be different */
+ mbi->nFormat = 2;
+ mbi->nDataSize = src->data_size;
+ memcpy(&mbi->data, &src->data, src->data_size);
+
+ return mbi->nDataSize + sizeof(*mbi);
+}
+
+bool venc_dev::handle_input_extradata(struct v4l2_buffer buf)
+{
+ OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
+ unsigned int consumed_len = 0, index = 0;
+ int enable = 0, i = 0;
+ int height = 0, width = 0;
+ OMX_TICKS nTimeStamp = buf.timestamp.tv_sec * 1000000 + buf.timestamp.tv_usec;
+ int fd = buf.m.planes[0].reserved[0];
+ bool unknown_extradata = false;
+
+ if (!EXTRADATA_IDX(num_input_planes)) {
+ DEBUG_PRINT_LOW("Input extradata not enabled");
+ return true;
+ }
+
+ if (!input_extradata_info.uaddr) {
+ DEBUG_PRINT_ERROR("Extradata buffers not allocated\n");
+ return false;
+ }
+
+ /*
+ * At this point encoder component doesn't know where the extradata is
+ * located in YUV buffer. For all practical usecases, decoder appends
+ * extradata after nFilledLen which is calcualted as 32 aligned height
+ * and width * 3 / 2. Hence start looking for extradata from this point.
+ */
+
+ DEBUG_PRINT_HIGH("Processing Extradata for Buffer = %lld", nTimeStamp); // Useful for debugging
+
+ height = ALIGN(m_sVenc_cfg.input_height, 32);
+ width = ALIGN(m_sVenc_cfg.input_width, 32);
+
+ index = venc_get_index_from_fd(input_extradata_info.m_ion_dev,fd);
+
+ unsigned char *pVirt;
+ int size = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height);
+ pVirt= (unsigned char *)mmap(NULL, size, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0);
+
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) ((unsigned long)(pVirt + ((width * height * 3) / 2) + 3)&(~3));
+ char *p_extradata = input_extradata_info.uaddr + index * input_extradata_info.buffer_size;
+ OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
+ memset((void *)(data), 0, (input_extradata_info.buffer_size)); // clear stale data in current buffer
+ if (p_extra) {
+ bool vqzip_sei_found = false;
+
+ while ((consumed_len < input_extradata_info.buffer_size)
+ && (p_extra->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)
+ && !unknown_extradata) {
+ DEBUG_PRINT_LOW("Extradata Type = 0x%x", (OMX_QCOM_EXTRADATATYPE)p_extra->eType);
+ switch ((OMX_QCOM_EXTRADATATYPE)p_extra->eType) {
+ case OMX_ExtraDataFrameDimension:
+ {
+ struct msm_vidc_extradata_index *payload;
+ OMX_QCOM_EXTRADATA_FRAMEDIMENSION *framedimension_format;
+ data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_extradata_index) + 3)&(~3);
+ data->nVersion.nVersion = OMX_SPEC_VERSION;
+ data->nPortIndex = 0;
+ data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_INDEX;
+ data->nDataSize = sizeof(struct msm_vidc_input_crop_payload);
+ framedimension_format = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)p_extra->data;
+ payload = (struct msm_vidc_extradata_index *)(data->data);
+ payload->type = (msm_vidc_extradata_type)MSM_VIDC_EXTRADATA_INPUT_CROP;
+ payload->input_crop.left = framedimension_format->nDecWidth;
+ payload->input_crop.top = framedimension_format->nDecHeight;
+ payload->input_crop.width = framedimension_format->nActualWidth;
+ payload->input_crop.height = framedimension_format->nActualHeight;
+ DEBUG_PRINT_LOW("Height = %d Width = %d Actual Height = %d Actual Width = %d",
+ framedimension_format->nDecWidth, framedimension_format->nDecHeight,
+ framedimension_format->nActualWidth, framedimension_format->nActualHeight);
+ data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+ break;
+ }
+ case OMX_ExtraDataQP:
+ {
+ OMX_QCOM_EXTRADATA_QP * qp_payload = NULL;
+ struct msm_vidc_frame_qp_payload *payload;
+ data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct msm_vidc_frame_qp_payload) + 3)&(~3);
+ data->nVersion.nVersion = OMX_SPEC_VERSION;
+ data->nPortIndex = 0;
+ data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_FRAME_QP;
+ data->nDataSize = sizeof(struct msm_vidc_frame_qp_payload);
+ qp_payload = (OMX_QCOM_EXTRADATA_QP *)p_extra->data;
+ payload = (struct msm_vidc_frame_qp_payload *)(data->data);
+ payload->frame_qp = qp_payload->nQP;
+ DEBUG_PRINT_LOW("Frame QP = %d", payload->frame_qp);
+ data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+ break;
+ }
+ case OMX_ExtraDataVQZipSEI:
+ DEBUG_PRINT_LOW("VQZIP SEI Found ");
+ input_extradata_info.vqzip_sei_found = true;
+ break;
+ default:
+ unknown_extradata = true;
+ break;
+ }
+ if (!unknown_extradata) {
+ consumed_len += p_extra->nSize;
+ p_extra = (OMX_OTHER_EXTRADATATYPE *)((char *)p_extra + p_extra->nSize);
+ } else {
+ DEBUG_PRINT_HIGH(" Unknown Extradata. Exiting parsing ");
+ break;
+ }
+ }
+
+ /*
+ * Below code is based on these points.
+ * 1) _PQ_ not defined :
+ * a) Send data to Venus as ROI.
+ * b) ROI enabled : Processed under unlocked context.
+ * c) ROI disabled : Nothing to fill.
+ * d) pq enabled : Not possible.
+ * 2) _PQ_ defined, but pq is not enabled :
+ * a) Send data to Venus as ROI.
+ * b) ROI enabled and dirty : Copy the data to Extradata buffer here
+ * b) ROI enabled and no dirty : Nothing to fill
+ * d) ROI disabled : Nothing to fill
+ * 3) _PQ_ defined and pq is enabled :
+ * a) Send data to Venus as PQ.
+ * b) ROI enabled and dirty : Copy the ROI contents to pq_roi buffer
+ * c) ROI enabled and no dirty : pq_roi is already memset. Hence nothing to do here
+ * d) ROI disabled : Just PQ data will be filled by GPU.
+ * 4) Normal ROI handling is in #else part as PQ can introduce delays.
+ * By this time if client sets next ROI, then we shouldn't process new ROI here.
+ */
+
+#ifdef _PQ_
+ pthread_mutex_lock(&m_pq.lock);
+ if (m_pq.is_pq_enabled) {
+ if (roi.dirty) {
+ struct msm_vidc_roi_qp_payload *roiData =
+ (struct msm_vidc_roi_qp_payload *)(m_pq.roi_extradata_info.uaddr);
+ roiData->upper_qp_offset = roi.info.nUpperQpOffset;
+ roiData->lower_qp_offset = roi.info.nLowerQpOffset;
+ roiData->b_roi_info = roi.info.bUseRoiInfo;
+ roiData->mbi_info_size = roi.info.nRoiMBInfoSize;
+ DEBUG_PRINT_HIGH("Using PQ + ROI QP map: Enable = %d", roiData->b_roi_info);
+ memcpy(roiData->data, roi.info.pRoiMBInfo, roi.info.nRoiMBInfoSize);
+ roi.dirty = false;
+ }
+ consumed_len += sizeof(msm_vidc_extradata_header) - sizeof(unsigned int);
+ data->nDataSize = m_pq.fill_pq_stats(buf, consumed_len);
+ data->nSize = ALIGN(sizeof(msm_vidc_extradata_header) + data->nDataSize, 4);
+ data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_PQ_INFO;
+ } else {
+ data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) +
+ sizeof(struct msm_vidc_roi_qp_payload) +
+ roi.info.nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
+ data->nVersion.nVersion = OMX_SPEC_VERSION;
+ data->nPortIndex = 0;
+ data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
+ data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
+
+ struct msm_vidc_roi_qp_payload *roiData =
+ (struct msm_vidc_roi_qp_payload *)(data->data);
+ roiData->upper_qp_offset = roi.info.nUpperQpOffset;
+ roiData->lower_qp_offset = roi.info.nLowerQpOffset;
+ roiData->b_roi_info = roi.info.bUseRoiInfo;
+ roiData->mbi_info_size = roi.info.nRoiMBInfoSize;
+ DEBUG_PRINT_HIGH("Using ROI QP map: Enable = %d", roiData->b_roi_info);
+ memcpy(roiData->data, roi.info.pRoiMBInfo, roi.info.nRoiMBInfoSize);
+ roi.dirty = false;
+ }
+ pthread_mutex_unlock(&m_pq.lock);
+ data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+#else // _PQ_
+ if (roi.dirty) {
+ data->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) +
+ sizeof(struct msm_vidc_roi_qp_payload) +
+ roi.info.nRoiMBInfoSize - 2 * sizeof(unsigned int), 4);
+ data->nVersion.nVersion = OMX_SPEC_VERSION;
+ data->nPortIndex = 0;
+ data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_ROI_QP;
+ data->nDataSize = sizeof(struct msm_vidc_roi_qp_payload);
+
+ struct msm_vidc_roi_qp_payload *roiData =
+ (struct msm_vidc_roi_qp_payload *)(data->data);
+ roiData->upper_qp_offset = roi.info.nUpperQpOffset;
+ roiData->lower_qp_offset = roi.info.nLowerQpOffset;
+ roiData->b_roi_info = roi.info.bUseRoiInfo;
+ roiData->mbi_info_size = roi.info.nRoiMBInfoSize;
+ DEBUG_PRINT_HIGH("Using ROI QP map: Enable = %d", roiData->b_roi_info);
+ memcpy(roiData->data, roi.info.pRoiMBInfo, roi.info.nRoiMBInfoSize);
+
+ roi.dirty = false;
+ data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+ }
+#endif // _PQ_
+
+#ifdef _VQZIP_
+ if (vqzip_sei_info.enabled && !input_extradata_info.vqzip_sei_found) {
+ DEBUG_PRINT_ERROR("VQZIP is enabled, But no VQZIP SEI found. Rejecting the session");
+ munmap(pVirt, size);
+ return false;
+ }
+ if (vqzip_sei_info.enabled) {
+ data->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + sizeof(struct VQZipStats) + 3)&(~3);
+ data->nVersion.nVersion = OMX_SPEC_VERSION;
+ data->nPortIndex = 0;
+ data->eType = (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_YUVSTATS_INFO;
+ data->nDataSize = sizeof(struct VQZipStats);
+ vqzip.fill_stats_data((void*)pVirt, (void*) data->data);
+ data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
+ }
+#endif
+
+ data->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
+ data->nVersion.nVersion = OMX_SPEC_VERSION;
+ data->eType = OMX_ExtraDataNone;
+ data->nDataSize = 0;
+ data->data[0] = 0;
+
+ }
+ munmap(pVirt, size);
+ return true;
+}
+
+bool venc_dev::handle_output_extradata(void *buffer, int index)
+{
+ OMX_BUFFERHEADERTYPE *p_bufhdr = (OMX_BUFFERHEADERTYPE *) buffer;
+ OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
+
+ if (!output_extradata_info.uaddr) {
+ DEBUG_PRINT_ERROR("Extradata buffers not allocated\n");
+ return false;
+ }
+
+ p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
+ p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
+
+ if (output_extradata_info.buffer_size >
+ p_bufhdr->nAllocLen - ALIGN(p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4)) {
+ DEBUG_PRINT_ERROR("Insufficient buffer size for extradata");
+ p_extra = NULL;
+ return false;
+ } else if (sizeof(msm_vidc_extradata_header) != sizeof(OMX_OTHER_EXTRADATATYPE)) {
+ /* A lot of the code below assumes this condition, so error out if it's not met */
+ DEBUG_PRINT_ERROR("Extradata ABI mismatch");
+ return false;
+ }
+
+ struct msm_vidc_extradata_header *p_extradata = NULL;
+ do {
+ p_extradata = (struct msm_vidc_extradata_header *) (p_extradata ?
+ ((char *)p_extradata) + p_extradata->size :
+ output_extradata_info.uaddr + index * output_extradata_info.buffer_size);
+
+ switch (p_extradata->type) {
+ case MSM_VIDC_EXTRADATA_METADATA_MBI:
+ {
+ OMX_U32 payloadSize = append_mbi_extradata(&p_extra->data, p_extradata);
+ p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + payloadSize, 4);
+ p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ p_extra->nPortIndex = OMX_DirOutput;
+ p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVideoEncoderMBInfo;
+ p_extra->nDataSize = payloadSize;
+ break;
+ }
+ case MSM_VIDC_EXTRADATA_METADATA_LTR:
+ {
+ *p_extra->data = *p_extradata->data;
+ p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4);
+ p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ p_extra->nPortIndex = OMX_DirOutput;
+ p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo;
+ p_extra->nDataSize = p_extradata->data_size;
+ break;
+ }
+ case MSM_VIDC_EXTRADATA_NONE:
+ p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
+ p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
+ p_extra->nPortIndex = OMX_DirOutput;
+ p_extra->eType = OMX_ExtraDataNone;
+ p_extra->nDataSize = 0;
+ break;
+ default:
+ /* No idea what this stuff is, just skip over it */
+ DEBUG_PRINT_HIGH("Found an unrecognised extradata (%x) ignoring it",
+ p_extradata->type);
+ continue;
+ }
+
+ p_extra = (OMX_OTHER_EXTRADATATYPE *)(((char *)p_extra) + p_extra->nSize);
+ } while (p_extradata->type != MSM_VIDC_EXTRADATA_NONE);
+
+ /* Just for debugging: Traverse the list of extra datas and spit it out onto log */
+ p_extra = (OMX_OTHER_EXTRADATATYPE *)ALIGN(p_bufhdr->pBuffer +
+ p_bufhdr->nOffset + p_bufhdr->nFilledLen, 4);
+ while(p_extra->eType != OMX_ExtraDataNone)
+ {
+ DEBUG_PRINT_LOW("[%p/%u] found extradata type %x of size %u (%u) at %p",
+ p_bufhdr->pBuffer, (unsigned int)p_bufhdr->nFilledLen, p_extra->eType,
+ (unsigned int)p_extra->nSize, (unsigned int)p_extra->nDataSize, p_extra);
+
+ p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) +
+ p_extra->nSize);
+ }
+
+ return true;
+}
+
+int venc_dev::venc_set_format(int format)
+{
+ int rc = true;
+
+ if (format) {
+ color_format = format;
+
+ switch (color_format) {
+ case NV12_128m:
+ return venc_set_color_format((OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m);
+ default:
+ return false;
+ }
+
+ } else {
+ color_format = 0;
+ rc = false;
+ }
+
+ return rc;
+}
+
+OMX_ERRORTYPE venc_dev::allocate_extradata(struct extradata_buffer_info *extradata_info)
+{
+ if (extradata_info->allocated) {
+ DEBUG_PRINT_HIGH("2nd allocation return for port = %d",extradata_info->port_index);
+ 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);
+ venc_handle->free_ion_memory(&extradata_info->ion);
+ }
+
+ extradata_info->size = (extradata_info->size + 4095) & (~4095);
+
+ extradata_info->ion.ion_device_fd = venc_handle->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);
+ venc_handle->free_ion_memory(&extradata_info->ion);
+ return OMX_ErrorInsufficientResources;
+ }
+ extradata_info->m_ion_dev = open("/dev/ion", O_RDONLY);
+ }
+
+#endif
+ extradata_info->allocated = OMX_TRUE;
+ return OMX_ErrorNone;
+}
+
+void venc_dev::free_extradata()
+{
+#ifdef USE_ION
+
+ if (output_extradata_info.uaddr) {
+ munmap((void *)output_extradata_info.uaddr, output_extradata_info.size);
+ close(output_extradata_info.ion.fd_ion_data.fd);
+ venc_handle->free_ion_memory(&output_extradata_info.ion);
+ }
+ if (output_extradata_info.m_ion_dev)
+ close(output_extradata_info.m_ion_dev);
+
+ memset(&output_extradata_info, 0, sizeof(output_extradata_info));
+ output_extradata_info.ion.fd_ion_data.fd = -1;
+
+ if (input_extradata_info.uaddr) {
+ munmap((void *)input_extradata_info.uaddr, input_extradata_info.size);
+ close(input_extradata_info.ion.fd_ion_data.fd);
+ venc_handle->free_ion_memory(&input_extradata_info.ion);
+ }
+
+ if (input_extradata_info.m_ion_dev)
+ close(output_extradata_info.m_ion_dev);
+
+ memset(&input_extradata_info, 0, sizeof(input_extradata_info));
+ input_extradata_info.ion.fd_ion_data.fd = -1;
+
+#ifdef _PQ_
+ if (m_pq.roi_extradata_info.uaddr) {
+ munmap((void *)m_pq.roi_extradata_info.uaddr, m_pq.roi_extradata_info.size);
+ close(m_pq.roi_extradata_info.ion.fd_ion_data.fd);
+ venc_handle->free_ion_memory(&m_pq.roi_extradata_info.ion);
+ }
+
+ memset(&m_pq.roi_extradata_info, 0, sizeof(m_pq.roi_extradata_info));
+ m_pq.roi_extradata_info.ion.fd_ion_data.fd = -1;
+#endif // _PQ_
+
+#endif
+}
+
+bool venc_dev::venc_get_output_log_flag()
+{
+ return (m_debug.out_buffer_log == 1);
+}
+
+int venc_dev::venc_output_log_buffers(const char *buffer_addr, int buffer_len)
+{
+ if (venc_handle->is_secure_session()) {
+ DEBUG_PRINT_ERROR("logging secure output buffers is not allowed!");
+ return -1;
+ }
+
+ if (!m_debug.outfile) {
+ int size = 0;
+ if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.m4v",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.ivf",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ }
+ if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
+ DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
+ m_debug.outfile_name, size);
+ }
+ m_debug.outfile = fopen(m_debug.outfile_name, "ab");
+ if (!m_debug.outfile) {
+ DEBUG_PRINT_ERROR("Failed to open output file: %s for logging errno:%d",
+ m_debug.outfile_name, errno);
+ m_debug.outfile_name[0] = '\0';
+ return -1;
+ }
+ }
+ if (m_debug.outfile && buffer_len) {
+ DEBUG_PRINT_LOW("%s buffer_len:%d", __func__, buffer_len);
+ fwrite(buffer_addr, buffer_len, 1, m_debug.outfile);
+ }
+ return 0;
+}
+
+int venc_dev::venc_extradata_log_buffers(char *buffer_addr)
+{
+ if (!m_debug.extradatafile && m_debug.extradata_log) {
+ int size = 0;
+ if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
+ size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.bin",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.bin",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.bin",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
+ size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.bin",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.bin",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ }
+ if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
+ DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging size:%d",
+ m_debug.extradatafile_name, size);
+ }
+
+ m_debug.extradatafile = fopen(m_debug.extradatafile_name, "ab");
+ if (!m_debug.extradatafile) {
+ DEBUG_PRINT_ERROR("Failed to open extradata file: %s for logging errno:%d",
+ m_debug.extradatafile_name, errno);
+ m_debug.extradatafile_name[0] = '\0';
+ return -1;
+ }
+ }
+
+ if (m_debug.extradatafile && buffer_addr) {
+ OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
+ do {
+ p_extra = (OMX_OTHER_EXTRADATATYPE *)(!p_extra ? buffer_addr :
+ ((char *)p_extra) + p_extra->nSize);
+ fwrite(p_extra, p_extra->nSize, 1, m_debug.extradatafile);
+ } while (p_extra->eType != OMX_ExtraDataNone);
+ }
+ return 0;
+}
+
+int venc_dev::venc_input_log_buffers(OMX_BUFFERHEADERTYPE *pbuffer, int fd, int plane_offset,
+ unsigned long inputformat) {
+ if (venc_handle->is_secure_session()) {
+ DEBUG_PRINT_ERROR("logging secure input buffers is not allowed!");
+ return -1;
+ }
+
+ if (!m_debug.infile) {
+ int size = snprintf(m_debug.infile_name, PROPERTY_VALUE_MAX, "%s/input_enc_%lu_%lu_%p.yuv",
+ m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+ if ((size > PROPERTY_VALUE_MAX) && (size < 0)) {
+ DEBUG_PRINT_ERROR("Failed to open output file: %s for logging size:%d",
+ m_debug.infile_name, size);
+ }
+ m_debug.infile = fopen (m_debug.infile_name, "ab");
+ if (!m_debug.infile) {
+ DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
+ m_debug.infile_name[0] = '\0';
+ return -1;
+ }
+ }
+
+ if (m_debug.infile && pbuffer && pbuffer->nFilledLen) {
+ int stride, scanlines;
+ int color_format;
+ unsigned long i, msize;
+ unsigned char *pvirt = NULL, *ptemp = NULL;
+ unsigned char *temp = (unsigned char *)pbuffer->pBuffer;
+
+ switch (inputformat) {
+ case V4L2_PIX_FMT_NV12:
+ color_format = COLOR_FMT_NV12;
+ break;
+ case V4L2_PIX_FMT_NV12_UBWC:
+ color_format = COLOR_FMT_NV12_UBWC;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ color_format = COLOR_FMT_RGBA8888;
+ break;
+ case V4L2_PIX_FMT_RGBA8888_UBWC:
+ color_format = COLOR_FMT_RGBA8888_UBWC;
+ break;
+ default:
+ color_format = COLOR_FMT_NV12;
+ DEBUG_PRINT_LOW("Default format NV12 is set for logging [%lu]", inputformat);
+ break;
+ }
+
+ msize = VENUS_BUFFER_SIZE(color_format, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
+ const unsigned int extra_size = VENUS_EXTRADATA_SIZE(m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
+
+ if (metadatamode == 1) {
+ pvirt= (unsigned char *)mmap(NULL, msize, PROT_READ|PROT_WRITE,MAP_SHARED, fd, plane_offset);
+ if (pvirt == MAP_FAILED) {
+ DEBUG_PRINT_ERROR("%s mmap failed", __func__);
+ return -1;
+ }
+ ptemp = pvirt;
+ } else {
+ ptemp = temp;
+ }
+
+ if (color_format == COLOR_FMT_NV12) {
+ stride = VENUS_Y_STRIDE(color_format, m_sVenc_cfg.input_width);
+ scanlines = VENUS_Y_SCANLINES(color_format, m_sVenc_cfg.input_height);
+
+ for (i = 0; i < m_sVenc_cfg.input_height; i++) {
+ fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
+ ptemp += stride;
+ }
+ if (metadatamode == 1) {
+ ptemp = pvirt + (stride * scanlines);
+ } else {
+ ptemp = (unsigned char *)pbuffer->pBuffer + (stride * scanlines);
+ }
+ for (i = 0; i < m_sVenc_cfg.input_height/2; i++) {
+ fwrite(ptemp, m_sVenc_cfg.input_width, 1, m_debug.infile);
+ ptemp += stride;
+ }
+ } else if (color_format == COLOR_FMT_RGBA8888) {
+ stride = VENUS_RGB_STRIDE(color_format, m_sVenc_cfg.input_width);
+ scanlines = VENUS_RGB_SCANLINES(color_format, m_sVenc_cfg.input_height);
+
+ for (i = 0; i < m_sVenc_cfg.input_height; i++) {
+ fwrite(ptemp, m_sVenc_cfg.input_width * 4, 1, m_debug.infile);
+ ptemp += stride;
+ }
+ } else if (color_format == COLOR_FMT_NV12_UBWC || color_format == COLOR_FMT_RGBA8888_UBWC) {
+ if (color_format == COLOR_FMT_NV12_UBWC) {
+ msize -= 2 * extra_size;
+ }
+ fwrite(ptemp, msize, 1, m_debug.infile);
+ }
+
+ if (metadatamode == 1 && pvirt) {
+ munmap(pvirt, msize);
+ }
+ }
+
+ return 0;
+}
+
+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/video33";
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+ char platform_name[PROPERTY_VALUE_MAX] = {0};
+ FILE *soc_file = NULL;
+ char buffer[10];
+
+ property_get("ro.board.platform", platform_name, "0");
+ property_get("vidc.enc.narrow.searchrange", property_value, "0");
+ enable_mv_narrow_searchrange = atoi(property_value);
+
+ if (!strncmp(platform_name, "msm8610", 7)) {
+ device_name = (OMX_STRING)"/dev/video/q6_enc";
+ supported_rc_modes = (RC_ALL & ~RC_CBR_CFR);
+ }
+ m_nDriver_fd = open (device_name, O_RDWR);
+ if ((int)m_nDriver_fd < 0) {
+ DEBUG_PRINT_ERROR("ERROR: Omx_venc::Comp Init Returning failure");
+ return false;
+ }
+ m_poll_efd = eventfd(0, 0);
+ if (m_poll_efd < 0) {
+ DEBUG_PRINT_ERROR("Failed to open event fd(%s)", strerror(errno));
+ return false;
+ }
+ DEBUG_PRINT_LOW("m_nDriver_fd = %u", (unsigned int)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_DEFAULT_OUTPUT_COLOR_FMT;
+
+ m_codec = codec;
+
+ 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;
+ session_qp_range.minqp = 1;
+ session_qp_range.maxqp = 31;
+ } 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;
+ session_qp_range.minqp = 1;
+ session_qp_range.maxqp = 31;
+ } else 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;
+ session_qp_range.minqp = 1;
+ session_qp_range.maxqp = 51;
+ } else if (codec == OMX_VIDEO_CodingVP8) {
+ m_sVenc_cfg.codectype = V4L2_PIX_FMT_VP8;
+ codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
+ profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
+ session_qp_range.minqp = 1;
+ session_qp_range.maxqp = 128;
+ } else if (codec == OMX_VIDEO_CodingHEVC) {
+ m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
+ session_qp_range.minqp = 1;
+ session_qp_range.maxqp = 51;
+ codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
+ profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
+ }
+ session_qp_values.minqp = session_qp_range.minqp;
+ session_qp_values.maxqp = session_qp_range.maxqp;
+ session_ipb_qp_values.min_i_qp = session_qp_range.minqp;
+ session_ipb_qp_values.max_i_qp = session_qp_range.maxqp;
+ session_ipb_qp_values.min_p_qp = session_qp_range.minqp;
+ session_ipb_qp_values.max_p_qp = session_qp_range.maxqp;
+ session_ipb_qp_values.min_b_qp = session_qp_range.minqp;
+ session_ipb_qp_values.max_b_qp = session_qp_range.maxqp;
+
+ int ret;
+ ret = subscribe_to_events(m_nDriver_fd);
+
+ if (ret) {
+ DEBUG_PRINT_ERROR("Subscribe Event Failed");
+ return false;
+ }
+
+ struct v4l2_fmtdesc fdesc;
+ struct v4l2_format fmt;
+ struct v4l2_requestbuffers bufreq;
+ struct v4l2_capability cap;
+
+ ret = ioctl(m_nDriver_fd, VIDIOC_QUERYCAP, &cap);
+
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to query capabilities");
+ } else {
+ DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
+ " version = %d, capabilities = %x", 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", 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", fdesc.description,
+ fdesc.pixelformat, fdesc.flags);
+ fdesc.index++;
+ }
+
+ is_thulium_v1 = false;
+ soc_file= fopen("/sys/devices/soc0/soc_id", "r");
+ if (soc_file) {
+ fread(buffer, 1, 4, soc_file);
+ fclose(soc_file);
+ if (atoi(buffer) == 246) {
+ soc_file = fopen("/sys/devices/soc0/revision", "r");
+ if (soc_file) {
+ fread(buffer, 1, 4, soc_file);
+ fclose(soc_file);
+ if (atoi(buffer) == 1) {
+ is_thulium_v1 = true;
+ DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
+ }
+ }
+ }
+ }
+
+ if (venc_handle->is_secure_session()) {
+ m_sOutput_buff_property.alignment = SZ_1M;
+ m_sInput_buff_property.alignment = SZ_1M;
+ } else {
+ m_sOutput_buff_property.alignment = SZ_4K;
+ m_sInput_buff_property.alignment = SZ_4K;
+ }
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_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");
+ return false;
+ }
+
+ m_sOutput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+
+ memset(&fmt, 0, sizeof(fmt));
+ 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_DEFAULT_OUTPUT_COLOR_FMT;
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+
+ 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;
+
+ if(venc_handle->is_secure_session()) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
+ control.value = 1;
+ DEBUG_PRINT_HIGH("ioctl: open secure device");
+ ret=ioctl(m_nDriver_fd, VIDIOC_S_CTRL,&control);
+ if (ret) {
+ DEBUG_PRINT_ERROR("ioctl: open secure dev fail, rc %d", ret);
+ return false;
+ }
+ }
+
+ resume_in_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", control.id, control.value);
+
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
+ DEBUG_PRINT_ERROR("Failed to set control");
+
+ 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");
+ 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;
+ }
+
+ //Initialize non-default parameters
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
+ control.value = 0x7fffffff;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control))
+ DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
+ }
+
+ property_get("vidc.debug.turbo", property_value, "0");
+ if (atoi(property_value)) {
+ DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
+ control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set turbo mode");
+ }
+ }
+
+#ifdef _PQ_
+ if (codec == OMX_VIDEO_CodingAVC) {
+ m_pq.init(V4L2_DEFAULT_OUTPUT_COLOR_FMT);
+ allocate_extradata(&m_pq.roi_extradata_info);
+ m_pq.get_caps();
+ }
+#endif // _PQ_
+
+ input_extradata_info.port_index = OUTPUT_PORT;
+ output_extradata_info.port_index = CAPTURE_PORT;
+
+ 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) {
+ DEBUG_PRINT_ERROR("Invalid input: %d", 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) {
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
+ break;
+ }
+ }
+
+ return eRet;
+}
+
+void venc_dev::venc_close()
+{
+ DEBUG_PRINT_LOW("venc_close: fd = %u", (unsigned int)m_nDriver_fd);
+
+ if ((int)m_nDriver_fd >= 0) {
+ DEBUG_PRINT_HIGH("venc_close E");
+
+ if(eventfd_write(m_poll_efd, 1)) {
+ DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
+ async_thread_force_stop = true;
+ }
+
+ if (async_thread_created)
+ pthread_join(m_tid,NULL);
+
+ DEBUG_PRINT_HIGH("venc_close X");
+ unsubscribe_to_events(m_nDriver_fd);
+ close(m_poll_efd);
+ close(m_nDriver_fd);
+ m_nDriver_fd = -1;
+ }
+
+#ifdef _PQ_
+ m_pq.deinit();
+#endif // _PQ_
+
+#ifdef _VQZIP_
+ vqzip.deinit();
+#endif
+
+ if (m_debug.infile) {
+ fclose(m_debug.infile);
+ m_debug.infile = NULL;
+ }
+
+ if (m_debug.outfile) {
+ fclose(m_debug.outfile);
+ m_debug.outfile = NULL;
+ }
+
+ if (m_debug.extradatafile) {
+ fclose(m_debug.extradatafile);
+ m_debug.extradatafile = NULL;
+ }
+}
+
+bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 port)
+{
+ (void)min_buff_count, (void)buff_size;
+ 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("I/P Count set to %u", (unsigned int)*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("O/P Count set to %u", (unsigned int)*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)
+{
+ (void) buffer, (void) buffer_size, (void) header_len;
+ return true;
+}
+
+bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
+ OMX_U32 *actual_buff_count,
+ OMX_U32 *buff_size,
+ OMX_U32 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;
+ int extra_idx = 0;
+
+ 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 = m_sVenc_cfg.inputformat;
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+ 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;
+
+ // Increase buffer-header count for metadata-mode on input port
+ // to improve buffering and reduce bottlenecks in clients
+ if (metadatamode && (bufreq.count < 9)) {
+ DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 9",
+ bufreq.count);
+ bufreq.count = 9;
+ }
+ if (m_sVenc_cfg.input_height * m_sVenc_cfg.input_width >= 3840*2160) {
+ DEBUG_PRINT_LOW("Increasing buffer count = %d to 11", bufreq.count);
+ bufreq.count = 11;
+ }
+
+ int actualCount = bufreq.count;
+ // Request MAX_V4L2_BUFS from V4L2 in batch mode.
+ // Keep the original count for the client
+ if (metadatamode && mBatchSize) {
+ bufreq.count = MAX_V4L2_BUFS;
+ }
+
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
+
+ if (ret) {
+ DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
+ return false;
+ }
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
+ fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
+ ret = ioctl(m_nDriver_fd, VIDIOC_G_FMT, &fmt);
+ m_sInput_buff_property.datasize=fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+
+ if (metadatamode && mBatchSize) {
+ m_sInput_buff_property.mincount = m_sInput_buff_property.actualcount = actualCount;
+ } else {
+ 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 = ALIGN(m_sInput_buff_property.datasize, SZ_4K);
+#endif
+ *buff_size = m_sInput_buff_property.datasize;
+ num_input_planes = fmt.fmt.pix_mp.num_planes;
+ extra_idx = EXTRADATA_IDX(num_input_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;
+ }
+ input_extradata_info.buffer_size = ALIGN(extra_data_size, SZ_4K);
+ input_extradata_info.count = MAX_V4L2_BUFS;
+ input_extradata_info.size = input_extradata_info.buffer_size * input_extradata_info.count;
+
+ } else {
+ unsigned int extra_idx = 0;
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_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.dvs_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_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 (mBatchSize) {
+ // If we're in batch mode, we'd like to end up in a situation where
+ // driver is able to own mBatchSize buffers and we'd also own atleast
+ // mBatchSize buffers
+ bufreq.count = MAX(*actual_buff_count, mBatchSize) + mBatchSize;
+ } else 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("VIDIOC_REQBUFS CAPTURE_MPLANE Failed");
+ 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_output_planes = fmt.fmt.pix_mp.num_planes;
+ extra_idx = EXTRADATA_IDX(num_output_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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+
+ output_extradata_info.buffer_size = extra_data_size;
+ output_extradata_info.count = m_sOutput_buff_property.actualcount;
+ output_extradata_info.size = output_extradata_info.buffer_size * output_extradata_info.count;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_param(void *paramData, OMX_INDEXTYPE index)
+{
+ DEBUG_PRINT_LOW("venc_set_param:: venc-720p");
+ struct v4l2_format fmt;
+ struct v4l2_requestbuffers bufreq;
+ int ret;
+
+ switch ((int)index) {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+ DEBUG_PRINT_LOW("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;
+ }
+#ifdef _PQ_
+ venc_try_enable_pq();
+ #endif // _PQ_
+
+ if (enable_mv_narrow_searchrange &&
+ (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
+ (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
+ if (venc_set_searchrange() == false) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
+ }
+ }
+ if (m_sVenc_cfg.input_height != portDefn->format.video.nFrameHeight ||
+ m_sVenc_cfg.input_width != portDefn->format.video.nFrameWidth) {
+ 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;
+
+ memset(&fmt, 0, sizeof(fmt));
+ 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 = m_sVenc_cfg.inputformat;
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+
+ if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
+ DEBUG_PRINT_ERROR("VIDIOC_S_FMT OUTPUT_MPLANE Failed");
+ hw_overload = errno == EBUSY;
+ 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("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
+ 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;
+ if (num_input_planes > 1)
+ input_extradata_info.count = m_sInput_buff_property.actualcount + 1;
+
+ }
+
+ DEBUG_PRINT_LOW("input: actual: %u, min: %u, count_req: %u",
+ (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sInput_buff_property.mincount, bufreq.count);
+ } else if (portDefn->nPortIndex == PORT_INDEX_OUT) {
+ m_sVenc_cfg.dvs_height = portDefn->format.video.nFrameHeight;
+ m_sVenc_cfg.dvs_width = portDefn->format.video.nFrameWidth;
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
+ fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
+
+ if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
+ DEBUG_PRINT_ERROR("VIDIOC_S_FMT CAPTURE_MPLANE Failed");
+ hw_overload = errno == EBUSY;
+ 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;
+ }
+
+ 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("ERROR: Request for setting o/p buffer count failed: requested: %u, current: %u",
+ (unsigned int)portDefn->nBufferCountActual, (unsigned int)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_output_planes > 1)
+ output_extradata_info.count = m_sOutput_buff_property.actualcount;
+
+ DEBUG_PRINT_LOW("Output: actual: %u, min: %u, count_req: %u",
+ (unsigned int)portDefn->nBufferCountActual, (unsigned int)m_sOutput_buff_property.mincount, bufreq.count);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+
+ 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("ERROR: Invalid Port Index for OMX_IndexParamVideoPortFormat");
+ }
+#ifdef _PQ_
+ venc_try_enable_pq();
+#endif // _PQ_
+
+ break;
+ }
+ case OMX_IndexParamVideoBitrate:
+ {
+ OMX_VIDEO_PARAM_BITRATETYPE* pParam;
+ pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
+ DEBUG_PRINT_LOW("venc_set_param: OMX_IndexParamVideoBitrate");
+
+ if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+ if (!venc_set_target_bitrate(pParam->nTargetBitrate, 0)) {
+ DEBUG_PRINT_ERROR("ERROR: Target Bit Rate setting failed");
+ return false;
+ }
+
+ if (!venc_set_ratectrl_cfg(pParam->eControlRate)) {
+ DEBUG_PRINT_ERROR("ERROR: Rate Control setting failed");
+ return false;
+ }
+#ifdef _PQ_
+ venc_try_enable_pq();
+#endif // _PQ_
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+
+ if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+ if (!venc_set_voptiming_cfg(pParam->nTimeIncRes)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting vop_timing failed");
+ return false;
+ }
+
+ m_profile_set = false;
+ m_level_set = false;
+ rc_off_level = (int)pParam->eLevel;
+ if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
+ return false;
+ } else {
+ if (pParam->eProfile == OMX_VIDEO_MPEG4ProfileAdvancedSimple) {
+ if (pParam->nBFrames) {
+ bFrames = pParam->nBFrames;
+ }
+ } else {
+ if (pParam->nBFrames) {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported");
+ bFrames = 0;
+ }
+ }
+ }
+
+ if (!venc_set_intra_period (pParam->nPFrames,bFrames)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+
+ if (!venc_set_multislice_cfg(OMX_IndexParamVideoMpeg4,pParam->nSliceHeaderSpacing)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating slice_config");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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");
+ OMX_U32 bFrames = 0;
+
+ if (pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+ m_profile_set = false;
+ m_level_set = false;
+ rc_off_level = (int)pParam->eLevel;
+ if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level");
+ return false;
+ }
+
+ if (pParam->nBFrames)
+ DEBUG_PRINT_ERROR("WARNING: B frame not supported for H.263");
+
+ if (venc_set_intra_period (pParam->nPFrames, bFrames) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoH263");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoAvc:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoAvc");
+ 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",
+ pParam->eProfile,pParam->eLevel);
+
+ m_profile_set = false;
+ m_level_set = false;
+ rc_off_level = (int)pParam->eLevel;
+ if (!venc_set_profile_level (pParam->eProfile,pParam->eLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
+ pParam->eProfile, pParam->eLevel);
+ return false;
+ } else {
+ if ((pParam->eProfile != OMX_VIDEO_AVCProfileBaseline) &&
+ (pParam->eProfile != (OMX_VIDEO_AVCPROFILETYPE) QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
+ if (pParam->nBFrames) {
+ bFrames = pParam->nBFrames;
+ }
+ } else {
+ if (pParam->nBFrames) {
+ DEBUG_PRINT_ERROR("Warning: B frames not supported");
+ bFrames = 0;
+ }
+ }
+ }
+
+ if (!venc_set_intra_period (pParam->nPFrames, bFrames)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+
+ if (!venc_set_entropy_config (pParam->bEntropyCodingCABAC, pParam->nCabacInitIdc)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting Entropy failed");
+ return false;
+ }
+
+ if (!venc_set_inloop_filter (pParam->eLoopFilterMode)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting Inloop filter failed");
+ return false;
+ }
+
+ if (!venc_set_multislice_cfg(OMX_IndexParamVideoAvc, pParam->nSliceHeaderSpacing)) {
+ DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating slice_config");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoAvc");
+ }
+
+ //TBD, lot of other variables to be updated, yet to decide
+ break;
+ }
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoVp8:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoVp8");
+ OMX_VIDEO_PARAM_VP8TYPE* pParam = (OMX_VIDEO_PARAM_VP8TYPE*)paramData;
+ rc_off_level = (int)pParam->eLevel;
+ if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
+ pParam->eProfile, pParam->eLevel);
+ return false;
+ }
+ if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
+ return false;
+ }
+ if(!venc_set_ltrmode(1, ltrinfo.count)) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
+ return false;
+ }
+
+ // For VP8, hier-p and ltr are mutually exclusive features in firmware
+ // Disable hier-p if ltr is enabled.
+ if (m_codec == OMX_VIDEO_CodingVP8) {
+ DEBUG_PRINT_LOW("Disable Hier-P as LTR is being set");
+ if (!venc_set_hier_layers(QOMX_HIERARCHICALCODING_P, 0)) {
+ DEBUG_PRINT_ERROR("Disabling Hier P count failed");
+ }
+ }
+
+ break;
+ }
+ case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
+ OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
+ rc_off_level = (int)pParam->eLevel;
+ if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
+ pParam->eProfile, pParam->eLevel);
+ return false;
+ }
+ if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
+ DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
+
+ OMX_U32 fps = m_sVenc_cfg.fps_num ? m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den : 30;
+ OMX_U32 nPFrames = pParam->nKeyFrameInterval > 0 ? pParam->nKeyFrameInterval - 1 : fps - 1;
+ if (!venc_set_intra_period (nPFrames, 0 /* nBFrames */)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+ break;
+ }
+ case OMX_IndexParamVideoIntraRefresh:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
+ 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("ERROR: Setting Intra refresh failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoIntraRefresh");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoErrorCorrection:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoErrorCorrection");
+ 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("ERROR: Setting Intra refresh failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoErrorCorrection");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoProfileLevelCurrent:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoProfileLevelCurrent");
+ 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;
+ rc_off_level = (int)profile_level->eLevel;
+ if (!venc_set_profile_level (profile_level->eProfile,
+ profile_level->eLevel)) {
+ DEBUG_PRINT_ERROR("WARNING: Unsuccessful in updating Profile and level");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoProfileLevelCurrent");
+ }
+
+ break;
+ }
+ case OMX_IndexParamVideoQuantization:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoQuantization");
+ 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("ERROR: Setting Session QP failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexParamVideoQuantization");
+ }
+
+ break;
+ }
+ case QOMX_IndexParamVideoInitialQp:
+ {
+ QOMX_EXTNINDEX_VIDEO_INITIALQP * initqp =
+ (QOMX_EXTNINDEX_VIDEO_INITIALQP *)paramData;
+ if (initqp->bEnableInitQp) {
+ DEBUG_PRINT_LOW("Enable initial QP: %d", (int)initqp->bEnableInitQp);
+ if(venc_enable_initial_qp(initqp) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to enable initial QP");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ } else
+ DEBUG_PRINT_ERROR("ERROR: setting QOMX_IndexParamVideoEnableInitialQp");
+ break;
+ }
+ case OMX_QcomIndexParamVideoQPRange:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoQPRange");
+ OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *session_qp_range =
+ (OMX_QCOM_VIDEO_PARAM_QPRANGETYPE *)paramData;
+
+ if(session_qp_range->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
+ if(venc_set_session_qp_range (session_qp_range->minQP,
+ session_qp_range->maxQP) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting QP Range[%u %u] failed",
+ (unsigned int)session_qp_range->minQP, (unsigned int)session_qp_range->maxQP);
+ return false;
+ } else {
+ session_qp_values.minqp = session_qp_range->minQP;
+ session_qp_values.maxqp = session_qp_range->maxQP;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoQPRange");
+ }
+
+ break;
+ }
+ case OMX_QcomIndexParamVideoIPBQPRange:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:OMX_QcomIndexParamVideoIPBQPRange");
+ OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *qp =
+ (OMX_QCOM_VIDEO_PARAM_IPB_QPRANGETYPE *)paramData;
+ OMX_U32 min_IPB_packed_QP = 0;
+ OMX_U32 max_IPB_packed_QP = 0;
+ if (((qp->minIQP >= session_qp_range.minqp) && (qp->maxIQP <= session_qp_range.maxqp)) &&
+ ((qp->minPQP >= session_qp_range.minqp) && (qp->maxPQP <= session_qp_range.maxqp)) &&
+ ((qp->minBQP >= session_qp_range.minqp) && (qp->maxBQP <= session_qp_range.maxqp))) {
+
+ /* When creating the packet, pack the qp value as
+ * 0xbbppii, where ii = qp range for I-frames,
+ * pp = qp range for P-frames, etc. */
+ min_IPB_packed_QP = qp->minIQP | qp->minPQP << 8 | qp->minBQP << 16;
+ max_IPB_packed_QP = qp->maxIQP | qp->maxPQP << 8 | qp->maxBQP << 16;
+
+ if (qp->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
+ if (venc_set_session_qp_range_packed(min_IPB_packed_QP,
+ max_IPB_packed_QP) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting IPB QP Range[%d %d] failed",
+ min_IPB_packed_QP, max_IPB_packed_QP);
+ return false;
+ } else {
+ session_ipb_qp_values.min_i_qp = qp->minIQP;
+ session_ipb_qp_values.max_i_qp = qp->maxIQP;
+ session_ipb_qp_values.min_p_qp = qp->minPQP;
+ session_ipb_qp_values.max_p_qp = qp->maxPQP;
+ session_ipb_qp_values.min_b_qp = qp->minBQP;
+ session_ipb_qp_values.max_b_qp = qp->maxBQP;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexParamVideoIPBQPRange");
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Wrong qp values: IQP range[%u %u], PQP range[%u,%u], BQP[%u,%u] range allowed range[%u %u]",
+ (unsigned int)qp->minIQP, (unsigned int)qp->maxIQP , (unsigned int)qp->minPQP,
+ (unsigned int)qp->maxPQP, (unsigned int)qp->minBQP, (unsigned int)qp->maxBQP,
+ (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
+ }
+ 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(%u)", (unsigned int)pParam->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ break;
+ }
+ case OMX_ExtraDataFrameDimension:
+ {
+ DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataFrameDimension");
+ OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
+
+ if (venc_set_extradata(OMX_ExtraDataFrameDimension, extra_data) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataFrameDimension failed");
+ return false;
+ }
+
+ extradata = true;
+ break;
+ }
+ case OMX_ExtraDataVideoEncoderSliceInfo:
+ {
+ DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderSliceInfo");
+ OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
+
+ if (venc_set_extradata(OMX_ExtraDataVideoEncoderSliceInfo, extra_data) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderSliceInfo failed");
+ return false;
+ }
+
+ extradata = true;
+ break;
+ }
+ case OMX_ExtraDataVideoEncoderMBInfo:
+ {
+ DEBUG_PRINT_LOW("venc_set_param: OMX_ExtraDataVideoEncoderMBInfo");
+ OMX_BOOL extra_data = *(OMX_BOOL *)(paramData);
+
+ if (venc_set_extradata(OMX_ExtraDataVideoEncoderMBInfo, extra_data) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_ExtraDataVideoEncoderMBInfo failed");
+ return false;
+ }
+
+ extradata = true;
+ break;
+ }
+ case OMX_QcomIndexParamSequenceHeaderWithIDR:
+ {
+ PrependSPSPPSToIDRFramesParams * pParam =
+ (PrependSPSPPSToIDRFramesParams *)paramData;
+
+ DEBUG_PRINT_LOW("set inband sps/pps: %d", pParam->bEnable);
+ if(venc_set_inband_video_header(pParam->bEnable) == false) {
+ DEBUG_PRINT_ERROR("ERROR: set inband sps/pps failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ break;
+ }
+ case OMX_QcomIndexParamH264AUDelimiter:
+ {
+ OMX_QCOM_VIDEO_CONFIG_H264_AUD * pParam =
+ (OMX_QCOM_VIDEO_CONFIG_H264_AUD *)paramData;
+
+ DEBUG_PRINT_LOW("set AU delimiters: %d", pParam->bEnable);
+ if(venc_set_au_delimiter(pParam->bEnable) == false) {
+ DEBUG_PRINT_ERROR("ERROR: set H264 AU delimiter failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ break;
+ }
+ case OMX_QcomIndexParamMBIStatisticsMode:
+ {
+ OMX_QOMX_VIDEO_MBI_STATISTICS * pParam =
+ (OMX_QOMX_VIDEO_MBI_STATISTICS *)paramData;
+
+ DEBUG_PRINT_LOW("set MBI Dump mode: %d", pParam->eMBIStatisticsType);
+ if(venc_set_mbi_statistics_mode(pParam->eMBIStatisticsType) == false) {
+ DEBUG_PRINT_ERROR("ERROR: set MBI Statistics mode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ break;
+ }
+
+ case OMX_QcomIndexConfigH264EntropyCodingCabac:
+ {
+ QOMX_VIDEO_H264ENTROPYCODINGTYPE * pParam =
+ (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)paramData;
+
+ DEBUG_PRINT_LOW("set Entropy info : %d", pParam->bCabac);
+ if(venc_set_entropy_config (pParam->bCabac, 0) == false) {
+ DEBUG_PRINT_ERROR("ERROR: set Entropy failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ break;
+ }
+
+ case OMX_QcomIndexHierarchicalStructure:
+ {
+ QOMX_VIDEO_HIERARCHICALLAYERS* pParam =
+ (QOMX_VIDEO_HIERARCHICALLAYERS*)paramData;
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ if (!venc_set_hier_layers(pParam->eHierarchicalCodingType, pParam->nNumLayers)) {
+ DEBUG_PRINT_ERROR("Setting Hier P count failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("OMX_QcomIndexHierarchicalStructure called on wrong port(%d)", (int)pParam->nPortIndex);
+ return false;
+ }
+
+ // For VP8, hier-p and ltr are mutually exclusive features in firmware
+ // Disable ltr if hier-p is enabled.
+ if (m_codec == OMX_VIDEO_CodingVP8) {
+ DEBUG_PRINT_LOW("Disable LTR as HIER-P is being set");
+ if(!venc_set_ltrmode(0, 0)) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to disable ltrmode");
+ }
+ }
+ break;
+ }
+ case OMX_QcomIndexParamPerfLevel:
+ {
+ OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *pParam =
+ (OMX_QCOM_VIDEO_PARAM_PERF_LEVEL *)paramData;
+ DEBUG_PRINT_LOW("Set perf level: %d", pParam->ePerfLevel);
+ if (!venc_set_perf_level(pParam->ePerfLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", pParam->ePerfLevel);
+ return false;
+ } else {
+ performance_level.perflevel = (unsigned int) pParam->ePerfLevel;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamH264VUITimingInfo:
+ {
+ OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *pParam =
+ (OMX_QCOM_VIDEO_PARAM_VUI_TIMING_INFO *)paramData;
+ DEBUG_PRINT_LOW("Set VUI timing info: %d", pParam->bEnable);
+ if(venc_set_vui_timing_info(pParam->bEnable) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set vui timing info to %d", pParam->bEnable);
+ return false;
+ } else {
+ vui_timing_info.enabled = (unsigned int) pParam->bEnable;
+ }
+ break;
+ }
+ case OMX_QTIIndexParamVQZIPSEIType:
+ {
+ OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE*pParam =
+ (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
+ DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
+ if(venc_set_vqzip_sei_type(pParam->bEnable) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set VQZIP SEI type %d", pParam->bEnable);
+ return false;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamPeakBitrate:
+ {
+ OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *pParam =
+ (OMX_QCOM_VIDEO_PARAM_PEAK_BITRATE *)paramData;
+ DEBUG_PRINT_LOW("Set peak bitrate: %u", (unsigned int)pParam->nPeakBitrate);
+ if(venc_set_peak_bitrate(pParam->nPeakBitrate) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set peak bitrate to %u", (unsigned int)pParam->nPeakBitrate);
+ return false;
+ } else {
+ peak_bitrate.peakbitrate = (unsigned int) pParam->nPeakBitrate;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamSetMVSearchrange:
+ {
+ DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexParamSetMVSearchrange");
+ is_searchrange_set = true;
+ if (!venc_set_searchrange()) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set search range");
+ return false;
+ }
+ }
+ break;
+ case OMX_QcomIndexParamVideoLTRCount:
+ {
+ DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
+ OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
+ (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
+ if (pParam->nCount > 0) {
+ if (venc_set_ltrmode(1, pParam->nCount) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
+ return false;
+ }
+ } else {
+ if (venc_set_ltrmode(0, 0) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
+ return false;
+ }
+ }
+ break;
+ }
+ case OMX_QcomIndexParamVideoHybridHierpMode:
+ {
+ if (!venc_set_hybrid_hierp((QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData)) {
+ DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
+ return false;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamBatchSize:
+ {
+ OMX_PARAM_U32TYPE* pParam =
+ (OMX_PARAM_U32TYPE*)paramData;
+
+ if (pParam->nPortIndex == PORT_INDEX_OUT) {
+ DEBUG_PRINT_ERROR("For the moment, client-driven batching not supported"
+ " on output port");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ if (!venc_set_batch_size(pParam->nU32)) {
+ DEBUG_PRINT_ERROR("Failed setting batch size as %d", pParam->nU32);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QcomIndexParamVencAspectRatio:
+ {
+ if (!venc_set_aspectratio(paramData)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexParamVencAspectRatio failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QTIIndexParamLowLatencyMode:
+ {
+ QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE* pParam =
+ (QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE*)paramData;
+ if (!venc_set_low_latency(pParam->bLowLatencyMode)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamLowLatencyMode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_QTIIndexParamVideoEnableRoiInfo:
+ {
+ struct v4l2_control control;
+ if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
+ m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
+ DEBUG_PRINT_ERROR("OMX_QTIIndexParamVideoEnableRoiInfo is not supported for %lu codec", m_sVenc_cfg.codectype);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_ROI_QP;
+ DEBUG_PRINT_LOW("Setting param OMX_QTIIndexParamVideoEnableRoiInfo");
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("ERROR: Setting OMX_QTIIndexParamVideoEnableRoiInfo failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+#ifdef _PQ_
+ m_pq.pConfig.a_qp.roi_enabled = (OMX_U32)true;
+ m_pq.configure();
+#endif // _PQ_
+ break;
+ }
+ case OMX_QcomIndexConfigVideoVencLowLatencyMode:
+ {
+ QOMX_ENABLETYPE *pParam = (QOMX_ENABLETYPE*)paramData;
+
+ if (!venc_set_lowlatency_mode(pParam->bEnable)) {
+ DEBUG_PRINT_ERROR("Setting low latency mode failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ if (venc_set_temporal_layers(
+ (OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE*)paramData) != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("set_param: Failed to configure temporal layers");
+ return false;
+ }
+ break;
+ }
+ case OMX_IndexParamVideoSliceFMO:
+ default:
+ DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
+ index);
+ break;
+ //case
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_check_valid_config()
+{
+ if (streaming[OUTPUT_PORT] && streaming[CAPTURE_PORT] &&
+ ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 && hier_layers.hier_mode == HIER_P_HYBRID) ||
+ (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC && hier_layers.hier_mode == HIER_P))) {
+ DEBUG_PRINT_ERROR("venc_set_config not allowed run time for following usecases");
+ DEBUG_PRINT_ERROR("For H264 : When Hybrid Hier P enabled");
+ DEBUG_PRINT_ERROR("For H265 : When Hier P enabled");
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_config(void *configData, OMX_INDEXTYPE index)
+{
+
+ DEBUG_PRINT_LOW("Inside venc_set_config");
+
+ if(!venc_check_valid_config()) {
+ DEBUG_PRINT_ERROR("venc_set_config not allowed for this configuration");
+ return false;
+ }
+
+ switch ((int)index) {
+ case OMX_IndexConfigVideoBitrate:
+ {
+ OMX_VIDEO_CONFIG_BITRATETYPE *bit_rate = (OMX_VIDEO_CONFIG_BITRATETYPE *)
+ configData;
+ DEBUG_PRINT_LOW("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("ERROR: Setting Target Bit rate failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoBitrate");
+ }
+
+ break;
+ }
+ case OMX_IndexConfigVideoFramerate:
+ {
+ OMX_CONFIG_FRAMERATETYPE *frame_rate = (OMX_CONFIG_FRAMERATETYPE *)
+ configData;
+ DEBUG_PRINT_LOW("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("ERROR: Setting Encode Framerate failed");
+ return false;
+ }
+#ifdef _PQ_
+ venc_try_enable_pq();
+#endif // _PQ_
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+
+ break;
+ }
+ case QOMX_IndexConfigVideoIntraperiod:
+ {
+ DEBUG_PRINT_LOW("venc_set_param:QOMX_IndexConfigVideoIntraperiod");
+ 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("ERROR: 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("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("ERROR: Setting Encode Framerate failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoFramerate");
+ }
+
+ break;
+ }
+ case OMX_IndexConfigCommonRotate:
+ {
+ OMX_CONFIG_ROTATIONTYPE *config_rotation =
+ reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
+ OMX_U32 nFrameWidth;
+ if (!config_rotation) {
+ return false;
+ }
+ if (true == deinterlace_enabled) {
+ DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
+ return false;
+ }
+ if (config_rotation->nRotation == 90 || config_rotation->nRotation == 270) {
+ DEBUG_PRINT_HIGH("venc_set_config: updating the new Dims");
+ nFrameWidth = m_sVenc_cfg.dvs_width;
+ m_sVenc_cfg.dvs_width = m_sVenc_cfg.dvs_height;
+ m_sVenc_cfg.dvs_height = nFrameWidth;
+ }
+ if(venc_set_vpe_rotation(config_rotation->nRotation) == false) {
+ DEBUG_PRINT_ERROR("ERROR: 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;
+ }
+ case OMX_IndexConfigCommonDeinterlace:
+ {
+ OMX_VIDEO_CONFIG_DEINTERLACE *deinterlace = (OMX_VIDEO_CONFIG_DEINTERLACE *) configData;
+ DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigCommonDeinterlace");
+ if(deinterlace->nPortIndex == (OMX_U32)PORT_INDEX_OUT) {
+ if (m_sVenc_cfg.dvs_width == m_sVenc_cfg.input_height &&
+ m_sVenc_cfg.dvs_height == m_sVenc_cfg.input_width)
+ {
+ DEBUG_PRINT_ERROR("ERROR: Deinterlace not supported with rotation");
+ return false;
+ }
+ if(venc_set_deinterlace(deinterlace->nEnable) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting Deinterlace failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigCommonDeinterlace");
+ }
+ break;
+ }
+ case OMX_IndexConfigVideoVp8ReferenceFrame:
+ {
+ OMX_VIDEO_VP8REFERENCEFRAMETYPE* vp8refframe = (OMX_VIDEO_VP8REFERENCEFRAMETYPE*) configData;
+ DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
+ if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
+ (vp8refframe->bUseGoldenFrame)) {
+ if(venc_set_useltr(0x1) == false) {
+ DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
+ return false;
+ }
+ } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
+ (vp8refframe->bGoldenFrameRefresh)) {
+ if(venc_set_markltr(0x1) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoVp8ReferenceFrame");
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigVideoLTRUse:
+ {
+ OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
+ DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
+ if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
+ if (venc_set_useltr(pParam->nID) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigVideoLTRMark:
+ {
+ OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
+ DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
+ if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
+ if (venc_set_markltr(pParam->nID) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigPerfLevel:
+ {
+ OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
+ (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
+ DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
+ if (!venc_set_perf_level(perf->ePerfLevel)) {
+ DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
+ return false;
+ } else {
+ performance_level.perflevel = (unsigned int) perf->ePerfLevel;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigVideoVencPerfMode:
+ {
+ QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
+ DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
+ if (venc_set_perf_mode(pParam->nPerfMode) == false) {
+ DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
+ return false;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigNumHierPLayers:
+ {
+ QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *pParam =
+ (QOMX_EXTNINDEX_VIDEO_HIER_P_LAYERS *) configData;
+ DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigNumHierPLayers");
+ if (venc_set_hierp_layers(pParam->nNumHierLayers) == false) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigNumHierPLayers");
+ return false;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigBaseLayerId:
+ {
+ OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam =
+ (OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*) configData;
+ if (venc_set_baselayerid(pParam->nPID) == false) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigBaseLayerId failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_IndexParamAndroidVideoTemporalLayering:
+ {
+ DEBUG_PRINT_ERROR("TemporalLayer: Changing layer-configuration dynamically is not supported!");
+ return false;
+ }
+ case OMX_QcomIndexConfigQp:
+ {
+ OMX_SKYPE_VIDEO_CONFIG_QP* pParam =
+ (OMX_SKYPE_VIDEO_CONFIG_QP*) configData;
+ if (venc_set_qp(pParam->nQP) == false) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigQp failed");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ break;
+ }
+ case OMX_IndexConfigPriority:
+ {
+ OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
+ DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
+ if (!venc_set_priority(priority->nU32)) {
+ DEBUG_PRINT_ERROR("Failed to set priority");
+ return false;
+ }
+ break;
+ }
+ case OMX_IndexConfigOperatingRate:
+ {
+ OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
+ DEBUG_PRINT_LOW("Set_config: operating rate %d", rate->nU32);
+ if (!venc_set_operatingrate(rate->nU32)) {
+ DEBUG_PRINT_ERROR("Failed to set operating rate");
+ return false;
+ }
+ break;
+ }
+#ifdef SUPPORT_CONFIG_INTRA_REFRESH
+ case OMX_IndexConfigAndroidIntraRefresh:
+ {
+ OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *intra_refresh = (OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE *)configData;
+ DEBUG_PRINT_LOW("OMX_IndexConfigAndroidIntraRefresh : num frames = %d", intra_refresh->nRefreshPeriod);
+
+ if (intra_refresh->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+ OMX_U32 mb_size = m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC ? 32 : 16;
+ OMX_U32 num_mbs_per_frame = (ALIGN(m_sVenc_cfg.dvs_height, mb_size)/mb_size) * (ALIGN(m_sVenc_cfg.dvs_width, mb_size)/mb_size);
+ OMX_U32 num_intra_refresh_mbs = ceil(num_mbs_per_frame / intra_refresh->nRefreshPeriod);
+
+ if (venc_set_intra_refresh(OMX_VIDEO_IntraRefreshRandom, num_intra_refresh_mbs) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting Intra refresh failed");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_IndexConfigVideoIntraRefreshType");
+ }
+ break;
+ }
+#endif
+ case OMX_QTIIndexConfigVideoBlurResolution:
+ {
+ OMX_QTI_VIDEO_CONFIG_BLURINFO *blur = (OMX_QTI_VIDEO_CONFIG_BLURINFO *)configData;
+ if (blur->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
+ DEBUG_PRINT_LOW("Set_config: blur resolution: %d", blur->eTargetResol);
+ if(!venc_set_blur_resolution(blur)) {
+ DEBUG_PRINT_ERROR("Failed to set Blur Resolution");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QTIIndexConfigVideoBlurResolution");
+ return false;
+ }
+ break;
+ }
+ case OMX_QcomIndexConfigH264Transform8x8:
+ {
+ OMX_CONFIG_BOOLEANTYPE *pEnable = (OMX_CONFIG_BOOLEANTYPE *) configData;
+ DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigH264Transform8x8");
+ if (venc_h264_transform_8x8(pEnable->bEnabled) == false) {
+ DEBUG_PRINT_ERROR("Failed to set OMX_QcomIndexConfigH264Transform8x8");
+ return false;
+ }
+ break;
+ }
+ case OMX_QTIIndexConfigDescribeColorAspects:
+ {
+ DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
+
+ OMX_U32 color_space = MSM_VIDC_BT601_6_625;
+ OMX_U32 full_range = 0;
+ OMX_U32 matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
+ OMX_U32 transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
+
+ switch((ColorAspects::Primaries)(params->sAspects.mPrimaries)) {
+ case ColorAspects::PrimariesBT709_5:
+ color_space = MSM_VIDC_BT709_5;
+ break;
+ case ColorAspects::PrimariesBT470_6M:
+ color_space = MSM_VIDC_BT470_6_M;
+ break;
+ case ColorAspects::PrimariesBT601_6_625:
+ color_space = MSM_VIDC_BT601_6_625;
+ break;
+ case ColorAspects::PrimariesBT601_6_525:
+ color_space = MSM_VIDC_BT601_6_525;
+ break;
+ case ColorAspects::PrimariesGenericFilm:
+ color_space = MSM_VIDC_GENERIC_FILM;
+ break;
+ case ColorAspects::PrimariesBT2020:
+ color_space = MSM_VIDC_BT2020;
+ break;
+ default:
+ color_space = MSM_VIDC_BT601_6_625;
+ //params->sAspects.mPrimaries = ColorAspects::PrimariesBT601_6_625;
+ break;
+ }
+ switch((ColorAspects::Range)params->sAspects.mRange) {
+ case ColorAspects::RangeFull:
+ full_range = 1;
+ break;
+ case ColorAspects::RangeLimited:
+ full_range = 0;
+ break;
+ default:
+ break;
+ }
+ switch((ColorAspects::Transfer)params->sAspects.mTransfer) {
+ case ColorAspects::TransferSMPTE170M:
+ transfer_chars = MSM_VIDC_TRANSFER_601_6_525;
+ break;
+ case ColorAspects::TransferUnspecified:
+ transfer_chars = MSM_VIDC_TRANSFER_UNSPECIFIED;
+ break;
+ case ColorAspects::TransferGamma22:
+ transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_M;
+ break;
+ case ColorAspects::TransferGamma28:
+ transfer_chars = MSM_VIDC_TRANSFER_BT_470_6_BG;
+ break;
+ case ColorAspects::TransferSMPTE240M:
+ transfer_chars = MSM_VIDC_TRANSFER_SMPTE_240M;
+ break;
+ case ColorAspects::TransferLinear:
+ transfer_chars = MSM_VIDC_TRANSFER_LINEAR;
+ break;
+ case ColorAspects::TransferXvYCC:
+ transfer_chars = MSM_VIDC_TRANSFER_IEC_61966;
+ break;
+ case ColorAspects::TransferBT1361:
+ transfer_chars = MSM_VIDC_TRANSFER_BT_1361;
+ break;
+ case ColorAspects::TransferSRGB:
+ transfer_chars = MSM_VIDC_TRANSFER_SRGB;
+ break;
+ default:
+ //params->sAspects.mTransfer = ColorAspects::TransferSMPTE170M;
+ transfer_chars = MSM_VIDC_TRANSFER_601_6_625;
+ break;
+ }
+ switch((ColorAspects::MatrixCoeffs)params->sAspects.mMatrixCoeffs) {
+ case ColorAspects::MatrixUnspecified:
+ matrix_coeffs = MSM_VIDC_MATRIX_UNSPECIFIED;
+ break;
+ case ColorAspects::MatrixBT709_5:
+ matrix_coeffs = MSM_VIDC_MATRIX_BT_709_5;
+ break;
+ case ColorAspects::MatrixBT470_6M:
+ matrix_coeffs = MSM_VIDC_MATRIX_FCC_47;
+ break;
+ case ColorAspects::MatrixBT601_6:
+ matrix_coeffs = MSM_VIDC_MATRIX_601_6_525;
+ break;
+ case ColorAspects::MatrixSMPTE240M:
+ transfer_chars = MSM_VIDC_MATRIX_SMPTE_240M;
+ break;
+ case ColorAspects::MatrixBT2020:
+ matrix_coeffs = MSM_VIDC_MATRIX_BT_2020;
+ break;
+ case ColorAspects::MatrixBT2020Constant:
+ matrix_coeffs = MSM_VIDC_MATRIX_BT_2020_CONST;
+ break;
+ default:
+ //params->sAspects.mMatrixCoeffs = ColorAspects::MatrixBT601_6;
+ matrix_coeffs = MSM_VIDC_MATRIX_601_6_625;
+ break;
+ }
+ if (!venc_set_colorspace(color_space, full_range,
+ transfer_chars, matrix_coeffs)) {
+
+ DEBUG_PRINT_ERROR("Failed to set operating rate");
+ return false;
+ }
+ break;
+ }
+ case OMX_QTIIndexConfigVideoRoiInfo:
+ {
+ if(!venc_set_roi_qp_info((OMX_QTI_VIDEO_CONFIG_ROIINFO *)configData)) {
+ DEBUG_PRINT_ERROR("Failed to set ROI QP info");
+ return false;
+ }
+ break;
+ }
+ default:
+ DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
+ break;
+ }
+
+ return true;
+}
+
+unsigned venc_dev::venc_stop( void)
+{
+ struct venc_msg venc_msg;
+ struct v4l2_requestbuffers bufreq;
+ int rc = 0, ret = 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",
+ cap_type, rc);
+ } else
+ streaming[OUTPUT_PORT] = false;
+
+ DEBUG_PRINT_LOW("Releasing registered buffers from driver on o/p port");
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = 0;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
+
+ if (ret) {
+ DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS OUTPUT MPLANE Failed");
+ return 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",
+ cap_type, rc);
+ } else
+ streaming[CAPTURE_PORT] = false;
+
+ DEBUG_PRINT_LOW("Releasing registered buffers from driver on capture port");
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = 0;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ ret = ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq);
+
+ if (ret) {
+ DEBUG_PRINT_ERROR("ERROR: VIDIOC_REQBUFS CAPTURE MPLANE Failed");
+ return false;
+ }
+ }
+
+ if (!rc && !ret) {
+ venc_stop_done();
+ stopped = 1;
+ /*set flag to re-configure when started again*/
+ resume_in_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;
+}
+
+bool venc_dev::venc_set_vqzip_defaults()
+{
+ struct v4l2_control control;
+ int rc = 0, num_mbs_per_frame;
+
+ num_mbs_per_frame = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width;
+
+ switch (num_mbs_per_frame) {
+ case OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT:
+ case OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT:
+ case OMX_CORE_4KUHD_WIDTH * OMX_CORE_4KUHD_HEIGHT:
+ case OMX_CORE_4KDCI_WIDTH * OMX_CORE_4KDCI_HEIGHT:
+ break;
+ default:
+ DEBUG_PRINT_ERROR("VQZIP is not supported for this resoultion : %lu X %lu",
+ m_sVenc_cfg.input_width, m_sVenc_cfg.input_height);
+ return false;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL;
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc)
+ DEBUG_PRINT_ERROR("Failed to set Rate Control OFF for VQZIP");
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
+ control.value = INT_MAX;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc)
+ DEBUG_PRINT_ERROR("Failed to set P frame period for VQZIP");
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
+ control.value = 0;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc)
+ DEBUG_PRINT_ERROR("Failed to set B frame period for VQZIP");
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
+ control.value = V4L2_MPEG_VIDC_VIDEO_PERF_MAX_QUALITY;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc)
+ DEBUG_PRINT_ERROR("Failed to set Max quality for VQZIP");
+
+ 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 IDR period for VQZIP");
+
+ return true;
+}
+
+unsigned venc_dev::venc_start(void)
+{
+ enum v4l2_buf_type buf_type;
+ int ret, r;
+ struct v4l2_control control;
+
+ memset(&control, 0, sizeof(control));
+
+ DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
+ __func__);
+ m_level_set = false;
+
+ if (!venc_set_profile_level(0, 0)) {
+ DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
+ __func__);
+ } else {
+ DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
+ __func__, codec_profile.profile, profile_level.level);
+ }
+
+#ifdef _PQ_
+ /*
+ * Make sure that PQ is still applicable for given configuration.
+ * This call mainly disables PQ if current encoder configuration
+ * doesn't support PQ. PQ cann't enabled here as buffer allocation
+ * is already done by this time.
+ */
+ venc_try_enable_pq();
+#endif // _PQ_
+
+ if (vqzip_sei_info.enabled && !venc_set_vqzip_defaults())
+ return 1;
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264)
+ venc_set_low_latency((OMX_BOOL)!intra_period.num_bframes);
+
+ // re-configure the temporal layers as RC-mode and key-frame interval
+ // might have changed since the client last configured the layers.
+ if (temporal_layers_config.nPLayers) {
+ if (venc_set_temporal_layers_internal() != OMX_ErrorNone) {
+ DEBUG_PRINT_ERROR("Re-configuring temporal layers failed !");
+ } else {
+ // request buffers on capture port again since internal (scratch)-
+ // buffer requirements may change (i.e if we switch from non-hybrid
+ // to hybrid mode and vice-versa)
+ struct v4l2_requestbuffers bufreq;
+
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = m_sOutput_buff_property.actualcount;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ if (ioctl(m_nDriver_fd, VIDIOC_REQBUFS, &bufreq)) {
+ DEBUG_PRINT_ERROR("Request bufs failed while reconfiguring layers");
+ }
+ }
+ }
+
+ venc_config_print();
+
+ if(resume_in_stopped){
+ /*set buffercount when restarted*/
+ venc_reconfig_reqbufs();
+ resume_in_stopped = 0;
+ }
+
+ /* 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.dvs_width * m_sVenc_cfg.dvs_height)/(256 * multislice.mslice_size) >= MAX_SUPPORTED_SLICES_PER_FRAME) {
+ DEBUG_PRINT_ERROR("slice_mode: %lu, max slices (%lu) should be less than (%d)", slice_mode.enable,
+ (m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_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");
+ ret=ioctl(m_nDriver_fd, VIDIOC_STREAMON,&buf_type);
+
+ if (ret)
+ return 1;
+
+ streaming[CAPTURE_PORT] = true;
+
+ /*
+ * Workaround for Skype usecase. Skpye doesn't like SPS\PPS come as
+ seperate buffer. It wants SPS\PPS with IDR frame FTB.
+ */
+
+ if (!venc_handle->m_slowLatencyMode.bLowLatencyMode) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_REQUEST_SEQ_HEADER;
+ control.value = 1;
+ ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (ret) {
+ DEBUG_PRINT_ERROR("failed to request seq header");
+ return 1;
+ }
+ }
+
+ /* This is intentionally done after SEQ_HEADER check. Because
+ * PIC_ORDER_CNT is tightly coupled with lowlatency. Low latency
+ * flag is also overloaded not to send SPS in separate buffer.
+ * Hence lowlatency setting is done after SEQ_HEADER check.
+ * Don't change this sequence unless you know what you are doing.
+ */
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264)
+ venc_set_low_latency((OMX_BOOL)!intra_period.num_bframes);
+
+ stopped = 0;
+ return 0;
+}
+
+inline const char* hiermode_string(int val)
+{
+ switch(val)
+ {
+ case HIER_NONE:
+ return "No Hier";
+ case HIER_P:
+ return "Hier-P";
+ case HIER_B:
+ return "Hier-B";
+ case HIER_P_HYBRID:
+ return "Hybrid Hier-P";
+ default:
+ return "No hier";
+ }
+}
+
+inline const char* bitrate_type_string(int val)
+{
+ switch(val)
+ {
+ case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_DISABLE:
+ return "CUMULATIVE";
+ case V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE:
+ return "LAYER WISE";
+ default:
+ return "Unknown Bitrate Type";
+ }
+}
+
+static const char *codec_as_string(unsigned long codec) {
+ switch (codec) {
+ case V4L2_PIX_FMT_H264:
+ return "H264";
+ case V4L2_PIX_FMT_MPEG4:
+ return "MPEG4";
+ case V4L2_PIX_FMT_H263:
+ return "H263";
+ case V4L2_PIX_FMT_HEVC:
+ return "HEVC";
+ case V4L2_PIX_FMT_VP8:
+ return "VP8";
+ default:
+ return "UNKOWN";
+ }
+}
+
+void venc_dev::venc_config_print()
+{
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Codec: %s, Profile %ld, level : %ld",
+ codec_as_string(m_sVenc_cfg.codectype), codec_profile.profile, profile_level.level);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Input 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("ENC_CONFIG: Output Width: %ld, Height:%ld, Fps: %ld",
+ m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
+ m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Color Space: Primaries = %u, Range = %u, Transfer Chars = %u, Matrix Coeffs = %u",
+ color_space.primaries, color_space.range, color_space.transfer_chars, color_space.matrix_coeffs);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
+ bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
+ session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
+ init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
+ session_qp_values.minqp, session_qp_values.maxqp);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: VOP_Resolution: %ld, Slice-Mode: %ld, Slize_Size: %ld",
+ voptimecfg.voptime_resolution, multislice.mslice_mode,
+ multislice.mslice_size);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: EntropyMode: %d, CabacModel: %ld",
+ entropy.longentropysel, entropy.cabacmodel);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: DB-Mode: %ld, alpha: %ld, Beta: %ld",
+ dbkfilter.db_mode, dbkfilter.slicealpha_offset,
+ dbkfilter.slicebeta_offset);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
+ intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
+ ltrinfo.enabled, ltrinfo.count);
+
+ if (temporal_layers_config.nPLayers) {
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: P-layers: %u, B-layers: %u, Adjusted I-frame-interval: %lu",
+ temporal_layers_config.nPLayers, temporal_layers_config.nBLayers,
+ intra_period.num_pframes + intra_period.num_bframes + 1);
+
+ for (OMX_U32 l = 0; temporal_layers_config.bIsBitrateRatioValid
+ && (l < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers); ++l) {
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Temporal layers: layer[%d] bitrate %% = %u%%",
+ l, temporal_layers_config.nTemporalLayerBitrateFraction[l]);
+ }
+ } else {
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
+ hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layers: %d, Frame Interval : %d, MinQP: %d, Max_QP: %d",
+ hybrid_hp.nHpLayers, hybrid_hp.nKeyFrameInterval, hybrid_hp.nMinQuantizer, hybrid_hp.nMaxQuantizer);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Hybrid_HP PARAMS: Layer0: %d, Layer1: %d, Later2: %d, Layer3: %d, Layer4: %d, Layer5: %d",
+ hybrid_hp.nTemporalLayerBitrateRatio[0], hybrid_hp.nTemporalLayerBitrateRatio[1],
+ hybrid_hp.nTemporalLayerBitrateRatio[2], hybrid_hp.nTemporalLayerBitrateRatio[3],
+ hybrid_hp.nTemporalLayerBitrateRatio[4], hybrid_hp.nTemporalLayerBitrateRatio[5]);
+ }
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: VUI timing info enabled: %d", vui_timing_info.enabled);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Peak bitrate: %d", peak_bitrate.peakbitrate);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Session Priority: %u", sess_priority.priority);
+
+#ifdef _PQ_
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Adaptive QP (PQ): %u", m_pq.is_pq_enabled);
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: ROI : %u", m_pq.pConfig.a_qp.roi_enabled);
+#endif // _PQ_
+
+ DEBUG_PRINT_HIGH("ENC_CONFIG: Operating Rate: %u", operating_rate);
+}
+
+bool venc_dev::venc_reconfig_reqbufs()
+{
+ struct v4l2_requestbuffers bufreq;
+
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = m_sInput_buff_property.actualcount;
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
+ DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed when resume");
+ return false;
+ }
+
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = m_sOutput_buff_property.actualcount;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq))
+ {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting o/p buffer count failed when resume");
+ return false;
+ }
+ return true;
+}
+
+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("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;
+ unsigned int extra_idx;
+ int extradata_index = 0;
+
+ pmem_tmp = (struct pmem *)buf_addr;
+ DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
+
+ if (port == PORT_INDEX_IN) {
+ extra_idx = EXTRADATA_IDX(num_input_planes);
+
+ if ((num_input_planes > 1) && (extra_idx)) {
+ rc = allocate_extradata(&input_extradata_info);
+
+ if (rc)
+ DEBUG_PRINT_ERROR("Failed to allocate extradata: %d\n", rc);
+ }
+ 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 = num_input_planes;
+
+if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ extradata_index = venc_get_index_from_fd(input_extradata_info.m_ion_dev, pmem_tmp->fd);
+ if (extradata_index < 0 ) {
+ DEBUG_PRINT_ERROR("Extradata index calculation went wrong for fd = %d", pmem_tmp->fd);
+ return OMX_ErrorBadParameter;
+ }
+ plane[extra_idx].length = input_extradata_info.buffer_size;
+ plane[extra_idx].m.userptr = (unsigned long) (input_extradata_info.uaddr + extradata_index * input_extradata_info.buffer_size);
+#ifdef USE_ION
+ plane[extra_idx].reserved[0] = input_extradata_info.ion.fd_ion_data.fd;
+#endif
+ plane[extra_idx].reserved[1] = input_extradata_info.buffer_size * extradata_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;
+ }
+
+
+ DEBUG_PRINT_LOW("Registering [%d] fd=%d size=%d userptr=%lu", index,
+ pmem_tmp->fd, plane[0].length, plane[0].m.userptr);
+ rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
+
+ if (rc)
+ DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
+ } else if (port == PORT_INDEX_OUT) {
+ extra_idx = EXTRADATA_IDX(num_output_planes);
+
+ if ((num_output_planes > 1) && (extra_idx)) {
+ rc = allocate_extradata(&output_extradata_info);
+
+ if (rc)
+ DEBUG_PRINT_ERROR("Failed to allocate extradata: %d", 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_output_planes;
+
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ plane[extra_idx].length = output_extradata_info.buffer_size;
+ plane[extra_idx].m.userptr = (unsigned long) (output_extradata_info.uaddr + index * output_extradata_info.buffer_size);
+#ifdef USE_ION
+ plane[extra_idx].reserved[0] = output_extradata_info.ion.fd_ion_data.fd;
+#endif
+ plane[extra_idx].reserved[1] = output_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", extra_idx);
+ return OMX_ErrorBadParameter;
+ }
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
+
+ if (rc)
+ DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: 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("venc_free_buf:pbuffer = %p,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("venc_free_buf:pbuffer = %p,fd = %x, offset = %d, maped_size = %d", \
+ dev_buffer.pbuffer, \
+ dev_buffer.fd, \
+ dev_buffer.offset, \
+ dev_buffer.maped_size);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: venc_free_buf:Invalid Port Index ");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_color_align(OMX_BUFFERHEADERTYPE *buffer,
+ OMX_U32 width, OMX_U32 height)
+{
+ OMX_U32 y_stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, width),
+ y_scanlines = VENUS_Y_SCANLINES(COLOR_FMT_NV12, height),
+ uv_stride = VENUS_UV_STRIDE(COLOR_FMT_NV12, width),
+ uv_scanlines = VENUS_UV_SCANLINES(COLOR_FMT_NV12, height),
+ src_chroma_offset = width * height;
+
+ if (buffer->nAllocLen >= VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height)) {
+ OMX_U8* src_buf = buffer->pBuffer, *dst_buf = buffer->pBuffer;
+ //Do chroma first, so that we can convert it in-place
+ src_buf += width * height;
+ dst_buf += y_stride * y_scanlines;
+ for (int line = height / 2 - 1; line >= 0; --line) {
+ memmove(dst_buf + line * uv_stride,
+ src_buf + line * width,
+ width);
+ }
+
+ dst_buf = src_buf = buffer->pBuffer;
+ //Copy the Y next
+ for (int line = height - 1; line > 0; --line) {
+ memmove(dst_buf + line * y_stride,
+ src_buf + line * width,
+ width);
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
+ Insufficient bufferLen=%u v/s Required=%u",
+ (unsigned int)(width*height), (unsigned int)src_chroma_offset, (unsigned int)buffer->nAllocLen,
+ VENUS_BUFFER_SIZE(COLOR_FMT_NV12, width, height));
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_get_performance_level(OMX_U32 *perflevel)
+{
+ if (!perflevel) {
+ DEBUG_PRINT_ERROR("Null pointer error");
+ return false;
+ } else {
+ *perflevel = performance_level.perflevel;
+ return true;
+ }
+}
+
+bool venc_dev::venc_get_vui_timing_info(OMX_U32 *enabled)
+{
+ if (!enabled) {
+ DEBUG_PRINT_ERROR("Null pointer error");
+ return false;
+ } else {
+ *enabled = vui_timing_info.enabled;
+ return true;
+ }
+}
+
+bool venc_dev::venc_get_vqzip_sei_info(OMX_U32 *enabled)
+{
+ if (!enabled) {
+ DEBUG_PRINT_ERROR("Null pointer error");
+ return false;
+ } else {
+ *enabled = vqzip_sei_info.enabled;
+ return true;
+ }
+}
+
+bool venc_dev::venc_get_peak_bitrate(OMX_U32 *peakbitrate)
+{
+ if (!peakbitrate) {
+ DEBUG_PRINT_ERROR("Null pointer error");
+ return false;
+ } else {
+ *peakbitrate = peak_bitrate.peakbitrate;
+ return true;
+ }
+}
+
+bool venc_dev::venc_get_batch_size(OMX_U32 *size)
+{
+ if (!size) {
+ DEBUG_PRINT_ERROR("Null pointer error");
+ return false;
+ } else {
+ *size = mBatchSize;
+ 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_requestbuffers bufreq;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ int rc = 0, extra_idx;
+ struct OMX_BUFFERHEADERTYPE *bufhdr;
+ LEGACY_CAM_METADATA_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("ERROR: venc_etb: buffer is NULL");
+ return false;
+ }
+
+ bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = m_sInput_buff_property.actualcount;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+ DEBUG_PRINT_LOW("Input buffer length %u, Timestamp = %lld", (unsigned int)bufhdr->nFilledLen, bufhdr->nTimeStamp);
+
+ if (pmem_data_buf) {
+ DEBUG_PRINT_LOW("\n Internal PMEM addr for i/p Heap UseBuf: %p", pmem_data_buf);
+ plane[0].m.userptr = (unsigned long)pmem_data_buf;
+ plane[0].data_offset = bufhdr->nOffset;
+ plane[0].length = bufhdr->nAllocLen;
+ plane[0].bytesused = bufhdr->nFilledLen;
+ } else {
+ // --------------------------------------------------------------------------------------
+ // [Usage] [metadatamode] [Type] [color_format] [Where is buffer info]
+ // ---------------------------------------------------------------------------------------
+ // Camera-2 1 CameraSource 0 meta-handle
+ // Camera-3 1 GrallocSource 0 gralloc-private-handle
+ // surface encode (RBG) 1 GrallocSource 1 bufhdr (color-converted)
+ // CPU (Eg: MediaCodec) 0 -- 0 bufhdr
+ // ---------------------------------------------------------------------------------------
+ if (metadatamode) {
+ plane[0].m.userptr = index;
+ meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
+
+ if (!meta_buf) {
+ //empty EOS buffer
+ if (!bufhdr->nFilledLen && (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)) {
+ plane[0].data_offset = bufhdr->nOffset;
+ plane[0].length = bufhdr->nAllocLen;
+ plane[0].bytesused = bufhdr->nFilledLen;
+ DEBUG_PRINT_LOW("venc_empty_buf: empty EOS buffer");
+ } else {
+ return false;
+ }
+ } else if (!color_format) {
+
+ if (meta_buf->buffer_type == LEGACY_CAM_SOURCE) {
+ native_handle_t *hnd = (native_handle_t*)meta_buf->meta_handle;
+ if (!hnd) {
+ DEBUG_PRINT_ERROR("ERROR: venc_etb: handle is NULL");
+ return false;
+ }
+
+ if (!streaming[OUTPUT_PORT] && !(m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGB32 ||
+ m_sVenc_cfg.inputformat == V4L2_PIX_FMT_RGBA8888_UBWC)) {
+ int usage = 0;
+ struct v4l2_format fmt;
+ OMX_COLOR_FORMATTYPE color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+
+ if (!mBatchSize && hnd->numFds + hnd->numInts > 5) {
+ color_format = (OMX_COLOR_FORMATTYPE)hnd->data[5];
+ } else if (mBatchSize) {
+ color_format = (OMX_COLOR_FORMATTYPE)BatchInfo::getColorFormatAt(hnd, 0);
+ }
+
+ if (!mBatchSize && hnd->numFds + hnd->numInts > 3) {
+ usage = hnd->data[3];
+ } else if (mBatchSize) {
+ usage = BatchInfo::getUsageAt(hnd, 0);
+ }
+
+ memset(&fmt, 0, sizeof(fmt));
+ if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709 ||
+ usage & private_handle_t::PRIV_FLAGS_ITU_R_601) {
+ DEBUG_PRINT_ERROR("Camera buffer color format is not 601_FR.");
+ DEBUG_PRINT_ERROR(" This leads to unknown color space");
+ }
+ if (usage & private_handle_t::PRIV_FLAGS_ITU_R_601_FR) {
+ if (is_csc_enabled) {
+ buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
+ venc_set_colorspace(MSM_VIDC_BT709_5, 1,
+ MSM_VIDC_TRANSFER_BT709_5, MSM_VIDC_MATRIX_BT_709_5);
+ } else {
+ venc_set_colorspace(MSM_VIDC_BT601_6_525, 1,
+ MSM_VIDC_TRANSFER_601_6_525, MSM_VIDC_MATRIX_601_6_525);
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+ }
+ }
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.input_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.input_width;
+ if (usage & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) {
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
+ }
+
+ if (usage & private_handle_t::PRIV_FLAGS_ITU_R_709) {
+ buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
+ }
+
+ if (!venc_set_color_format(color_format)) {
+ DEBUG_PRINT_ERROR("Failed setting color format in Camerasource %lx", m_sVenc_cfg.inputformat);
+ return false;
+ }
+
+ if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
+ DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
+ return false;
+ }
+ }
+
+ // Setting batch mode is sticky. We do not expect camera to change
+ // between batch and normal modes at runtime.
+ if (mBatchSize) {
+ if ((unsigned)hnd->numFds != mBatchSize) {
+ DEBUG_PRINT_ERROR("Don't support dynamic batch sizes (changed from %d->%d)",
+ mBatchSize, hnd->numFds);
+ return false;
+ }
+
+ return venc_empty_batch ((OMX_BUFFERHEADERTYPE*)buffer, index);
+ }
+
+ if (hnd->numFds + hnd->numInts > 2) {
+ plane[0].data_offset = hnd->data[1];
+ plane[0].length = hnd->data[2];
+ plane[0].bytesused = hnd->data[2];
+ }
+ DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x format 0x%lx",
+ fd, plane[0].bytesused, plane[0].length, buf.flags, m_sVenc_cfg.inputformat);
+ } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
+ VideoGrallocMetadata *meta_buf = (VideoGrallocMetadata *)bufhdr->pBuffer;
+ private_handle_t *handle = (private_handle_t *)meta_buf->pHandle;
+
+ if (!handle) {
+ DEBUG_PRINT_ERROR("%s : handle is null!", __FUNCTION__);
+ return false;
+ }
+
+ if (!streaming[OUTPUT_PORT]) {
+ int color_space = 0;
+ // Moment of truth... actual colorspace is known here..
+ ColorSpace_t colorSpace = ITU_R_601;
+ if (getMetaData(handle, GET_COLOR_SPACE, &colorSpace) == 0) {
+ DEBUG_PRINT_INFO("ENC_CONFIG: gralloc ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
+ colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+ }
+
+ struct v4l2_format fmt;
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+ bool isUBWC = (handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED) && is_gralloc_source_ubwc;
+ if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
+ m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_NV12_UBWC : V4L2_PIX_FMT_NV12;
+ DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 %s", isUBWC ? "UBWC" : "Linear");
+ } else if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
+ // In case of RGB, conversion to YUV is handled within encoder.
+ // Disregard the Colorspace in gralloc-handle in case of RGB and use
+ // [a] 601 for non-UBWC case : C2D output is (apparently) 601-LR
+ // [b] 601 for UBWC case : Venus can convert to 601-LR or FR. use LR for now.
+ colorSpace = ITU_R_601;
+ m_sVenc_cfg.inputformat = isUBWC ? V4L2_PIX_FMT_RGBA8888_UBWC : V4L2_PIX_FMT_RGB32;
+ DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = RGBA8888 %s", isUBWC ? "UBWC" : "Linear");
+ } else if (handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
+ DEBUG_PRINT_INFO("ENC_CONFIG: Input Color = NV12 Linear");
+ }
+
+ // If device recommendation (persist.vidc.enc.csc.enable) is to use 709, force CSC
+ if (colorSpace == ITU_R_601_FR && is_csc_enabled) {
+ struct v4l2_control control;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC;
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_VPE_CSC_ENABLE;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("venc_empty_buf: Failed to set VPE CSC for 601_to_709");
+ } else {
+ DEBUG_PRINT_INFO("venc_empty_buf: Will convert 601-FR to 709");
+ buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
+ colorSpace = ITU_R_709;
+ }
+ }
+
+ msm_vidc_h264_color_primaries_values primary;
+ msm_vidc_h264_transfer_chars_values transfer;
+ msm_vidc_h264_matrix_coeff_values matrix;
+ OMX_U32 range;
+
+ switch (colorSpace) {
+ case ITU_R_601_FR:
+ {
+ primary = MSM_VIDC_BT601_6_525;
+ range = 1; // full
+ transfer = MSM_VIDC_TRANSFER_601_6_525;
+ matrix = MSM_VIDC_MATRIX_601_6_525;
+
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+ break;
+ }
+ case ITU_R_709:
+ {
+ primary = MSM_VIDC_BT709_5;
+ range = 0; // limited
+ transfer = MSM_VIDC_TRANSFER_BT709_5;
+ matrix = MSM_VIDC_MATRIX_BT_709_5;
+
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_REC709;
+ break;
+ }
+ default:
+ {
+ // 601 or something else ? assume 601
+ primary = MSM_VIDC_BT601_6_625;
+ range = 0; //limited
+ transfer = MSM_VIDC_TRANSFER_601_6_625;
+ matrix = MSM_VIDC_MATRIX_601_6_625;
+
+ fmt.fmt.pix_mp.colorspace = V4L2_COLORSPACE_470_SYSTEM_BG;
+ break;
+ }
+ }
+ DEBUG_PRINT_INFO("ENC_CONFIG: selected ColorSpace = %d (601=%d 601_FR=%d 709=%d)",
+ colorSpace, ITU_R_601, ITU_R_601_FR, ITU_R_709);
+ venc_set_colorspace(primary, range, transfer, matrix);
+
+ 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 in Grallocsource %lx", m_sVenc_cfg.inputformat);
+ return false;
+ }
+ if(ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
+ DEBUG_PRINT_ERROR("VIDIOC_REQBUFS OUTPUT_MPLANE Failed");
+ return false;
+ }
+ }
+
+ fd = handle->fd;
+ plane[0].data_offset = 0;
+ plane[0].length = handle->size;
+ plane[0].bytesused = handle->size;
+ DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
+ ": filled %d of %d format 0x%lx", fd, plane[0].bytesused, plane[0].length, m_sVenc_cfg.inputformat);
+ }
+ } else {
+ plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
+ plane[0].data_offset = bufhdr->nOffset;
+ plane[0].length = bufhdr->nAllocLen;
+ plane[0].bytesused = bufhdr->nFilledLen;
+ DEBUG_PRINT_LOW("venc_empty_buf: Opaque non-camera buf: fd = %d filled %d of %d",
+ fd, plane[0].bytesused, plane[0].length);
+ }
+ } else {
+ plane[0].m.userptr = (unsigned long) bufhdr->pBuffer;
+ plane[0].data_offset = bufhdr->nOffset;
+ plane[0].length = bufhdr->nAllocLen;
+ plane[0].bytesused = bufhdr->nFilledLen;
+ DEBUG_PRINT_LOW("venc_empty_buf: non-camera buf: fd = %d filled %d of %d",
+ fd, plane[0].bytesused, plane[0].length);
+ }
+ }
+
+ extra_idx = EXTRADATA_IDX(num_input_planes);
+
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ int extradata_index = venc_get_index_from_fd(input_extradata_info.m_ion_dev,fd);
+ if (extradata_index < 0 ) {
+ DEBUG_PRINT_ERROR("Extradata index calculation went wrong for fd = %d", fd);
+ return OMX_ErrorBadParameter;
+ }
+
+ plane[extra_idx].bytesused = 0;
+ plane[extra_idx].length = input_extradata_info.buffer_size;
+ plane[extra_idx].m.userptr = (unsigned long) (input_extradata_info.uaddr + extradata_index * input_extradata_info.buffer_size);
+#ifdef USE_ION
+ plane[extra_idx].reserved[0] = input_extradata_info.ion.fd_ion_data.fd;
+#endif
+ plane[extra_idx].reserved[1] = input_extradata_info.buffer_size * extradata_index;
+ plane[extra_idx].reserved[2] = input_extradata_info.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 false;
+ }
+
+#ifdef _PQ_
+ if (!streaming[OUTPUT_PORT]) {
+ /*
+ * This is the place where all parameters for deciding
+ * PQ enablement are aailable. Evaluate PQ for the final time.
+ */
+ m_pq.is_YUV_format_uncertain = false;
+ m_pq.reinit(m_sVenc_cfg.inputformat);
+ venc_try_enable_pq();
+ }
+#endif // _PQ_
+
+ buf.index = index;
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ plane[0].reserved[0] = fd;
+ plane[0].reserved[1] = 0;
+ buf.m.planes = plane;
+ buf.length = num_input_planes;
+
+ handle_input_extradata(buf);
+
+ if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
+ buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
+
+ buf.timestamp.tv_sec = bufhdr->nTimeStamp / 1000000;
+ buf.timestamp.tv_usec = (bufhdr->nTimeStamp % 1000000);
+ if (m_debug.in_buffer_log) {
+ venc_input_log_buffers(bufhdr, fd, plane[0].data_offset, m_sVenc_cfg.inputformat);
+ }
+ if (m_debug.extradata_log && extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ DEBUG_PRINT_ERROR("Extradata Addr 0x%llx, Buffer Addr = 0x%x", (OMX_U64)input_extradata_info.uaddr, (unsigned int)plane[extra_idx].m.userptr);
+ venc_extradata_log_buffers((char *)plane[extra_idx].m.userptr);
+ }
+ 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");
+ if (errno == EBUSY) {
+ hw_overload = true;
+ }
+ return false;
+ } else {
+ streaming[OUTPUT_PORT] = true;
+ }
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_empty_batch(OMX_BUFFERHEADERTYPE *bufhdr, unsigned index)
+{
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ int rc = 0, extra_idx, numBufs;
+ struct v4l2_control control;
+ LEGACY_CAM_METADATA_TYPE * meta_buf = NULL;
+ native_handle_t *hnd = NULL;
+
+ if (bufhdr == NULL) {
+ DEBUG_PRINT_ERROR("ERROR: %s: buffer is NULL", __func__);
+ return false;
+ }
+
+ bool status = true;
+ if (metadatamode) {
+ plane[0].m.userptr = index;
+ meta_buf = (LEGACY_CAM_METADATA_TYPE *)bufhdr->pBuffer;
+
+ if (!color_format) {
+ if (meta_buf->buffer_type == LEGACY_CAM_SOURCE) {
+ hnd = (native_handle_t*)meta_buf->meta_handle;
+ if (!hnd) {
+ DEBUG_PRINT_ERROR("venc_empty_batch: invalid handle !");
+ return false;
+ } else if (hnd->numFds > kMaxBuffersInBatch) {
+ DEBUG_PRINT_ERROR("venc_empty_batch: Too many buffers (%d) in batch. "
+ "Max = %d", hnd->numFds, kMaxBuffersInBatch);
+ status = false;
+ }
+ DEBUG_PRINT_LOW("venc_empty_batch: Batch of %d bufs", hnd->numFds);
+ } else {
+ DEBUG_PRINT_ERROR("Batch supported for CameraSource buffers only !");
+ status = false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Batch supported for Camera buffers only !");
+ status = false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Batch supported for metabuffer mode only !");
+ status = false;
+ }
+
+ if (status) {
+ OMX_TICKS bufTimeStamp = 0ll;
+ int numBufs = hnd->numFds;
+ int v4l2Ids[kMaxBuffersInBatch] = {-1};
+ for (int i = 0; i < numBufs; ++i) {
+ v4l2Ids[i] = mBatchInfo.registerBuffer(index);
+ if (v4l2Ids[i] < 0) {
+ DEBUG_PRINT_ERROR("Failed to register buffer");
+ // TODO: cleanup the map and purge all slots of current index
+ status = false;
+ break;
+ }
+ }
+ for (int i = 0; i < numBufs; ++i) {
+ int v4l2Id = v4l2Ids[i];
+
+ memset(&buf, 0, sizeof(buf));
+ memset(&plane, 0, sizeof(plane));
+
+ DEBUG_PRINT_LOW("Batch: registering %d as %d", index, v4l2Id);
+ buf.index = (unsigned)v4l2Id;
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ plane[0].reserved[0] = BatchInfo::getFdAt(hnd, i);
+ plane[0].reserved[1] = 0;
+ plane[0].data_offset = BatchInfo::getOffsetAt(hnd, i);
+ plane[0].m.userptr = (unsigned long)meta_buf;
+ plane[0].length = plane[0].bytesused = BatchInfo::getSizeAt(hnd, i);
+ buf.m.planes = plane;
+ buf.length = num_input_planes;
+
+ extra_idx = EXTRADATA_IDX(num_input_planes);
+
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ int fd = plane[0].reserved[0];
+ int extradata_index = venc_get_index_from_fd(input_extradata_info.m_ion_dev, fd);
+ if (extradata_index < 0) {
+ DEBUG_PRINT_ERROR("Extradata index calculation went wrong for fd = %d", fd);
+ return OMX_ErrorBadParameter;
+ }
+
+ plane[extra_idx].bytesused = 0;
+ plane[extra_idx].length = input_extradata_info.buffer_size;
+ plane[extra_idx].m.userptr = (unsigned long) (input_extradata_info.uaddr + extradata_index * input_extradata_info.buffer_size);
+ plane[extra_idx].reserved[0] = input_extradata_info.ion.fd_ion_data.fd;
+ plane[extra_idx].reserved[1] = input_extradata_info.buffer_size * extradata_index;
+ plane[extra_idx].reserved[2] = input_extradata_info.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 false;
+ }
+
+#ifdef _PQ_
+ if (!streaming[OUTPUT_PORT]) {
+ m_pq.is_YUV_format_uncertain = false;
+ m_pq.reinit(m_sVenc_cfg.inputformat);
+ venc_try_enable_pq();
+ }
+#endif // _PQ_
+
+ handle_input_extradata(buf);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_PREPARE_BUF, &buf);
+ if (rc)
+ DEBUG_PRINT_LOW("VIDIOC_PREPARE_BUF Failed");
+
+ if (bufhdr->nFlags & OMX_BUFFERFLAG_EOS)
+ buf.flags |= V4L2_QCOM_BUF_FLAG_EOS;
+ if (i != numBufs - 1) {
+ buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
+ DEBUG_PRINT_LOW("for buffer %d (etb #%d) in batch of %d, marking as defer",
+ i, etb + 1, numBufs);
+ }
+
+ // timestamp differences from camera are in nano-seconds
+ bufTimeStamp = bufhdr->nTimeStamp + BatchInfo::getTimeStampAt(hnd, i) / 1000;
+
+ DEBUG_PRINT_LOW(" Q Batch [%d of %d] : buf=%p fd=%d len=%d TS=%lld",
+ i, numBufs, bufhdr, plane[0].reserved[0], plane[0].length, bufTimeStamp);
+ buf.timestamp.tv_sec = bufTimeStamp / 1000000;
+ buf.timestamp.tv_usec = (bufTimeStamp % 1000000);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_QBUF, &buf);
+ if (rc) {
+ DEBUG_PRINT_ERROR("%s: Failed to qbuf (etb) to driver", __func__);
+ return false;
+ }
+
+ etb++;
+ }
+ }
+
+ if (status && !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");
+ if (errno == EBUSY) {
+ hw_overload = true;
+ }
+ status = false;
+ } else {
+ streaming[OUTPUT_PORT] = true;
+ }
+ }
+
+ return status;
+}
+
+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;
+ unsigned int extra_idx;
+ struct OMX_BUFFERHEADERTYPE *bufhdr;
+
+ if (buffer == NULL)
+ return false;
+
+ bufhdr = (OMX_BUFFERHEADERTYPE *)buffer;
+
+ if (pmem_data_buf) {
+ DEBUG_PRINT_LOW("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("Shared PMEM addr for o/p PMEM UseBuf/AllocateBuf: %p", bufhdr->pBuffer);
+ plane[0].m.userptr = (unsigned long)bufhdr->pBuffer;
+ }
+
+ memset(&buf, 0, sizeof(buf));
+ memset(&plane, 0, sizeof(plane));
+
+ 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_output_planes;
+ buf.flags = 0;
+
+ if (venc_handle->is_secure_session()) {
+ output_metabuffer *meta_buf = (output_metabuffer *)(bufhdr->pBuffer);
+ native_handle_t *handle_t = meta_buf->nh;
+ plane[0].length = handle_t->data[3];
+ }
+
+ if (mBatchSize) {
+ // Should always mark first buffer as DEFER, since 0 % anything is 0, just offset by 1
+ // This results in the first batch being of size mBatchSize + 1, but thats good because
+ // we need an extra FTB for the codec specific data.
+
+ if (!ftb || ftb % mBatchSize) {
+ buf.flags |= V4L2_MSM_BUF_FLAG_DEFER;
+ DEBUG_PRINT_LOW("for ftb buffer %d marking as defer", ftb + 1);
+ }
+ }
+
+ extra_idx = EXTRADATA_IDX(num_output_planes);
+
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ plane[extra_idx].bytesused = 0;
+ plane[extra_idx].length = output_extradata_info.buffer_size;
+ plane[extra_idx].m.userptr = (unsigned long) (output_extradata_info.uaddr + index * output_extradata_info.buffer_size);
+#ifdef USE_ION
+ plane[extra_idx].reserved[0] = output_extradata_info.ion.fd_ion_data.fd;
+#endif
+ plane[extra_idx].reserved[1] = output_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", 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_inband_video_header(OMX_BOOL enable)
+{
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
+ if(enable) {
+ control.value = V4L2_MPEG_VIDEO_HEADER_MODE_JOINED_WITH_I_FRAME;
+ } else {
+ control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
+ }
+
+ DEBUG_PRINT_HIGH("Set inband sps/pps: %d", enable);
+ if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
+ DEBUG_PRINT_ERROR("Request for inband sps/pps failed");
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_au_delimiter(OMX_BOOL enable)
+{
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_AU_DELIMITER;
+ if(enable) {
+ control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_ENABLED;
+ } else {
+ control.value = V4L2_MPEG_VIDC_VIDEO_H264_AU_DELIMITER_DISABLED;
+ }
+
+ DEBUG_PRINT_HIGH("Set au delimiter: %d", enable);
+ if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
+ DEBUG_PRINT_ERROR("Request to set AU delimiter failed");
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_mbi_statistics_mode(OMX_U32 mode)
+{
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MBI_STATISTICS_MODE;
+ control.value = mode;
+
+ DEBUG_PRINT_HIGH("Set MBI dumping mode: %d", mode);
+ if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
+ DEBUG_PRINT_ERROR("Setting MBI mode failed");
+ return false;
+ }
+ return true;
+}
+
+int venc_dev::venc_get_index_from_fd(OMX_U32 ion_fd, OMX_U32 buffer_fd)
+{
+ unsigned int cookie = buffer_fd;
+ struct ion_fd_data fdData;
+
+ memset(&fdData, 0, sizeof(fdData));
+ fdData.fd = buffer_fd;
+ if (ion_fd && !ioctl(ion_fd, ION_IOC_IMPORT, &fdData)) {
+ cookie = fdData.handle;
+ }
+
+ for (unsigned int i = 0; i < (sizeof(fd_list)/sizeof(fd_list[0])); i++) {
+ if (fd_list[i] == cookie) {
+ DEBUG_PRINT_HIGH("FD is present at index = %d", i);
+ return i;
+ }
+ }
+ for (unsigned int i = 0; i < (sizeof(fd_list)/sizeof(fd_list[0])); i++)
+ if (fd_list[i] == 0) {
+ DEBUG_PRINT_HIGH("FD added at index = %d", i);
+ fd_list[i] = cookie;
+ return i;
+ }
+ return -EINVAL;
+}
+
+bool venc_dev::venc_set_vqzip_sei_type(OMX_BOOL enable)
+{
+ struct v4l2_control sei_control, yuvstats_control;
+
+ DEBUG_PRINT_HIGH("Set VQZIP SEI: %d", enable);
+ sei_control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
+ yuvstats_control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+
+ if (ioctl(m_nDriver_fd, VIDIOC_G_CTRL, &yuvstats_control) < 0) {
+ DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
+ }
+
+ if(enable) {
+ sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
+ yuvstats_control.value |= V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
+ } else {
+ sei_control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_DISABLE;
+ yuvstats_control.value &= ~V4L2_MPEG_VIDC_EXTRADATA_YUV_STATS;
+ }
+
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &sei_control) < 0) {
+ DEBUG_PRINT_HIGH("Non-Fatal: Request to set SEI failed");
+ }
+
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &yuvstats_control) < 0) {
+ DEBUG_PRINT_HIGH("Non-Fatal: Request to set YUVSTATS failed");
+ }
+#ifdef _VQZIP_
+ vqzip.pConfig.nWidth = ALIGN(m_sVenc_cfg.input_width, 16);
+ vqzip.pConfig.nHeight = ALIGN(m_sVenc_cfg.input_height, 16);
+ vqzip.init();
+ vqzip_sei_info.enabled = true;
+#endif
+
+ return true;
+}
+
+bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
+{
+ // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
+ if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
+ return false;
+
+ // Check for bframes with Hier-P-Hybrid
+ if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
+ return false;
+
+ // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
+ if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
+ hier_layers.hier_mode == HIER_B || ltrinfo.count))
+ return false;
+
+ // Check for LTR with Hier-P-Hybrid
+ if (count && hier_layers.hier_mode == HIER_P_HYBRID)
+ return false;
+
+ return true;
+}
+
+bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
+ OMX_U32 num_layers)
+{
+ struct v4l2_control control;
+
+ if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
+ DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
+ return false;
+ }
+
+ if (type == QOMX_HIERARCHICALCODING_P) {
+ // Reduce layer count by 1 before sending to driver. This avoids
+ // driver doing the same in multiple places.
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
+ control.value = num_layers - 1;
+ DEBUG_PRINT_HIGH("Set MAX Hier P num layers: %u", (unsigned int)num_layers);
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Request to set MAX Hier P num layers failed");
+ return false;
+ }
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
+ control.value = num_layers - 1;
+ DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
+ return false;
+ }
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ DEBUG_PRINT_LOW("Set H264_SVC_NAL");
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
+ return false;
+ }
+ }
+ hier_layers.hier_mode = HIER_P;
+ } else if (type == QOMX_HIERARCHICALCODING_B) {
+ if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
+ DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
+ return false;
+ }
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
+ control.value = num_layers - 1;
+ DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
+ return false;
+ }
+ hier_layers.hier_mode = HIER_B;
+ } else {
+ DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
+ return false;
+ }
+ hier_layers.numlayers = num_layers;
+ return true;
+}
+
+bool venc_dev::venc_set_extradata(OMX_U32 extra_data, OMX_BOOL enable)
+{
+ struct v4l2_control control;
+
+ DEBUG_PRINT_HIGH("venc_set_extradata:: %x", (int) extra_data);
+
+ if (enable == OMX_FALSE) {
+ /* No easy way to turn off extradata to the driver
+ * at the moment */
+ return false;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+ switch (extra_data) {
+ case OMX_ExtraDataVideoEncoderSliceInfo:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_MULTISLICE_INFO;
+ break;
+ case OMX_ExtraDataVideoEncoderMBInfo:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_METADATA_MBI;
+ break;
+ case OMX_ExtraDataFrameDimension:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_INPUT_CROP;
+ break;
+ case OMX_ExtraDataEncoderOverrideQPInfo:
+ control.value = V4L2_MPEG_VIDC_EXTRADATA_PQ_INFO;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("Unrecognized extradata index 0x%x", (unsigned int)extra_data);
+ return false;
+ }
+
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting extradata (%x) failed %d",
+ (unsigned int)extra_data, errno);
+ return false;
+ }
+
+ 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", control.id, control.value);
+ slice_mode.enable = 1;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Failed to set slice delivery mode, slice_mode [%lu] "
+ "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");
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp)
+{
+ int rc;
+ struct v4l2_control control;
+ struct v4l2_ext_control ctrl[4];
+ struct v4l2_ext_controls controls;
+
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_I_FRAME_QP;
+ ctrl[0].value = initqp->nQpI;
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_P_FRAME_QP;
+ ctrl[1].value = initqp->nQpP;
+ ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_B_FRAME_QP;
+ ctrl[2].value = initqp->nQpB;
+ ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_ENABLE_INITIAL_QP;
+ ctrl[3].value = initqp->bEnableInitQp;
+
+ controls.count = 4;
+ controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ controls.controls = ctrl;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
+ controls.controls[0].id, controls.controls[0].value,
+ controls.controls[1].id, controls.controls[1].value,
+ controls.controls[2].id, controls.controls[2].value,
+ controls.controls[3].id, controls.controls[3].value);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set session_qp %d", rc);
+ return false;
+ }
+
+ init_qp.iframeqp = initqp->nQpI;
+ init_qp.pframeqp = initqp->nQpP;
+ init_qp.bframeqp = initqp->nQpB;
+ init_qp.enableinitqp = initqp->bEnableInitQp;
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d, id=%x val=%d, id=%x val=%d",
+ controls.controls[0].id, controls.controls[0].value,
+ controls.controls[1].id, controls.controls[1].value,
+ controls.controls[2].id, controls.controls[2].value,
+ controls.controls[3].id, controls.controls[3].value);
+ return true;
+}
+
+bool venc_dev::venc_set_colorspace(OMX_U32 primaries, OMX_U32 range,
+ OMX_U32 transfer_chars, OMX_U32 matrix_coeffs)
+{
+ int rc;
+ struct v4l2_control control;
+
+ DEBUG_PRINT_LOW("Setting color space : Primaries = %d, Range = %d, Trans = %d, Matrix = %d",
+ primaries, range, transfer_chars, matrix_coeffs);
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE;
+ control.value = primaries;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ color_space.primaries = control.value;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE;
+ control.value = range;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_FULL_RANGE");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ color_space.range = control.value;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS;
+ control.value = transfer_chars;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_TRANSFER_CHARS");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ color_space.transfer_chars = control.value;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS;
+ control.value = matrix_coeffs;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control : V4L2_CID_MPEG_VIDC_VIDEO_MATRIX_COEFFS");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ color_space.matrix_coeffs = control.value;
+
+ 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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ session_qp.pframeqp = 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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ session_qp.bframeqp = control.value;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_session_qp_range(OMX_U32 min_qp, OMX_U32 max_qp)
+{
+ int rc;
+ struct v4l2_control control;
+
+ if ((min_qp >= session_qp_range.minqp) && (max_qp <= session_qp_range.maxqp)) {
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MIN_QP;
+ else
+ control.id = V4L2_CID_MPEG_VIDEO_H264_MIN_QP;
+ control.value = min_qp;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP control id=%d, val=%d",
+ control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_MAX_QP;
+ else
+ control.id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
+ control.value = max_qp;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP control id=%d, val=%d",
+ control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
+ (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_session_qp_range_packed(OMX_U32 min_qp, OMX_U32 max_qp)
+{
+ int rc;
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDEO_MIN_QP_PACKED;
+ control.value = min_qp;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set MIN_QP_PACKED control id=%d, val=%d",
+ control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDEO_MAX_QP_PACKED;
+ control.value = max_qp;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set MAX_QP_PACKED control id=%d, val=%d",
+ control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ 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 = %u, Level = %u",
+ (unsigned int)eProfile, (unsigned int)eLevel);
+ mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
+ ((m_sVenc_cfg.dvs_width + 15) >> 4);
+
+ if ((eProfile == 0) && (eLevel == 0) && m_profile_set && m_level_set) {
+ DEBUG_PRINT_LOW("Profile/Level setting complete before venc_start");
+ return true;
+ }
+
+ DEBUG_PRINT_LOW("Validating Profile/Level from table");
+
+ if (!venc_validate_profile_level(&eProfile, &eLevel)) {
+ DEBUG_PRINT_LOW("ERROR: Profile/Level validation failed");
+ return false;
+ }
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
+ DEBUG_PRINT_LOW("eProfile = %u, OMX_VIDEO_MPEG4ProfileSimple = %d and "
+ "OMX_VIDEO_MPEG4ProfileAdvancedSimple = %d", (unsigned int)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("ERROR: Unsupported MPEG4 profile = %u",
+ (unsigned int)eProfile);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("eLevel = %u, OMX_VIDEO_MPEG4Level0 = %d, OMX_VIDEO_MPEG4Level1 = %d,"
+ "OMX_VIDEO_MPEG4Level2 = %d, OMX_VIDEO_MPEG4Level3 = %d, OMX_VIDEO_MPEG4Level4 = %d,"
+ "OMX_VIDEO_MPEG4Level5 = %d", (unsigned int)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("ERROR: Unsupported H.263 profile = %lu",
+ 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 == QOMX_VIDEO_AVCProfileConstrainedBaseline) {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
+ } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh) {
+ requested_profile.profile = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
+ } 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("ERROR: Unsupported H.264 profile = %lu",
+ 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;
+ case OMX_VIDEO_AVCLevel52:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
+ break;
+ case OMX_VIDEO_AVCLevelMax:
+ requested_level.level = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
+ break;
+ default :
+ DEBUG_PRINT_ERROR("ERROR: Unsupported H.264 level= %lu",
+ requested_level.level);
+ return false;
+ break;
+ }
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ if (!(eProfile == OMX_VIDEO_VP8ProfileMain)) {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 profile = %u",
+ (unsigned int)eProfile);
+ return false;
+ }
+ requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED;
+ m_profile_set = true;
+ switch(eLevel) {
+ case OMX_VIDEO_VP8Level_Version0:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
+ break;
+ case OMX_VIDEO_VP8Level_Version1:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("ERROR: Unsupported VP8 level= %u",
+ (unsigned int)eLevel);
+ return false;
+ break;
+ }
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ if (eProfile == OMX_VIDEO_HEVCProfileMain) {
+ requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
+ } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
+ requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
+ requested_profile.profile);
+ return false;
+ }
+
+ //profile level
+ switch (eLevel) {
+ case OMX_VIDEO_HEVCMainTierLevel1:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel1:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel2:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel2:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel21:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel21:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel3:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel3:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel31:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel31:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel4:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel4:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel41:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel41:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel5:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel5:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel51:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel51:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel52:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel52:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel6:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel6:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
+ break;
+ case OMX_VIDEO_HEVCMainTierLevel61:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
+ break;
+ case OMX_VIDEO_HEVCHighTierLevel61:
+ requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
+ break;
+ default :
+ DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
+ requested_level.level);
+ return false;
+ }
+ }
+
+ 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_HEVC) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
+ } else {
+ DEBUG_PRINT_ERROR("Wrong CODEC");
+ return false;
+ }
+
+ control.value = requested_profile.profile;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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 if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
+ } else {
+ DEBUG_PRINT_ERROR("Wrong CODEC");
+ return false;
+ }
+
+ control.value = requested_level.level;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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("venc_set_voptiming_cfg: TimeRes = %u",
+ (unsigned int)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("venc_set_intra_period: nPFrames = %u, nBFrames: %u", (unsigned int)nPFrames, (unsigned int)nBFrames);
+ int rc;
+ struct v4l2_control control;
+ int pframe = 0, bframe = 0;
+ char property_value[PROPERTY_VALUE_MAX] = {0};
+
+ 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_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
+ (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
+ (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
+ nBFrames=0;
+ }
+
+ if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0) && !is_thulium_v1) {
+ DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
+ return false;
+ }
+
+ intra_period.num_pframes = nPFrames;
+ intra_period.num_bframes = nBFrames;
+
+ if (!venc_calibrate_gop() && !is_thulium_v1)
+ {
+ DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
+ return false;
+ }
+
+ if (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >= 3840 * 2160 &&
+ (property_get("vidc.enc.disable_bframes", property_value, "0") && atoi(property_value))) {
+ intra_period.num_pframes = intra_period.num_pframes + intra_period.num_bframes;
+ intra_period.num_bframes = 0;
+ DEBUG_PRINT_LOW("Warning: Disabling B frames for UHD recording pFrames = %lu bFrames = %lu",
+ intra_period.num_pframes, intra_period.num_bframes);
+ }
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
+ control.value = intra_period.num_pframes;
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
+ control.value = intra_period.num_bframes;
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264 ||
+ m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ 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");
+ 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("venc_set_idr_period: nPFrames = %u, nIDRPeriod: %u",
+ (unsigned int)nPFrames, (unsigned int)nIDRPeriod);
+
+ if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
+ DEBUG_PRINT_ERROR("ERROR: IDR period valid for H264 only!!");
+ return false;
+ }
+
+ if (venc_set_intra_period (nPFrames, intra_period.num_bframes) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Request for setting intra period failed");
+ return false;
+ }
+
+ if (!intra_period.num_bframes)
+ 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");
+ 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("venc_set_entropy_config: CABAC = %u level: %u", enable, (unsigned int)i_cabac_level);
+
+ if (enable && (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) &&
+ (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+ entropy.cabacmodel=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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+ entropy.longentropysel=control.value;
+ } else {
+ DEBUG_PRINT_ERROR("Invalid 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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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;
+ control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_CIR_MBS;
+ control_mbs.value = 0;
+ // 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.dvs_width * m_sVenc_cfg.dvs_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.dvs_width * m_sVenc_cfg.dvs_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.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
+ control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
+ } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
+ (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
+ control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
+ control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
+ control_mbs.value = irMBs;
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
+ "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%u, val=%d", 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");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control_mode.id, control_mode.value);
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", 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");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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;
+ OMX_U32 resynchMarkerSpacingBytes = 0;
+ 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("RVLC is not Supported");
+ return false;
+ }
+
+ if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
+ (error_resilience->bEnableDataPartitioning)) {
+ DEBUG_PRINT_ERROR("DataPartioning are not Supported for MPEG4/H264");
+ return false;
+ }
+
+ if (error_resilience->nResynchMarkerSpacing) {
+ resynchMarkerSpacingBytes = error_resilience->nResynchMarkerSpacing;
+ resynchMarkerSpacingBytes = ALIGN(resynchMarkerSpacingBytes, 8) >> 3;
+ }
+ if (( m_sVenc_cfg.codectype != V4L2_PIX_FMT_H263) &&
+ (error_resilience->nResynchMarkerSpacing)) {
+ multislice_cfg.mslice_mode = VEN_MSLICE_CNT_BYTE;
+ multislice_cfg.mslice_size = resynchMarkerSpacingBytes;
+ 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 = resynchMarkerSpacingBytes;
+ 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("%s(): mode = %lu, size = %lu", __func__,
+ multislice_cfg.mslice_mode, multislice_cfg.mslice_size);
+ DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set Slice mode control");
+ return false;
+ }
+
+ DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
+ multislice.mslice_mode=control.value;
+
+ control.id = (multislice_cfg.mslice_mode == VEN_MSLICE_GOB) ?
+ V4L2_CID_MPEG_VIDEO_MULTI_SLICE_GOB : V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES;
+ control.value = resynchMarkerSpacingBytes;
+ DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set MAX MB control");
+ return false;
+ }
+
+ DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", 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;
+ control.value=0;
+
+ 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", 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", 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", 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", 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", 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", 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("venc_set_target_bitrate: bitrate = %u",
+ (unsigned int)nTargetBitrate);
+ struct v4l2_control control;
+ int rc = 0;
+
+ if (vqzip_sei_info.enabled) {
+ DEBUG_PRINT_HIGH("For VQZIP 1.0, Bitrate setting is not supported");
+ return true;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDEO_BITRATE;
+ control.value = nTargetBitrate;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", 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",profile_level.level);
+ }
+ }
+
+ // Configure layer-wise bitrate if temporal layers are enabled and layer-wise distribution
+ // has been specified
+ if (temporal_layers_config.bIsBitrateRatioValid && temporal_layers_config.nPLayers) {
+ OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
+ numLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
+
+ DEBUG_PRINT_LOW("TemporalLayer: configuring layerwise bitrate");
+ for (OMX_U32 i = 0; i < numLayers; ++i) {
+ layerBitrates[i] =
+ (temporal_layers_config.nTemporalLayerBitrateFraction[i] * bitrate.target_bitrate) / 100;
+ DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
+ i, temporal_layers_config.nTemporalLayerBitrateFraction[i],
+ layerBitrates[i], bitrate.target_bitrate);
+ }
+ if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
+ return false;
+ }
+ }
+
+ 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 (vqzip_sei_info.enabled) {
+ DEBUG_PRINT_HIGH("For VQZIP 1.0, Framerate setting is not supported");
+ return true;
+ }
+
+
+ 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");
+ 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",profile_level.level);
+ }
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_color_format(OMX_COLOR_FORMATTYPE color_format)
+{
+ struct v4l2_format fmt;
+ int color_space = 0;
+ DEBUG_PRINT_LOW("venc_set_color_format: color_format = %u ", color_format);
+
+ switch ((int)color_format) {
+ case OMX_COLOR_FormatYUV420SemiPlanar:
+ case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12;
+ color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
+ break;
+ case QOMX_COLOR_FormatYVU420SemiPlanar:
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV21;
+ color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
+ break;
+ case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed:
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_NV12_UBWC;
+ color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
+ break;
+ case QOMX_COLOR_Format32bitRGBA8888:
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGB32;
+ break;
+ case QOMX_COLOR_Format32bitRGBA8888Compressed:
+ m_sVenc_cfg.inputformat = V4L2_PIX_FMT_RGBA8888_UBWC;
+ break;
+ default:
+ DEBUG_PRINT_HIGH("WARNING: Unsupported Color format [%d]", color_format);
+ m_sVenc_cfg.inputformat = V4L2_DEFAULT_OUTPUT_COLOR_FMT;
+ color_space = V4L2_COLORSPACE_470_SYSTEM_BG;
+ DEBUG_PRINT_HIGH("Default color format NV12 UBWC is set");
+#ifdef _PQ_
+ /*
+ * If Client is using Opaque, YUV format will be informed with
+ * first ETB. Till that point, it is unknown.
+ */
+ m_pq.is_YUV_format_uncertain = true;
+#endif // _PQ_
+ break;
+ }
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.inputformat;
+ fmt.fmt.pix_mp.colorspace = color_space;
+ 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("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;
+ DEBUG_PRINT_ERROR("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set Intra Frame Request control");
+ return false;
+ }
+
+ DEBUG_PRINT_ERROR("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
+ } else {
+ DEBUG_PRINT_ERROR("ERROR: VOP Refresh is False, no effect");
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_deinterlace(OMX_U32 enable)
+{
+ DEBUG_PRINT_LOW("venc_set_deinterlace: enable = %u", (unsigned int)enable);
+ struct v4l2_control control;
+ int rc;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE;
+ if (enable)
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
+ else
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_DEINTERLACE_ENABLED;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set Deinterlcing control");
+ return false;
+ }
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
+ deinterlace_enabled = true;
+ return true;
+}
+
+bool venc_dev::venc_calibrate_gop()
+{
+ int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
+ int num_sub_gops_in_a_gop;
+ nPframes = intra_period.num_pframes;
+ nBframes = intra_period.num_bframes;
+ nLayers = hier_layers.numlayers;
+ if (temporal_layers_config.nPLayers) {
+ nLayers = temporal_layers_config.nPLayers + temporal_layers_config.nBLayers;
+ }
+
+ if (!nPframes && nLayers) {
+ DEBUG_PRINT_ERROR("nPframes should be non-zero when nLayers are present\n");
+ return false;
+ }
+
+ if (nLayers > 1) { /*Multi-layer encoding*/
+ sub_gop_size = 1 << (nLayers - 1);
+ /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
+ * below calculations we are ignoring +1 . Ignoring +1 in below
+ * calculations is not a mistake but intentional.
+ */
+ gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
+ num_sub_gops_in_a_gop = gop_size/sub_gop_size;
+ if (nBframes) { /*Hier-B case*/
+ /*
+ * Frame Type--> I B B B P B B B P I B B P ...
+ * Layer --> 0 2 1 2 0 2 1 2 0 0 2 1 2 ...
+ * nPframes = 2, nBframes = 6, nLayers = 3
+ *
+ * Intention is to keep the intraperiod as close as possible to what is desired
+ * by the client while adjusting nPframes and nBframes to meet other constraints.
+ * eg1: Input by client: nPframes = 9, nBframes = 14, nLayers = 2
+ * Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
+ *
+ * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
+ * Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
+ */
+ nPframes = num_sub_gops_in_a_gop;
+ nBframes = gop_size - nPframes;
+ } else { /*Hier-P case*/
+ /*
+ * Frame Type--> I P P P P P P P I P P P P ...
+ * Layer--> 0 2 1 2 0 2 1 2 0 2 1 2 0 ...
+ * nPframes = 7, nBframes = 0, nLayers = 3
+ *
+ * Intention is to keep the intraperiod as close as possible to what is desired
+ * by the client while adjusting nPframes and nBframes to meet other constraints.
+ * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
+ * Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
+ *
+ * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
+ * Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
+ */
+ nPframes = gop_size - 1;
+ }
+ } else { /*Single-layer encoding*/
+ if (nBframes) {
+ /* I P B B B P B B B P B B B I P B B...
+ * 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17...
+ * nPframes = 3, nBframes = 9, nLayers = 0
+ *
+ * ratio is rounded,
+ * eg1: nPframes = 9, nBframes = 11 => ratio = 1
+ * eg2: nPframes = 9, nBframes = 16 => ratio = 2
+ */
+ ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
+ nBframes = ratio * nPframes;
+ }
+ }
+ DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
+ intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
+ intra_period.num_pframes = nPframes;
+ intra_period.num_bframes = nBframes;
+ hier_layers.numlayers = nLayers;
+ return true;
+}
+
+bool venc_dev::venc_set_bitrate_type(OMX_U32 type)
+{
+ struct v4l2_control control;
+ int rc = 0;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_TYPE;
+ control.value = type;
+ DEBUG_PRINT_LOW("Set Bitrate type to %s for %d \n", bitrate_type_string(type), type);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Request to set Bitrate type to %s failed",
+ bitrate_type_string(type));
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_layer_bitrates(OMX_U32 *layerBitrate, OMX_U32 numLayers)
+{
+ DEBUG_PRINT_LOW("venc_set_layer_bitrates");
+ struct v4l2_ext_control ctrl[OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS];
+ struct v4l2_ext_controls controls;
+ int rc = 0;
+ OMX_U32 i;
+
+ if (!venc_set_bitrate_type(V4L2_CID_MPEG_VIDC_VIDEO_VENC_BITRATE_ENABLE)) {
+ DEBUG_PRINT_ERROR("Failed to set layerwise bitrate type %d", rc);
+ return false;
+ }
+
+ for (OMX_U32 i = 0; i < numLayers && i < OMX_VIDEO_ANDROID_MAXTEMPORALLAYERS; ++i) {
+ if (!layerBitrate[i]) {
+ DEBUG_PRINT_ERROR("Invalid bitrate settings for layer %d", i);
+ return false;
+ } else {
+ ctrl[i].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_LAYER_BITRATE;
+ ctrl[i].value = layerBitrate[i];
+ }
+ }
+ controls.count = numLayers;
+ controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ controls.controls = ctrl;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set layerwise bitrate %d", rc);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Layerwise bitrate configured successfully");
+ return true;
+}
+
+bool venc_dev::venc_set_hybrid_hierp(QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* hhp)
+{
+ DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers");
+ struct v4l2_control control;
+ int rc;
+
+ if (!venc_validate_hybridhp_params(hhp->nHpLayers, 0, 0, (int) HIER_P_HYBRID)) {
+ DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
+ return false;
+ }
+
+ if (!hhp->nHpLayers || hhp->nHpLayers > MAX_HYB_HIERP_LAYERS) {
+ DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", hhp->nHpLayers);
+ return false;
+ }
+ if (!venc_set_intra_period(hhp->nKeyFrameInterval, 0)) {
+ DEBUG_PRINT_ERROR("Failed to set Intraperiod: %d", hhp->nKeyFrameInterval);
+ return false;
+ }
+
+ hier_layers.numlayers = hhp->nHpLayers;
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ hier_layers.hier_mode = HIER_P_HYBRID;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ hier_layers.hier_mode = HIER_P;
+ }
+ if (venc_calibrate_gop()) {
+ // Update the driver with the new nPframes and nBframes
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
+ control.value = intra_period.num_pframes;
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
+ control.value = intra_period.num_bframes;
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+ DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
+ intra_period.num_pframes, intra_period.num_bframes);
+ } else {
+ DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
+ return false;
+ }
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
+ }
+ control.value = hhp->nHpLayers - 1;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
+ control.id, control.value);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp %d", rc);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
+ control.id, control.value);
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
+ return false;
+ }
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
+ control.value = hhp->nHpLayers - 1;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Failed : Unsupported codec for Hybrid Hier P : %lu", m_sVenc_cfg.codectype);
+ return false;
+ }
+
+ if(venc_set_session_qp_range (hhp->nMinQuantizer,
+ hhp->nMaxQuantizer) == false) {
+ DEBUG_PRINT_ERROR("ERROR: Setting QP Range for hybridHP [%u %u] failed",
+ (unsigned int)hhp->nMinQuantizer, (unsigned int)hhp->nMaxQuantizer);
+ return false;
+ } else {
+ session_qp_values.minqp = hhp->nMinQuantizer;
+ session_qp_values.maxqp = hhp->nMaxQuantizer;
+ }
+
+ OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0};
+ for (OMX_U32 i = 0; i < hhp->nHpLayers; i++) {
+ layerBitrates[i] = hhp->nTemporalLayerBitrateRatio[i];
+ hybrid_hp.nTemporalLayerBitrateRatio[i] = hhp->nTemporalLayerBitrateRatio[i];
+ DEBUG_PRINT_LOW("Setting Layer[%u] bitrate = %u", i, layerBitrates[i]);
+ }
+ if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, hhp->nHpLayers)) {
+ DEBUG_PRINT_ERROR("Failed to set Layer wise bitrate: %d, %d, %d, %d, %d, %d",
+ hhp->nTemporalLayerBitrateRatio[0],hhp->nTemporalLayerBitrateRatio[1],
+ hhp->nTemporalLayerBitrateRatio[2],hhp->nTemporalLayerBitrateRatio[3],
+ hhp->nTemporalLayerBitrateRatio[4],hhp->nTemporalLayerBitrateRatio[5]);
+ return false;
+ }
+ hybrid_hp.nHpLayers = hhp->nHpLayers;
+
+ // Set this or else the layer0 bitrate will be overwritten by
+ // default value in component
+ m_sVenc_cfg.targetbitrate = bitrate.target_bitrate = hhp->nTemporalLayerBitrateRatio[0];
+ hybrid_hp.nHpLayers = hhp->nHpLayers;
+ hybrid_hp.nKeyFrameInterval = hhp->nKeyFrameInterval;
+ hybrid_hp.nMaxQuantizer = hhp->nMaxQuantizer;
+ hybrid_hp.nMinQuantizer = hhp->nMinQuantizer;
+ return true;
+}
+
+bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
+{
+ DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
+ struct v4l2_ext_control ctrl[2];
+ struct v4l2_ext_controls controls;
+ int rc;
+
+ if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
+ DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
+ return false;
+ }
+
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
+ if (enable)
+ ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
+ else
+ ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
+
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
+ if (enable && count > 0)
+ ctrl[1].value = count;
+ else if (enable)
+ ctrl[1].value = 1;
+ else
+ ctrl[1].value = 0;
+
+ controls.count = 2;
+ controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ controls.controls = ctrl;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d id=%x, val=%d",
+ controls.controls[0].id, controls.controls[0].value,
+ controls.controls[1].id, controls.controls[1].value);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
+ return false;
+ }
+ ltrinfo.enabled = enable;
+ ltrinfo.count = count;
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
+ controls.controls[0].id, controls.controls[0].value,
+ controls.controls[1].id, controls.controls[1].value);
+
+ if (!venc_set_profile_level(0, 0)) {
+ DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
+ __func__);
+ } else {
+ DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
+ __func__, codec_profile.profile, profile_level.level);
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
+{
+ DEBUG_PRINT_LOW("venc_use_goldenframe");
+ int rc = true;
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
+ control.value = frameIdx;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set use_ltr %d", rc);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
+ control.id, control.value);
+ return true;
+}
+
+bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
+{
+ DEBUG_PRINT_LOW("venc_set_goldenframe");
+ int rc = true;
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
+ control.value = frameIdx;
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d",
+ control.id, control.value);
+ return true;
+}
+
+bool venc_dev::venc_set_vpe_rotation(OMX_S32 rotation_angle)
+{
+ DEBUG_PRINT_LOW("venc_set_vpe_rotation: rotation angle = %d", (int)rotation_angle);
+ struct v4l2_control control;
+ int rc;
+ struct v4l2_format fmt;
+ struct v4l2_requestbuffers bufreq;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION;
+ if (rotation_angle == 0)
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_NONE;
+ else if (rotation_angle == 90)
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_90;
+ else if (rotation_angle == 180)
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_180;
+ else if (rotation_angle == 270)
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_ROTATION_270;
+ else {
+ DEBUG_PRINT_ERROR("Failed to find valid rotation angle");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_HIGH("Failed to set VPE Rotation control");
+ return false;
+ }
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
+ fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
+ fmt.fmt.pix_mp.pixelformat = m_sVenc_cfg.codectype;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_FMT, &fmt)) {
+ DEBUG_PRINT_ERROR("Failed to set format on capture port");
+ return false;
+ }
+
+ m_sOutput_buff_property.datasize = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = m_sOutput_buff_property.actualcount;
+ bufreq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ if (ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq)) {
+ DEBUG_PRINT_ERROR("ERROR: Request for o/p buffer count failed for rotation");
+ return false;
+ }
+ if (bufreq.count >= m_sOutput_buff_property.mincount)
+ m_sOutput_buff_property.actualcount = m_sOutput_buff_property.mincount = bufreq.count;
+
+ return true;
+}
+
+bool venc_dev::venc_set_searchrange()
+{
+ DEBUG_PRINT_LOW("venc_set_searchrange");
+ struct v4l2_control control;
+ struct v4l2_ext_control ctrl[6];
+ struct v4l2_ext_controls controls;
+ int rc;
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_MPEG4) {
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
+ ctrl[0].value = 16;
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
+ ctrl[1].value = 4;
+ ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
+ ctrl[2].value = 16;
+ ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
+ ctrl[3].value = 4;
+ ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
+ ctrl[4].value = 12;
+ ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
+ ctrl[5].value = 4;
+ } else if ((m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) ||
+ (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
+ ctrl[0].value = 16;
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
+ ctrl[1].value = 4;
+ ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
+ ctrl[2].value = 16;
+ ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
+ ctrl[3].value = 4;
+ ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
+ ctrl[4].value = 12;
+ ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
+ ctrl[5].value = 4;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_X_RANGE;
+ ctrl[0].value = 4;
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_IFRAME_Y_RANGE;
+ ctrl[1].value = 4;
+ ctrl[2].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_X_RANGE;
+ ctrl[2].value = 4;
+ ctrl[3].id = V4L2_CID_MPEG_VIDC_VIDEO_PFRAME_Y_RANGE;
+ ctrl[3].value = 4;
+ ctrl[4].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_X_RANGE;
+ ctrl[4].value = 4;
+ ctrl[5].id = V4L2_CID_MPEG_VIDC_VIDEO_BFRAME_Y_RANGE;
+ ctrl[5].value = 4;
+ } else {
+ DEBUG_PRINT_ERROR("Invalid codec type");
+ return false;
+ }
+ controls.count = 6;
+ controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ controls.controls = ctrl;
+
+ DEBUG_PRINT_LOW(" Calling IOCTL set control for"
+ "id=%x, val=%d id=%x, val=%d"
+ "id=%x, val=%d id=%x, val=%d"
+ "id=%x, val=%d id=%x, val=%d",
+ controls.controls[0].id, controls.controls[0].value,
+ controls.controls[1].id, controls.controls[1].value,
+ controls.controls[2].id, controls.controls[2].value,
+ controls.controls[3].id, controls.controls[3].value,
+ controls.controls[4].id, controls.controls[4].value,
+ controls.controls[5].id, controls.controls[5].value);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set search range %d", rc);
+ return false;
+ }
+ 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 ((OMX_U32)eControlRate) {
+ case OMX_Video_ControlRateDisable:
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
+ break;
+ case OMX_Video_ControlRateVariableSkipFrames:
+ (supported_rc_modes & RC_VBR_VFR) ?
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
+ status = false;
+ break;
+ case OMX_Video_ControlRateVariable:
+ (supported_rc_modes & RC_VBR_CFR) ?
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
+ status = false;
+ break;
+ case OMX_Video_ControlRateConstantSkipFrames:
+ (supported_rc_modes & RC_CBR_VFR) ?
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
+ status = false;
+ break;
+ case OMX_Video_ControlRateConstant:
+ (supported_rc_modes & RC_CBR_CFR) ?
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
+ status = false;
+ break;
+ case QOMX_Video_ControlRateMaxBitrate:
+ (supported_rc_modes & RC_MBR_CFR) ?
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR:
+ status = false;
+ break;
+ case QOMX_Video_ControlRateMaxBitrateSkipFrames:
+ (supported_rc_modes & RC_MBR_VFR) ?
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR:
+ status = false;
+ break;
+ default:
+ status = false;
+ break;
+ }
+
+ if (status) {
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ rate_ctrl.rcmode = control.value;
+ }
+
+#ifdef _VQZIP_
+ if (eControlRate == OMX_Video_ControlRateVariable && (supported_rc_modes & RC_VBR_CFR)
+ && m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ /* Enable VQZIP SEI by default for camcorder RC modes */
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI;
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_VQZIP_SEI_ENABLE;
+ DEBUG_PRINT_HIGH("Set VQZIP SEI:");
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control) < 0) {
+ DEBUG_PRINT_HIGH("Non-Fatal: Request to set VQZIP failed");
+ }
+ }
+#endif
+
+ return status;
+}
+
+bool venc_dev::venc_set_perf_level(QOMX_VIDEO_PERF_LEVEL ePerfLevel)
+{
+ bool status = true;
+ struct v4l2_control control;
+ int rc = 0;
+ control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+
+ switch (ePerfLevel) {
+ case OMX_QCOM_PerfLevelNominal:
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
+ break;
+ case OMX_QCOM_PerfLevelTurbo:
+ control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+ break;
+ default:
+ status = false;
+ break;
+ }
+
+ if (status) {
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set control for id=%d, val=%d", control.id, control.value);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+ }
+ return status;
+}
+
+bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
+{
+ struct v4l2_control control;
+ if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
+ control.value = mode;
+ DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
+ return false;
+ }
+ return true;
+ } else {
+ DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
+ return false;
+ }
+}
+
+bool venc_dev::venc_set_qp(OMX_U32 nQp)
+{
+ struct v4l2_control control;
+ if (nQp) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP;
+ control.value = nQp;
+ DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP");
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Invalid qp set for V4L2_CID_MPEG_VIDC_VIDEO_CONFIG_QP: %d", nQp);
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_aspectratio(void *nSar)
+{
+ int rc;
+ struct v4l2_control control;
+ struct v4l2_ext_control ctrl[2];
+ struct v4l2_ext_controls controls;
+ QOMX_EXTNINDEX_VIDEO_VENC_SAR *sar;
+
+ sar = (QOMX_EXTNINDEX_VIDEO_VENC_SAR *) nSar;
+
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_WIDTH;
+ ctrl[0].value = sar->nSARWidth;
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VENC_PARAM_SAR_HEIGHT;
+ ctrl[1].value = sar->nSARHeight;
+
+ controls.count = 2;
+ controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ controls.controls = ctrl;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x val=%d, id=%x val=%d",
+ controls.controls[0].id, controls.controls[0].value,
+ controls.controls[1].id, controls.controls[1].value);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set SAR %d", rc);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x val=%d, id=%x val=%d",
+ controls.controls[0].id, controls.controls[0].value,
+ controls.controls[1].id, controls.controls[1].value);
+ return true;
+}
+
+bool venc_dev::venc_set_hierp_layers(OMX_U32 hierp_layers)
+{
+ struct v4l2_control control;
+ if (hierp_layers && (hier_layers.hier_mode == HIER_P) &&
+ (hierp_layers <= hier_layers.numlayers)) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
+ control.value = hierp_layers - 1;
+ DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS");
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set HIERP_LAYERS");
+ return false;
+ }
+ return true;
+ } else {
+ DEBUG_PRINT_ERROR("Invalid layers set for HIERP_LAYERS: %d",
+ hierp_layers);
+ return false;
+ }
+}
+
+bool venc_dev::venc_set_lowlatency_mode(OMX_BOOL enable)
+{
+ int rc = 0;
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE;
+ if (enable)
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_ENABLE;
+ else
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_DISABLE;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set lowlatency control");
+ return false;
+ }
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
+
+ return true;
+}
+
+bool venc_dev::venc_set_low_latency(OMX_BOOL enable)
+{
+ struct v4l2_control control;
+
+ if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264) {
+ DEBUG_PRINT_ERROR("Low Latency mode is valid only for H264");
+ return false;
+ }
+
+ enable ? control.value = 2 : control.value = 0;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_PIC_ORDER_CNT;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set H264_PICORDER_CNT");
+ return false;
+ }
+
+ low_latency_mode = (OMX_BOOL) enable;
+
+ return true;
+}
+
+bool venc_dev::venc_set_baselayerid(OMX_U32 baseid)
+{
+ struct v4l2_control control;
+ if (hier_layers.hier_mode == HIER_P) {
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID;
+ control.value = baseid;
+ DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID");
+ return false;
+ }
+ return true;
+ } else {
+ DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_BASELAYER_ID: %d",
+ hier_layers.hier_mode);
+ return false;
+ }
+}
+
+bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
+{
+ struct v4l2_control control;
+ int rc = 0;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO;
+
+ if (enable)
+ control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_ENABLED;
+ else
+ control.value = V4L2_MPEG_VIDC_VIDEO_H264_VUI_TIMING_INFO_DISABLED;
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set VUI timing info control");
+ return false;
+ }
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, value=%d", control.id, control.value);
+ return true;
+}
+
+bool venc_dev::venc_set_peak_bitrate(OMX_U32 nPeakBitrate)
+{
+ struct v4l2_control control;
+ int rc = 0;
+ control.id = V4L2_CID_MPEG_VIDEO_BITRATE_PEAK;
+ control.value = nPeakBitrate;
+
+ DEBUG_PRINT_LOW("venc_set_peak_bitrate: bitrate = %u", (unsigned int)nPeakBitrate);
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set peak bitrate control");
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+
+ return true;
+}
+
+bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
+{
+ struct v4l2_control control;
+ int rc = 0;
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
+
+ if (enable)
+ control.value = 1;
+ else
+ control.value = 0;
+
+ DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
+
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+
+ rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
+ return false;
+ }
+ vpx_err_resilience.enable = 1;
+ DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+ return true;
+}
+
+bool venc_dev::venc_set_priority(OMX_U32 priority) {
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
+ if (priority == 0)
+ control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
+ else
+ control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
+
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_%s",
+ priority == 0 ? "ENABLE" : "DISABLE");
+ return false;
+ }
+ return true;
+}
+
+bool venc_dev::venc_set_operatingrate(OMX_U32 rate) {
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
+ control.value = rate;
+
+ DEBUG_PRINT_LOW("venc_set_operating_rate: %d fps", rate >> 16);
+ DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+
+ if(ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ hw_overload = errno == EBUSY;
+ DEBUG_PRINT_ERROR("Failed to set operating rate %d fps (%s)",
+ rate >> 16, hw_overload ? "HW overload" : strerror(errno));
+ return false;
+ }
+ operating_rate = rate;
+ DEBUG_PRINT_LOW("Operating Rate Set = %d fps", rate >> 16);
+ return true;
+}
+
+bool venc_dev::venc_set_roi_qp_info(OMX_QTI_VIDEO_CONFIG_ROIINFO *roiInfo) {
+ if (!roiInfo) {
+ DEBUG_PRINT_ERROR("No ROI info present");
+ return false;
+ }
+ if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_H264 &&
+ m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
+ DEBUG_PRINT_ERROR("OMX_QTIIndexConfigVideoRoiInfo is not supported for %d codec", (OMX_U32) m_sVenc_cfg.codectype);
+ return false;
+ }
+
+#ifdef _PQ_
+ DEBUG_PRINT_HIGH("ROI QP info received");
+ pthread_mutex_lock(&m_pq.lock);
+ roi.info = *roiInfo;
+ roi.dirty = true;
+ pthread_mutex_unlock(&m_pq.lock);
+#else // _PQ_
+ roi.info = *roiInfo;
+ roi.dirty = true;
+#endif // _PQ_
+
+ return true;
+}
+
+bool venc_dev::venc_set_blur_resolution(OMX_QTI_VIDEO_CONFIG_BLURINFO *blurInfo)
+{
+ struct v4l2_ext_control ctrl[2];
+ struct v4l2_ext_controls controls;
+
+ int blur_width = 0, blur_height = 0;
+
+ switch (blurInfo->eTargetResol) {
+ case BLUR_RESOL_DISABLED:
+ blur_width = 0;
+ blur_height = 0;
+ break;
+ case BLUR_RESOL_240:
+ blur_width = 426;
+ blur_height = 240;
+ break;
+ case BLUR_RESOL_480:
+ blur_width = 854;
+ blur_height = 480;
+ break;
+ case BLUR_RESOL_720:
+ blur_width = 1280;
+ blur_height = 720;
+ break;
+ case BLUR_RESOL_1080:
+ blur_width = 1920;
+ blur_height = 1080;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("Blur resolution not recognized");
+ return false;
+ }
+
+ ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_BLUR_WIDTH;
+ ctrl[0].value = blur_width;
+
+ ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_BLUR_HEIGHT;
+ ctrl[1].value = blur_height;
+
+ controls.count = 2;
+ controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+ controls.controls = ctrl;
+
+ if(ioctl(m_nDriver_fd, VIDIOC_S_EXT_CTRLS, &controls)) {
+ DEBUG_PRINT_ERROR("Failed to set blur resoltion");
+ return false;
+ }
+ DEBUG_PRINT_LOW("Blur resolution set = %d x %d", blur_width, blur_height);
+ return true;
+
+}
+
+bool venc_dev::venc_h264_transform_8x8(OMX_BOOL enable)
+{
+ struct v4l2_control control;
+
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8;
+ if (enable)
+ control.value = V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_ENABLE;
+ else
+ control.value = V4L2_MPEG_VIDC_VIDEO_H264_TRANSFORM_8x8_DISABLE;
+
+ DEBUG_PRINT_LOW("Set h264_transform_8x8 mode: %d", control.value);
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("set control: H264 transform 8x8 failed");
+ return false;
+ }
+
+ return true;
+}
+
+bool venc_dev::venc_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
+ OMX_U32 *nMaxBLayers) {
+
+ // no B-layers for all cases
+ temporal_layers_config.nMaxBLayers = 0;
+ temporal_layers_config.nMaxLayers = 1;
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
+ || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ temporal_layers_config.nMaxLayers = MAX_HYB_HIERP_LAYERS; // TODO: get this count from codec
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ temporal_layers_config.nMaxLayers = 4; // TODO: get this count from codec
+ }
+
+ *nMaxLayers = temporal_layers_config.nMaxLayers;
+ *nMaxBLayers = temporal_layers_config.nMaxBLayers;
+ return true;
+}
+
+OMX_ERRORTYPE venc_dev::venc_set_temporal_layers(
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE *pTemporalParams) {
+
+ if (!(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264
+ || m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC
+ || m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8)) {
+ DEBUG_PRINT_ERROR("Temporal layers not supported for %s", codec_as_string(m_sVenc_cfg.codectype));
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ if (pTemporalParams->ePattern == OMX_VIDEO_AndroidTemporalLayeringPatternNone &&
+ (pTemporalParams->nBLayerCountActual != 0 ||
+ pTemporalParams->nPLayerCountActual != 1)) {
+ return OMX_ErrorBadParameter;
+ } else if (pTemporalParams->ePattern != OMX_VIDEO_AndroidTemporalLayeringPatternAndroid ||
+ pTemporalParams->nPLayerCountActual < 1) {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (pTemporalParams->nBLayerCountActual > temporal_layers_config.nMaxBLayers) {
+ DEBUG_PRINT_ERROR("TemporalLayer: Requested B-layers(%u) exceeds supported max(%u)",
+ pTemporalParams->nBLayerCountActual, temporal_layers_config.nMaxBLayers);
+ return OMX_ErrorBadParameter;
+ } else if (pTemporalParams->nPLayerCountActual >
+ temporal_layers_config.nMaxLayers - pTemporalParams->nBLayerCountActual) {
+ DEBUG_PRINT_ERROR("TemporalLayer: Requested layers(%u) exceeds supported max(%u)",
+ pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual,
+ temporal_layers_config.nMaxLayers);
+ return OMX_ErrorBadParameter;
+ }
+
+ // For AVC, if B-layer has not been configured and RC mode is VBR (camcorder),
+ // use hybrid-HP for best results
+ bool isAvc = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
+ bool isVBR = rate_ctrl.rcmode == RC_VBR_CFR || rate_ctrl.rcmode == RC_VBR_VFR;
+ bool bUseHybridMode = isAvc && pTemporalParams->nBLayerCountActual == 0 && isVBR;
+
+ // If there are more than 3 layers configured for AVC, normal HP will not work. force hybrid
+ bUseHybridMode |= (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS);
+
+ DEBUG_PRINT_LOW("TemporalLayer: RC-mode = %ld : %s hybrid-HP",
+ rate_ctrl.rcmode, bUseHybridMode ? "enable" : "disable");
+
+ if (bUseHybridMode &&
+ !venc_validate_hybridhp_params(pTemporalParams->nPLayerCountActual,
+ pTemporalParams->nBLayerCountActual,
+ 0 /* LTR count */, (int) HIER_P_HYBRID)) {
+ bUseHybridMode = false;
+ DEBUG_PRINT_ERROR("Failed to validate Hybrid HP. Will try fallback to normal HP");
+ }
+
+ if (intra_period.num_bframes) {
+ DEBUG_PRINT_ERROR("TemporalLayer: B frames are not supported with layers");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ if (!venc_set_intra_period(intra_period.num_pframes, intra_period.num_bframes)) {
+ DEBUG_PRINT_ERROR("TemporalLayer : Failed to set Intra-period nP(%lu)/pB(%lu)",
+ intra_period.num_pframes, intra_period.num_bframes);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ struct v4l2_control control;
+ // Num enhancements layers does not include the base-layer
+ control.value = pTemporalParams->nPLayerCountActual - 1;
+
+ if (bUseHybridMode) {
+ DEBUG_PRINT_LOW("TemporalLayer: Try enabling hybrid HP with %u layers", control.value);
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ bUseHybridMode = false;
+ DEBUG_PRINT_ERROR("Failed to set hybrid HP");
+ } else {
+ // Disable normal HP if Hybrid mode is being enabled
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
+ control.value = 0;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
+ control.value = 0;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set HP layers to %u", control.value);
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+ }
+
+ if (!bUseHybridMode) {
+
+ // in case of normal HP, avc encoder cannot support more than MAX_AVC_HP_LAYERS
+ if (isAvc && pTemporalParams->nPLayerCountActual > MAX_AVC_HP_LAYERS) {
+ DEBUG_PRINT_ERROR("AVC supports only up to %d layers", MAX_AVC_HP_LAYERS);
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ DEBUG_PRINT_LOW("TemporalLayer: Try enabling HP with %u layers", control.value);
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set hybrid hierp/hierp");
+ return OMX_ErrorUnsupportedSetting;
+ }
+
+ // configure max layers for a session.. Okay to use current num-layers as max
+ // since we do not plan to support dynamic changes to number of layers
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_MAX_HIERP_LAYERS;
+ control.value = pTemporalParams->nPLayerCountActual - 1;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to set max HP layers to %u", control.value);
+ return OMX_ErrorUnsupportedSetting;
+
+ } else if (temporal_layers_config.hier_mode == HIER_P_HYBRID) {
+ // Disable hybrid mode if it was enabled already
+ DEBUG_PRINT_LOW("TemporalLayer: disable hybrid HP (normal-HP preferred)");
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
+ control.value = 0;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to disable hybrid HP !");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+ }
+
+ // SVC-NALs to indicate layer-id in case of H264 needs explicit enablement..
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ DEBUG_PRINT_LOW("TemporalLayer: Enable H264_SVC_NAL");
+ control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
+ control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
+ if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+ DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
+ return OMX_ErrorUnsupportedSetting;
+ }
+ }
+
+ temporal_layers_config.hier_mode = bUseHybridMode ? HIER_P_HYBRID : HIER_P;
+ temporal_layers_config.nPLayers = pTemporalParams->nPLayerCountActual;
+ temporal_layers_config.nBLayers = 0;
+
+ temporal_layers_config.bIsBitrateRatioValid = OMX_FALSE;
+ if (pTemporalParams->bBitrateRatiosSpecified == OMX_FALSE) {
+ DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio not specified. Will use cumulative..");
+ return OMX_ErrorNone;
+ }
+ DEBUG_PRINT_LOW("TemporalLayer: layerwise bitrate ratio specified");
+
+ OMX_U32 layerBitrates[OMX_VIDEO_MAX_HP_LAYERS] = {0},
+ numLayers = pTemporalParams->nPLayerCountActual + pTemporalParams->nBLayerCountActual;
+
+ OMX_U32 i = 0;
+ for (; i < numLayers; ++i) {
+ OMX_U32 previousLayersAccumulatedBitrateRatio = i == 0 ? 0 : pTemporalParams->nBitrateRatios[i-1];
+ OMX_U32 currentLayerBitrateRatio = pTemporalParams->nBitrateRatios[i] - previousLayersAccumulatedBitrateRatio;
+ if (previousLayersAccumulatedBitrateRatio > pTemporalParams->nBitrateRatios[i]) {
+ DEBUG_PRINT_ERROR("invalid bitrate ratio for layer %d.. Will fallback to cumulative", i);
+ return OMX_ErrorBadParameter;
+ } else {
+ layerBitrates[i] = (currentLayerBitrateRatio * bitrate.target_bitrate) / 100;
+ temporal_layers_config.nTemporalLayerBitrateRatio[i] = pTemporalParams->nBitrateRatios[i];
+ temporal_layers_config.nTemporalLayerBitrateFraction[i] = currentLayerBitrateRatio;
+ DEBUG_PRINT_LOW("TemporalLayer: layer[%u] ratio=%u%% bitrate=%u(of %ld)",
+ i, currentLayerBitrateRatio, layerBitrates[i], bitrate.target_bitrate);
+ }
+ }
+
+ temporal_layers_config.bIsBitrateRatioValid = OMX_TRUE;
+
+ // Setting layerwise bitrate makes sense only if target bitrate is configured, else defer until later..
+ if (bitrate.target_bitrate > 0) {
+ if (!venc_set_layer_bitrates((OMX_U32 *)layerBitrates, numLayers)) {
+ return OMX_ErrorUnsupportedSetting;
+ }
+ } else {
+ DEBUG_PRINT_HIGH("Defer setting layerwise bitrate since target bitrate is not yet set");
+ }
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE venc_dev::venc_set_temporal_layers_internal() {
+ OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE pTemporalParams;
+ memset(&pTemporalParams, 0x0, sizeof(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE));
+
+ if (!temporal_layers_config.nPLayers) {
+ return OMX_ErrorNone;
+ }
+ pTemporalParams.eSupportedPatterns = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+ pTemporalParams.nLayerCountMax = temporal_layers_config.nMaxLayers;
+ pTemporalParams.nBLayerCountMax = temporal_layers_config.nMaxBLayers;
+ pTemporalParams.ePattern = OMX_VIDEO_AndroidTemporalLayeringPatternAndroid;
+ pTemporalParams.nPLayerCountActual = temporal_layers_config.nPLayers;
+ pTemporalParams.nBLayerCountActual = temporal_layers_config.nBLayers;
+ pTemporalParams.bBitrateRatiosSpecified = temporal_layers_config.bIsBitrateRatioValid;
+ if (temporal_layers_config.bIsBitrateRatioValid == OMX_TRUE) {
+ for (OMX_U32 i = 0; i < temporal_layers_config.nPLayers + temporal_layers_config.nBLayers; ++i) {
+ pTemporalParams.nBitrateRatios[i] =
+ temporal_layers_config.nTemporalLayerBitrateRatio[i];
+ }
+ }
+ return venc_set_temporal_layers(&pTemporalParams);
+}
+
+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_CONSTRAINED_BASELINE:
+ *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
+ *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
+ 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;
+ case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
+ *eLevel = OMX_VIDEO_AVCLevel52;
+ break;
+ default :
+ *eLevel = OMX_VIDEO_AVCLevelMax;
+ status = false;
+ break;
+ }
+ }
+ else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ switch (codec_profile.profile) {
+ case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
+ *eProfile = OMX_VIDEO_VP8ProfileMain;
+ break;
+ default:
+ *eProfile = OMX_VIDEO_VP8ProfileMax;
+ status = false;
+ break;
+ }
+ if (!status) {
+ return status;
+ }
+
+ switch (profile_level.level) {
+ case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
+ *eLevel = OMX_VIDEO_VP8Level_Version0;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
+ *eLevel = OMX_VIDEO_VP8Level_Version1;
+ break;
+ default:
+ *eLevel = OMX_VIDEO_VP8LevelMax;
+ status = false;
+ break;
+ }
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ switch (codec_profile.profile) {
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
+ *eProfile = OMX_VIDEO_HEVCProfileMain;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
+ *eProfile = OMX_VIDEO_HEVCProfileMain10;
+ break;
+ default:
+ *eProfile = OMX_VIDEO_HEVCProfileMax;
+ status = false;
+ break;
+ }
+ if (!status) {
+ return status;
+ }
+
+ switch (profile_level.level) {
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
+ *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
+ *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
+ break;
+ default:
+ *eLevel = OMX_VIDEO_HEVCLevelMax;
+ 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;
+
+ if (vqzip_sei_info.enabled) {
+ DEBUG_PRINT_HIGH("VQZIP is enabled. Profile and Level set by client. Skipping validation");
+ return true;
+ }
+
+ DEBUG_PRINT_LOW("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("%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("Unsupported MPEG4 profile type %u", (unsigned int)*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_CONSTRAINED_BASELINE:
+ *eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
+ break;
+ case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
+ *eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
+ 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("%s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if (*eLevel == 0 && !m_level_set) {
+ *eLevel = OMX_VIDEO_AVCLevelMax;
+ }
+
+ if ((*eProfile == OMX_VIDEO_AVCProfileBaseline) ||
+ (*eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline)) {
+ profile_tbl = (unsigned int const *)h264_profile_level_table;
+ } else if ((*eProfile == OMX_VIDEO_AVCProfileHigh) ||
+ (*eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh)) {
+ 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("Unsupported AVC profile type %u", (unsigned int)*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("%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("Unsupported H.263 profile type %u", (unsigned int)*eProfile);
+ return false;
+ }
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ if (*eProfile == 0) {
+ *eProfile = OMX_VIDEO_VP8ProfileMain;
+ } else {
+ switch (codec_profile.profile) {
+ case V4L2_MPEG_VIDC_VIDEO_VP8_UNUSED:
+ *eProfile = OMX_VIDEO_VP8ProfileMain;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("%s(): Unknown VP8 profile", __func__);
+ return false;
+ }
+ }
+ if (*eLevel == 0) {
+ switch (profile_level.level) {
+ case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0:
+ *eLevel = OMX_VIDEO_VP8Level_Version0;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1:
+ *eLevel = OMX_VIDEO_VP8Level_Version1;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("%s(): Unknown VP8 level", __func__);
+ return false;
+ }
+ }
+ return true;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ if (*eProfile == 0) {
+ if (!m_profile_set) {
+ *eProfile = OMX_VIDEO_HEVCProfileMain;
+ } else {
+ switch (codec_profile.profile) {
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
+ *eProfile = OMX_VIDEO_HEVCProfileMain;
+ break;
+ case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
+ *eProfile = OMX_VIDEO_HEVCProfileMain10;
+ break;
+ default:
+ DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
+ return false;
+ }
+ }
+ }
+
+ if (*eLevel == 0 && !m_level_set) {
+ *eLevel = OMX_VIDEO_HEVCLevelMax;
+ }
+
+ if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
+ profile_tbl = (unsigned int const *)hevc_profile_level_table;
+ } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
+ profile_tbl = (unsigned int const *)
+ (&hevc_profile_level_table[HEVC_MAIN10_START]);
+ } else {
+ DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
+ return false;
+ }
+ } else {
+ DEBUG_PRINT_ERROR("Invalid codec type");
+ return false;
+ }
+
+ mb_per_frame = ((m_sVenc_cfg.dvs_height + 15) >> 4)*
+ ((m_sVenc_cfg.dvs_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;
+ }
+ }
+
+ if (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF) {
+ *eLevel = rc_off_level; //No level calculation for RC_OFF
+ profile_level_found = true;
+ return true;
+ }
+
+ mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
+
+ bool h264, ltr, hlayers;
+ unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
+ h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
+ ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
+ hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
+ ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
+
+ /* Hybrid HP reference buffers:
+ layers = 1, 2 need 1 reference buffer
+ layers = 3, 4 need 2 reference buffers
+ layers = 5, 6 need 3 reference buffers
+ */
+
+ if(hier_layers.hier_mode == HIER_P_HYBRID)
+ hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
+
+ 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]) {
+ if (h264 && (ltr || hlayers || hybridp)) {
+ // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
+ new_level = (int)profile_tbl[3];
+ new_profile = (int)profile_tbl[4];
+ profile_level_found = true;
+ DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
+ ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
+ MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
+ break;
+ } else {
+ new_level = (int)profile_tbl[3];
+ new_profile = (int)profile_tbl[4];
+ profile_level_found = true;
+ DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
+ break;
+ }
+ }
+ }
+ }
+ profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
+ } while (profile_tbl[0] != 0);
+
+ if (profile_level_found != true) {
+ DEBUG_PRINT_LOW("ERROR: Unsupported profile/level");
+ return false;
+ }
+
+ if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
+ || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
+ || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
+ *eLevel = new_level;
+ }
+
+ DEBUG_PRINT_LOW("%s: Returning with eProfile = %u"
+ "Level = %u", __func__, (unsigned int)*eProfile, (unsigned int)*eLevel);
+
+ return true;
+}
+#ifdef _ANDROID_ICS_
+bool venc_dev::venc_set_meta_mode(bool mode)
+{
+ metadatamode = mode;
+ 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 = (%lu)x(%lu) supported range = min (%d)x(%d) - max (%d)x(%d)",
+ width, height, capability.min_width, capability.min_height,
+ capability.max_width, capability.max_height);
+ return false;
+ }
+
+ DEBUG_PRINT_LOW("video session supported");
+ return true;
+}
+
+bool venc_dev::venc_set_batch_size(OMX_U32 batchSize)
+{
+ struct v4l2_control control;
+ int ret;
+
+ control.id = V4L2_CID_VIDC_QBUF_MODE;
+ control.value = batchSize ? V4L2_VIDC_QBUF_BATCHED : V4L2_VIDC_QBUF_STANDARD;
+
+ ret = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set batching mode: %d", ret);
+ return false;
+ }
+
+ mBatchSize = batchSize;
+ DEBUG_PRINT_HIGH("Using batch size of %d", mBatchSize);
+ return true;
+}
+
+venc_dev::BatchInfo::BatchInfo()
+ : mNumPending(0) {
+ pthread_mutex_init(&mLock, NULL);
+ for (int i = 0; i < kMaxBufs; ++i) {
+ mBufMap[i] = kBufIDFree;
+ }
+}
+
+int venc_dev::BatchInfo::registerBuffer(int bufferId) {
+ pthread_mutex_lock(&mLock);
+ int availId = 0;
+ for( ; availId < kMaxBufs && mBufMap[availId] != kBufIDFree; ++availId);
+ if (availId >= kMaxBufs) {
+ DEBUG_PRINT_ERROR("Failed to find free entry !");
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
+ mBufMap[availId] = bufferId;
+ mNumPending++;
+ pthread_mutex_unlock(&mLock);
+ return availId;
+}
+
+int venc_dev::BatchInfo::retrieveBufferAt(int v4l2Id) {
+ pthread_mutex_lock(&mLock);
+ if (v4l2Id >= kMaxBufs || v4l2Id < 0) {
+ DEBUG_PRINT_ERROR("Batch: invalid index %d", v4l2Id);
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
+ if (mBufMap[v4l2Id] == kBufIDFree) {
+ DEBUG_PRINT_ERROR("Batch: buffer @ %d was not registered !", v4l2Id);
+ pthread_mutex_unlock(&mLock);
+ return -1;
+ }
+ int bufferId = mBufMap[v4l2Id];
+ mBufMap[v4l2Id] = kBufIDFree;
+ mNumPending--;
+ pthread_mutex_unlock(&mLock);
+ return bufferId;
+}
+
+bool venc_dev::BatchInfo::isPending(int bufferId) {
+ pthread_mutex_lock(&mLock);
+ int existsId = 0;
+ for(; existsId < kMaxBufs && mBufMap[existsId] != bufferId; ++existsId);
+ pthread_mutex_unlock(&mLock);
+ return existsId < kMaxBufs;
+}
+
+int venc_dev::BatchInfo::getFdAt(native_handle_t *hnd, int index) {
+ int fd = hnd && index < hnd->numFds ? hnd->data[index] : -1;
+ return fd;
+}
+
+int venc_dev::BatchInfo::getOffsetAt(native_handle_t *hnd, int index) {
+ int off = hnd && index < hnd->numInts ? hnd->data[hnd->numFds + index] : -1;
+ return off;
+}
+
+int venc_dev::BatchInfo::getSizeAt(native_handle_t *hnd, int index) {
+ int size = hnd && (index + hnd->numFds) < hnd->numInts ?
+ hnd->data[2*hnd->numFds + index] : -1;
+ return size;
+}
+
+int venc_dev::BatchInfo::getUsageAt(native_handle_t *hnd, int index) {
+ int usage = hnd && (index + 2*hnd->numFds) < hnd->numInts ?
+ hnd->data[3*hnd->numFds + index] : 0;
+ return usage;
+}
+
+int venc_dev::BatchInfo::getColorFormatAt(native_handle_t *hnd, int index) {
+ int usage = hnd && (index + 4*hnd->numFds) < hnd->numInts ?
+ hnd->data[5*hnd->numFds + index] : 0;
+ return usage;
+}
+
+int venc_dev::BatchInfo::getTimeStampAt(native_handle_t *hnd, int index) {
+ int size = hnd && (index + 3*hnd->numFds) < hnd->numInts ?
+ hnd->data[4*hnd->numFds + index] : -1;
+ return size;
+}
+
+#ifdef _VQZIP_
+venc_dev::venc_dev_vqzip::venc_dev_vqzip()
+{
+ mLibHandle = NULL;
+ pthread_mutex_init(&lock, NULL);
+}
+
+bool venc_dev::venc_dev_vqzip::init()
+{
+ bool status = true;
+ if (mLibHandle) {
+ DEBUG_PRINT_ERROR("VQZIP init called twice");
+ status = false;
+ }
+ if (status) {
+ mLibHandle = dlopen("libvqzip.so", RTLD_NOW);
+ if (mLibHandle) {
+ mVQZIPInit = (vqzip_init_t)
+ dlsym(mLibHandle,"VQZipInit");
+ mVQZIPDeInit = (vqzip_deinit_t)
+ dlsym(mLibHandle,"VQZipDeInit");
+ mVQZIPComputeStats = (vqzip_compute_stats_t)
+ dlsym(mLibHandle,"VQZipComputeStats");
+ if (!mVQZIPInit || !mVQZIPDeInit || !mVQZIPComputeStats)
+ status = false;
+ } else {
+ DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen libvqzip.so: %s", dlerror());
+ status = false;
+ }
+ if (status) {
+ mVQZIPHandle = mVQZIPInit();
+ }
+ }
+ if (!status && mLibHandle) {
+ dlclose(mLibHandle);
+ mLibHandle = NULL;
+ mVQZIPHandle = NULL;
+ mVQZIPInit = NULL;
+ mVQZIPDeInit = NULL;
+ mVQZIPComputeStats = NULL;
+ }
+ return status;
+}
+
+int venc_dev::venc_dev_vqzip::fill_stats_data(void* pBuf, void* extraData)
+{
+ VQZipStatus result;
+ VQZipStats *pStats = (VQZipStats *)extraData;
+ pConfig.pSEIPayload = NULL;
+ unsigned long size;
+
+ if (!pBuf || !pStats || !mVQZIPHandle) {
+ DEBUG_PRINT_ERROR("Invalid data passed to stats function");
+ }
+ result = mVQZIPComputeStats(mVQZIPHandle, (void* )pBuf, &pConfig, pStats);
+ return result;
+}
+
+void venc_dev::venc_dev_vqzip::deinit()
+{
+ if (mLibHandle) {
+ pthread_mutex_lock(&lock);
+ dlclose(mLibHandle);
+ mVQZIPDeInit(mVQZIPHandle);
+ mLibHandle = NULL;
+ mVQZIPHandle = NULL;
+ mVQZIPInit = NULL;
+ mVQZIPDeInit = NULL;
+ mVQZIPComputeStats = NULL;
+ pthread_mutex_unlock(&lock);
+ }
+}
+
+venc_dev::venc_dev_vqzip::~venc_dev_vqzip()
+{
+ DEBUG_PRINT_HIGH("Destroy C2D instance");
+ if (mLibHandle) {
+ dlclose(mLibHandle);
+ }
+ mLibHandle = NULL;
+ pthread_mutex_destroy(&lock);
+}
+#endif
+
+#ifdef _PQ_
+void venc_dev::venc_try_enable_pq(void)
+{
+ bool rc_mode_supported = false;
+ bool codec_supported = false;
+ bool resolution_supported = false;
+ bool frame_rate_supported = false;
+ bool yuv_format_supported = false;
+ bool is_non_secure_session = false;
+ bool is_pq_handle_valid = false;
+ bool is_non_vpe_session = false;
+ bool enable = false;
+
+ codec_supported = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
+
+ rc_mode_supported = (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR) ||
+ (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_CFR) ||
+ (rate_ctrl.rcmode == V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_MBR_VFR);
+
+ resolution_supported = m_sVenc_cfg.input_height * m_sVenc_cfg.input_width <=
+ m_pq.caps.max_width * m_pq.caps.max_height;
+
+ frame_rate_supported = (m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den) <= MAX_FPS_PQ;
+
+ yuv_format_supported = ((m_sVenc_cfg.inputformat == V4L2_PIX_FMT_NV12 && (m_pq.caps.color_formats & BIT(COLOR_FMT_NV12)))
+ || (m_sVenc_cfg.inputformat == V4L2_PIX_FMT_NV21 && (m_pq.caps.color_formats & BIT(COLOR_FMT_NV21)))
+ || (m_sVenc_cfg.inputformat == V4L2_PIX_FMT_NV12_UBWC && (m_pq.caps.color_formats & BIT(COLOR_FMT_NV12_UBWC))));
+
+ yuv_format_supported |= m_pq.is_YUV_format_uncertain; // When YUV format is uncertain, Let this condition pass
+
+ is_non_secure_session = !venc_handle->is_secure_session();
+
+ is_non_vpe_session = (m_sVenc_cfg.input_height == m_sVenc_cfg.dvs_height && m_sVenc_cfg.input_width == m_sVenc_cfg.dvs_width);
+
+ is_pq_handle_valid = m_pq.is_pq_handle_valid();
+
+ /* Add future PQ conditions here */
+
+ enable = (!is_pq_force_disable &&
+ codec_supported &&
+ rc_mode_supported &&
+ resolution_supported &&
+ frame_rate_supported &&
+ yuv_format_supported &&
+ is_non_secure_session &&
+ is_non_vpe_session &&
+ is_pq_handle_valid);
+
+ DEBUG_PRINT_HIGH("PQ Condition : Force disable = %d Codec = %d, RC = %d, RES = %d, FPS = %d, YUV = %d, Non - Secure = %d, PQ lib = %d Non - VPE = %d PQ enable = %d",
+ is_pq_force_disable, codec_supported, rc_mode_supported, resolution_supported, frame_rate_supported, yuv_format_supported,
+ is_non_secure_session, is_pq_handle_valid, is_non_vpe_session, enable);
+
+ venc_set_extradata(OMX_ExtraDataEncoderOverrideQPInfo, (OMX_BOOL)enable);
+ extradata |= enable;
+
+ m_pq.pConfig.algo = ADAPTIVE_QP;
+ m_pq.pConfig.height = m_sVenc_cfg.input_height;
+ m_pq.pConfig.width = m_sVenc_cfg.input_width;
+ m_pq.pConfig.mb_height = 16;
+ m_pq.pConfig.mb_width = 16;
+ m_pq.pConfig.a_qp.pq_enabled = enable;
+ m_pq.pConfig.stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, m_sVenc_cfg.input_width);
+ m_pq.configure();
+ m_pq.is_pq_enabled = enable;
+
+ return;
+}
+
+venc_dev::venc_dev_pq::venc_dev_pq()
+{
+ mLibHandle = NULL;
+ mPQHandle = NULL;
+ mPQInit = NULL;
+ mPQDeInit = NULL;
+ mPQGetCaps = NULL;
+ mPQConfigure = NULL;
+ mPQComputeStats = NULL;
+ configured_format = 0;
+ pthread_mutex_init(&lock, NULL);
+}
+
+bool venc_dev::venc_dev_pq::init(unsigned long format)
+{
+ bool status = true;
+ enum color_compression_format yuv_format;
+
+ if (mLibHandle) {
+ DEBUG_PRINT_ERROR("PQ init called twice");
+ status = false;
+ }
+
+ switch (format) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ yuv_format = color_compression_format::LINEAR_NV12;
+ break;
+ case V4L2_PIX_FMT_NV12_UBWC:
+ default:
+ yuv_format = color_compression_format::UBWC_NV12;
+ break;
+ }
+
+ if (status) {
+ mLibHandle = dlopen(YUV_STATS_LIBRARY_NAME, RTLD_NOW);
+ if (mLibHandle) {
+ mPQInit = (gpu_stats_lib_init_t)
+ dlsym(mLibHandle,"gpu_stats_lib_init");
+ mPQDeInit = (gpu_stats_lib_deinit_t)
+ dlsym(mLibHandle,"gpu_stats_lib_deinit");
+ mPQGetCaps = (gpu_stats_lib_get_caps_t)
+ dlsym(mLibHandle,"gpu_stats_lib_get_caps");
+ mPQConfigure = (gpu_stats_lib_configure_t)
+ dlsym(mLibHandle,"gpu_stats_lib_configure");
+ mPQComputeStats = (gpu_stats_lib_fill_data_t)
+ dlsym(mLibHandle,"gpu_stats_lib_fill_data");
+ if (!mPQInit || !mPQDeInit || !mPQGetCaps || !mPQConfigure || !mPQComputeStats)
+ status = false;
+ } else {
+ DEBUG_PRINT_ERROR("FATAL ERROR: could not dlopen %s: %s", YUV_STATS_LIBRARY_NAME, dlerror());
+ status = false;
+ }
+ if (status) {
+ mPQInit(&mPQHandle, perf_hint::NORMAL, yuv_format);
+ if (mPQHandle == NULL) {
+ DEBUG_PRINT_ERROR("Failed to get handle for PQ Library");
+ status = false;
+ } else {
+ DEBUG_PRINT_HIGH("GPU PQ lib initialized successfully");
+ }
+
+ }
+ }
+
+ if (!status && mLibHandle) {
+ if (mLibHandle)
+ dlclose(mLibHandle);
+ mLibHandle = NULL;
+ mPQHandle = NULL;
+ mPQInit = NULL;
+ mPQDeInit = NULL;
+ mPQGetCaps = NULL;
+ mPQConfigure = NULL;
+ mPQComputeStats = NULL;
+ }
+ memset(&pConfig, 0, sizeof(gpu_stats_lib_input_config));
+ memset(&roi_extradata_info, 0, sizeof(extradata_buffer_info));
+ roi_extradata_info.size = 16 * 1024; // Max size considering 4k
+ roi_extradata_info.buffer_size = 16 * 1024; // Max size considering 4k
+ roi_extradata_info.port_index = OUTPUT_PORT;
+ is_YUV_format_uncertain = false;
+ configured_format = format;
+
+ return status;
+}
+
+void venc_dev::venc_dev_pq::deinit()
+{
+ if (mLibHandle) {
+ mPQDeInit(mPQHandle);
+ dlclose(mLibHandle);
+ mPQHandle = NULL;
+ mLibHandle = NULL;
+ mPQInit = NULL;
+ mPQDeInit = NULL;
+ mPQGetCaps = NULL;
+ mPQConfigure = NULL;
+ mPQComputeStats = NULL;
+ configured_format = 0;
+ }
+}
+
+bool venc_dev::venc_dev_pq::reinit(unsigned long format)
+{
+ bool status = false;
+
+ if (configured_format != format) {
+ DEBUG_PRINT_HIGH("New format (%lu) is different from configure format (%lu);"
+ " reinitializing PQ lib", format, configured_format);
+ deinit();
+ if (is_color_format_supported(format)) {
+ status = init(format);
+ get_caps();
+ }
+ } else {
+ // ignore if new format is same as configured
+ }
+
+ return status;
+}
+
+void venc_dev::venc_dev_pq::get_caps()
+{
+ memset(&caps, 0, sizeof(gpu_stats_lib_caps_t));
+ if (mPQHandle)
+ mPQGetCaps(mPQHandle, &caps);
+ DEBUG_PRINT_HIGH("GPU lib stats caps max (w,h) = (%u, %u)",caps.max_width, caps.max_height);
+ DEBUG_PRINT_HIGH("GPU lib stats caps max mb per sec = %u",caps.max_mb_per_sec);
+ DEBUG_PRINT_HIGH("GPU lib stats caps color_format = %u",caps.color_formats);
+}
+
+bool venc_dev::venc_dev_pq::is_color_format_supported(unsigned long format)
+{
+ bool support = false;
+ int color_format = -1;
+
+ switch (format) {
+ case V4L2_PIX_FMT_NV12:
+ color_format = COLOR_FMT_NV12;
+ break;
+ case V4L2_PIX_FMT_NV21:
+ color_format = COLOR_FMT_NV21;
+ break;
+ case V4L2_PIX_FMT_NV12_UBWC:
+ color_format = COLOR_FMT_NV12_UBWC;
+ break;
+ case V4L2_PIX_FMT_RGB32:
+ color_format = COLOR_FMT_RGBA8888;
+ break;
+ case V4L2_PIX_FMT_RGBA8888_UBWC:
+ color_format = COLOR_FMT_RGBA8888_UBWC;
+ break;
+ default:
+ color_format = -1;
+ break;
+ }
+
+ if (color_format >= 0) {
+ support = (caps.color_formats & BIT(color_format)) ? true : false;
+ }
+
+ if (support == true)
+ DEBUG_PRINT_HIGH("GPU lib supports this format %lu",format);
+ else
+ DEBUG_PRINT_HIGH("GPU lib doesn't support this format %lu",format);
+
+ return support;
+}
+
+int venc_dev::venc_dev_pq::configure()
+{
+ if (mPQHandle) {
+ pConfig.a_qp.gain = 1.0397;
+ pConfig.a_qp.offset = 14.427;
+ if (pConfig.a_qp.roi_enabled) {
+ pConfig.a_qp.minDeltaQPlimit = -16;
+ pConfig.a_qp.maxDeltaQPlimit = 15;
+ } else {
+ pConfig.a_qp.minDeltaQPlimit = -6;
+ pConfig.a_qp.maxDeltaQPlimit = 9;
+ }
+ return mPQConfigure(mPQHandle, &pConfig);
+ }
+ return -EINVAL;
+}
+
+bool venc_dev::venc_dev_pq::is_pq_handle_valid()
+{
+ return ((mPQHandle) ? true : false);
+}
+
+int venc_dev::venc_dev_pq::fill_pq_stats(struct v4l2_buffer buf,
+ unsigned int data_offset)
+{
+ gpu_stats_lib_buffer_params_t input, output;
+ gpu_stats_lib_buffer_params_t roi_input;
+
+ if (!mPQHandle || !is_pq_enabled) {
+ DEBUG_PRINT_HIGH("Invalid Usage : Handle = %p PQ = %d",
+ mPQHandle, is_pq_enabled);
+ return 0;
+ }
+
+ input.fd = buf.m.planes[0].reserved[0];
+ input.data_offset = buf.m.planes[0].data_offset;
+ input.alloc_len = buf.m.planes[0].length;
+ input.filled_len = buf.m.planes[0].bytesused;
+
+ output.fd = buf.m.planes[1].reserved[0];
+ output.data_offset = buf.m.planes[1].reserved[1]; // This is current Extradata buffer
+ output.data_offset += data_offset; // Offset to start in current buffer
+ output.alloc_len = buf.m.planes[1].reserved[2];
+ output.filled_len = buf.m.planes[1].bytesused;
+
+ DEBUG_PRINT_HIGH("Input fd = %d, data_offset = %d", input.fd, input.data_offset);
+ DEBUG_PRINT_HIGH("Final Output fd = %d, data_offset = %d", output.fd, output.data_offset);
+
+ if (pConfig.a_qp.roi_enabled) {
+ roi_input.fd = roi_extradata_info.ion.fd_ion_data.fd;
+ roi_input.data_offset = 0;
+ roi_input.alloc_len = roi_extradata_info.size;
+ roi_input.filled_len = 0;
+ DEBUG_PRINT_HIGH("ROI fd = %d, offset = %d Length = %d", roi_input.fd, roi_input.data_offset, roi_input.alloc_len);
+ mPQComputeStats(mPQHandle, &input, &roi_input, &output, NULL, NULL);
+ memset(roi_extradata_info.uaddr, 0, roi_extradata_info.size);
+ } else {
+ DEBUG_PRINT_HIGH("Output fd = %d, data_offset = %d", output.fd, output.data_offset);
+ mPQComputeStats(mPQHandle, &input, NULL, &output, NULL, NULL);
+ }
+
+ DEBUG_PRINT_HIGH("PQ data length = %d", output.filled_len);
+ return output.filled_len;
+}
+
+venc_dev::venc_dev_pq::~venc_dev_pq()
+{
+ if (mLibHandle) {
+ mPQDeInit(mPQHandle);
+ dlclose(mLibHandle);
+ }
+ mLibHandle = NULL;
+ mPQHandle = NULL;
+ mPQInit = NULL;
+ mPQDeInit = NULL;
+ mPQGetCaps = NULL;
+ mPQConfigure = NULL;
+ mPQComputeStats = NULL;
+ pthread_mutex_destroy(&lock);
+}
+#endif // _PQ_
diff --git a/msmcobalt/videopp/Android.mk b/msmcobalt/videopp/Android.mk
new file mode 100644
index 0000000..d482cce
--- /dev/null
+++ b/msmcobalt/videopp/Android.mk
@@ -0,0 +1,74 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+ROOT_DIR := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_PATH:= $(ROOT_DIR)
+
+# ---------------------------------------------------------------------------------
+# Common definitons
+# ---------------------------------------------------------------------------------
+
+libOmxVdpp-def := -D__alignx\(x\)=__attribute__\(\(__aligned__\(x\)\)\)
+libOmxVdpp-def += -D__align=__alignx
+libOmxVdpp-def += -Dinline=__inline
+libOmxVdpp-def += -g -O3
+libOmxVdpp-def += -DIMAGE_APPS_PROC
+libOmxVdpp-def += -D_ANDROID_
+libOmxVdpp-def += -DCDECL
+libOmxVdpp-def += -DT_ARM
+libOmxVdpp-def += -DNO_ARM_CLZ
+libOmxVdpp-def += -UENABLE_DEBUG_LOW
+libOmxVdpp-def += -DENABLE_DEBUG_HIGH
+libOmxVdpp-def += -DENABLE_DEBUG_ERROR
+libOmxVdpp-def += -D_ANDROID_ICS_
+libOmxVdpp-def += -UINPUT_BUFFER_LOG
+libOmxVdpp-def += -UOUTPUT_BUFFER_LOG
+libOmxVdpp-def += -DMAX_RES_1080P
+libOmxVdpp-def += -DMAX_RES_1080P_EBI
+
+ifeq ($(TARGET_USES_ION),true)
+libOmxVdpp-def += -DUSE_ION
+endif
+
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+vidpp-inc = $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
+endif
+
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxVdpp)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+LOCAL_PATH:= $(ROOT_DIR)
+
+libmm-vidpp-inc += $(LOCAL_PATH)/inc
+libmm-vidpp-inc += $(OMX_VIDEO_PATH)/vidc/common/inc
+libmm-vidpp-inc += $(QCOM_MEDIA_ROOT)/mm-core/inc
+libmm-vidpp-inc += $(TARGET_OUT_HEADERS)/qcom/display
+libmm-vidpp-inc += frameworks/native/include/media/openmax
+libmm-vidpp-inc += frameworks/native/include/media/hardware
+libmm-vidpp-inc += $(vidpp-inc)
+libmm-vidpp-inc += frameworks/av/include/media/stagefright
+
+LOCAL_MODULE := libOmxVdpp
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libOmxVdpp-def)
+LOCAL_C_INCLUDES += $(libmm-vidpp-inc)
+
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := liblog libutils libbinder libcutils libdl libc
+
+LOCAL_SRC_FILES += src/omx_vdpp.cpp
+
+ifeq ($(TARGET_COMPILE_WITH_MSM_KERNEL),true)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
+endif
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif #BUILD_TINY_ANDROID
+
+# ---------------------------------------------------------------------------------
+# END
+# ---------------------------------------------------------------------------------
diff --git a/msmcobalt/videopp/inc/omx_vdpp.h b/msmcobalt/videopp/inc/omx_vdpp.h
new file mode 100644
index 0000000..b76cea4
--- /dev/null
+++ b/msmcobalt/videopp/inc/omx_vdpp.h
@@ -0,0 +1,949 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2013-2014, 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_VDPP_H__
+#define __OMX_VDPP_H__
+/*============================================================================
+ O p e n M A X Component
+ Video Decoder
+
+*//** @file omx_vdpp.h
+ This module contains the class definition for openMAX video post-processing component.
+
+*//*========================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <cstddef>
+#include <math.h>
+
+#ifdef _ANDROID_
+#define LOG_TAG "OMX-VDPP"
+
+#ifdef USE_ION
+#include <linux/msm_ion.h>
+#endif
+#include <binder/MemoryHeapBase.h>
+#include <ui/ANativeObjectBase.h>
+extern "C"{
+#include <utils/Log.h>
+}
+#include <linux/videodev2.h>
+#include <poll.h>
+#define TIMEOUT 5000
+
+
+#define DEBUG_PRINT_LOW(x, ...) ALOGV("[Entry] "x, ##__VA_ARGS__)
+#define DEBUG_PRINT_HIGH(x, ...) ALOGV("[Step] "x, ##__VA_ARGS__)
+#define DEBUG_PRINT_ERROR(x, ...) ALOGE("[Error] "x, ##__VA_ARGS__)
+
+/*#define DEBUG_PRINT_LOW(x, ...)
+#define DEBUG_PRINT_HIGH(x, ...)
+#define DEBUG_PRINT_ERROR(x, ...) */
+
+#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 <media/hardware/HardwareAPI.h>
+#endif
+
+#include <unistd.h>
+
+#if defined (_ANDROID_ICS_)
+#include <gralloc_priv.h>
+#endif
+
+#include <pthread.h>
+#ifndef PC_DEBUG
+#include <semaphore.h>
+#endif
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "OMX_CoreExt.h"
+#include "OMX_IndexExt.h"
+#include "qc_omx_component.h"
+#include <linux/android_pmem.h>
+#include <dlfcn.h>
+
+#include <media/msm_vpu.h>
+extern "C" {
+ OMX_API void * get_omx_component_factory_fn(void); //used by qc_omx_core
+}
+
+#ifdef _ANDROID_
+ using namespace android;
+#endif // _ANDROID_
+//////////////////////////////////////////////////////////////////////////////
+// Module specific globals
+//////////////////////////////////////////////////////////////////////////////
+#define OMX_SPEC_VERSION 0x00000101
+
+// #define OUTPUT_BUFFER_LOG 1
+// #define INPUT_BUFFER_LOG 1
+//////////////////////////////////////////////////////////////////////////////
+// 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 200//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
+
+#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 VALID_TS(ts) ((ts < LLONG_MAX)? true : false)
+
+/* STATUS CODES */
+/* Base value for status codes */
+#define VDPP_S_BASE 0x40000000
+/* Success */
+#define VDPP_S_SUCCESS (VDPP_S_BASE)
+/* General failure */
+#define VDPP_S_EFAIL (VDPP_S_BASE + 1)
+/* Fatal irrecoverable failure. Need to tear down session. */
+#define VDPP_S_EFATAL (VDPP_S_BASE + 2)
+/* Error detected in the passed parameters */
+#define VDPP_S_EBADPARAM (VDPP_S_BASE + 3)
+/* Command called in invalid state. */
+#define VDPP_S_EINVALSTATE (VDPP_S_BASE + 4)
+ /* Insufficient OS resources - thread, memory etc. */
+#define VDPP_S_ENOSWRES (VDPP_S_BASE + 5)
+ /* Insufficient HW resources - core capacity maxed out. */
+#define VDPP_S_ENOHWRES (VDPP_S_BASE + 6)
+/* Invalid command called */
+#define VDPP_S_EINVALCMD (VDPP_S_BASE + 7)
+/* Command timeout. */
+#define VDPP_S_ETIMEOUT (VDPP_S_BASE + 8)
+/* Pre-requirement is not met for API. */
+#define VDPP_S_ENOPREREQ (VDPP_S_BASE + 9)
+/* Command queue is full. */
+#define VDPP_S_ECMDQFULL (VDPP_S_BASE + 10)
+/* Command is not supported by this driver */
+#define VDPP_S_ENOTSUPP (VDPP_S_BASE + 11)
+/* Command is not implemented by thedriver. */
+#define VDPP_S_ENOTIMPL (VDPP_S_BASE + 12)
+/* Command is not implemented by the driver. */
+#define VDPP_S_BUSY (VDPP_S_BASE + 13)
+#define VDPP_S_INPUT_BITSTREAM_ERR (VDPP_S_BASE + 14)
+
+#define VDPP_INTF_VER 1
+#define VDPP_MSG_BASE 0x0000000
+/* Codes to identify asynchronous message responses and events that driver
+ wants to communicate to the app.*/
+#define VDPP_MSG_INVALID (VDPP_MSG_BASE + 0)
+#define VDPP_MSG_RESP_INPUT_BUFFER_DONE (VDPP_MSG_BASE + 1)
+#define VDPP_MSG_RESP_OUTPUT_BUFFER_DONE (VDPP_MSG_BASE + 2)
+#define VDPP_MSG_RESP_INPUT_FLUSHED (VDPP_MSG_BASE + 3)
+#define VDPP_MSG_RESP_OUTPUT_FLUSHED (VDPP_MSG_BASE + 4)
+#define VDPP_MSG_RESP_FLUSH_INPUT_DONE (VDPP_MSG_BASE + 5)
+#define VDPP_MSG_RESP_FLUSH_OUTPUT_DONE (VDPP_MSG_BASE + 6)
+#define VDPP_MSG_RESP_START_DONE (VDPP_MSG_BASE + 7)
+#define VDPP_MSG_RESP_STOP_DONE (VDPP_MSG_BASE + 8)
+#define VDPP_MSG_RESP_PAUSE_DONE (VDPP_MSG_BASE + 9)
+#define VDPP_MSG_RESP_RESUME_DONE (VDPP_MSG_BASE + 10)
+#define VDPP_MSG_RESP_RESOURCE_LOADED (VDPP_MSG_BASE + 11)
+#define VDPP_EVT_RESOURCES_LOST (VDPP_MSG_BASE + 12)
+#define VDPP_MSG_EVT_CONFIG_CHANGED (VDPP_MSG_BASE + 13)
+#define VDPP_MSG_EVT_HW_ERROR (VDPP_MSG_BASE + 14)
+#define VDPP_MSG_EVT_INFO_CONFIG_CHANGED (VDPP_MSG_BASE + 15)
+#define VDPP_MSG_EVT_INFO_FIELD_DROPPED (VDPP_MSG_BASE + 16)
+
+#define VDPP_MSG_EVT_ACTIVE_REGION_DETECTION_STATUS (VDPP_MSG_BASE + 17)
+
+
+#define VP_INPUT_BUFFER_COUNT_INTERLACE 4
+#define VP_OUTPUT_BUFFER_COUNT 4
+
+#define VDPP_SESSION 1
+//#define STUB_VPU 1
+//#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 vdpp_ion
+{
+ int ion_device_fd;
+ struct ion_fd_data fd_ion_data;
+ struct ion_allocation_data ion_alloc_data;
+};
+#endif
+
+struct extradata_buffer_info {
+ int buffer_size;
+ char* uaddr;
+ int count;
+ int size;
+#ifdef USE_ION
+ struct vdpp_ion ion;
+#endif
+};
+
+struct vdpp_picsize {
+ uint32_t frame_width;
+ uint32_t frame_height;
+ uint32_t stride;
+ uint32_t scan_lines;
+};
+
+enum vdpp_interlaced_format {
+ VDPP_InterlaceFrameProgressive = 0x1,
+ VDPP_InterlaceInterleaveFrameTopFieldFirst = 0x2,
+ VDPP_InterlaceInterleaveFrameBottomFieldFirst = 0x4
+};
+
+enum vdpp_buffer {
+ VDPP_BUFFER_TYPE_INPUT,
+ VDPP_BUFFER_TYPE_OUTPUT
+};
+
+struct vdpp_allocatorproperty {
+ enum vdpp_buffer buffer_type;
+ uint32_t mincount;
+ uint32_t maxcount;
+ uint32_t actualcount;
+ size_t buffer_size;
+ uint32_t alignment;
+ uint32_t buf_poolid;
+ size_t frame_size;
+};
+
+struct vdpp_bufferpayload {
+ void *bufferaddr;
+ size_t buffer_len;
+ int pmem_fd;
+ size_t offset;
+ size_t mmaped_size;
+};
+
+struct vdpp_framesize {
+ uint32_t left;
+ uint32_t top;
+ uint32_t right;
+ uint32_t bottom;
+};
+
+struct vdpp_setbuffer_cmd {
+ enum vdpp_buffer buffer_type;
+ struct vdpp_bufferpayload buffer;
+};
+
+struct vdpp_output_frameinfo {
+ void *bufferaddr;
+ size_t offset;
+ size_t len;
+ uint32_t flags;
+ int64_t time_stamp;
+ void *client_data;
+ struct vdpp_framesize framesize;
+
+};
+
+union vdpp_msgdata {
+ struct v4l2_rect ar_result;
+ struct vdpp_output_frameinfo output_frame;
+ void *input_frame_clientdata;
+};
+
+struct vdpp_msginfo {
+ uint32_t status_code;
+ uint32_t msgcode;
+ union vdpp_msgdata msgdata;
+ size_t msgdatasize;
+};
+
+struct vdpp_framerate {
+ unsigned long fps_denominator;
+ unsigned long fps_numerator;
+};
+
+#ifdef STUB_VPU
+typedef struct vcap_etb_ftb_info
+{
+ int etb_cnt; // only simulate 1-to-1
+ __u32 etb_index;
+ size_t etb_len;
+ int ftb_cnt;
+ __u32 ftb_index;
+ size_t ftb_len;
+}vcap_etb_ftb_info;
+#endif
+
+struct video_vpu_context
+{
+ int video_vpu_fd;
+ uint32_t output_format;
+ enum v4l2_field interlace;
+ struct vdpp_picsize video_resolution_input;
+ struct vdpp_picsize video_resolution_output;
+ struct vdpp_allocatorproperty ip_buf;
+ struct vdpp_allocatorproperty op_buf;
+ struct vdpp_bufferpayload *ptr_inputbuffer;
+ struct vdpp_bufferpayload *ptr_outputbuffer;
+ struct vdpp_output_frameinfo *ptr_respbuffer;
+#ifdef USE_ION
+ struct vdpp_ion *ip_buf_ion_info;
+ struct vdpp_ion *op_buf_ion_info;
+#endif
+ struct vdpp_framerate frame_rate;
+ bool timestamp_adjust;
+ char kind[128];
+ struct extradata_buffer_info extradata_info;
+ int input_num_planes;
+ int output_num_planes;
+ double input_bytesperpixel[2];
+ double output_bytesperpixel[2];
+ int sessionsSupported;
+ int sessionAttached;
+#ifdef STUB_VPU
+ bool thread_exit;
+ vcap_etb_ftb_info etb_ftb_info;
+ sem_t async_lock;
+#endif
+};
+
+typedef struct _VdppExtensionData_t
+{
+ bool activeRegionDetectionDirtyFlag;
+ QOMX_ACTIVEREGIONDETECTIONTYPE activeRegionDetection;
+ bool activeRegionDetectionStatusDirtyFlag;
+ QOMX_ACTIVEREGIONDETECTION_STATUSTYPE activeRegionDetectionStatus;
+ bool scalingModeDirtyFlag;
+ QOMX_SCALINGMODETYPE scalingMode;
+ bool noiseReductionDirtyFlag;
+ QOMX_NOISEREDUCTIONTYPE noiseReduction;
+ bool imageEnhancementDirtyFlag;
+ QOMX_IMAGEENHANCEMENTTYPE imageEnhancement;
+} VdppExtensionData_t;
+
+// OMX video decoder class
+class omx_vdpp: public qc_omx_component
+{
+
+public:
+ omx_vdpp(); // constructor
+ virtual ~omx_vdpp(); // destructor
+
+ static int async_message_process (void *context, void* message);
+ static void process_event_cb(void *ctxt,unsigned char id);
+ 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();
+
+ };
+
+ 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_input_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_vpu_context drv_ctx;
+ int update_resolution(uint32_t width, uint32_t height, uint32_t stride, uint32_t scan_lines);
+
+ int m_pipe_in;
+ int m_pipe_out;
+ int m_ctrl_in;
+ int m_ctrl_out;
+
+ pthread_t msg_thread_id;
+ pthread_t async_thread_id;
+ omx_cmd_queue m_index_q_ftb;
+ omx_cmd_queue m_index_q_etb;
+ bool m_ar_callback_setup;
+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 vidpp component thread context
+ OMX_COMPONENT_GENERATE_EVENT = 0x1,
+ //Buffer Done callbacks from the vidpp component thread context
+ OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2,
+ //Frame Done callbacks from the vidpp component thread context
+ OMX_COMPONENT_GENERATE_FRAME_DONE = 0x3,
+ //Buffer Done callbacks from the vidpp component thread context
+ OMX_COMPONENT_GENERATE_FTB = 0x4,
+ //Frame Done callbacks from the vidpp 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 vidpp 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,
+
+ // extensions
+ OMX_COMPONENT_GENERATE_ACTIVE_REGION_DETECTION_STATUS = 0x18,
+ };
+
+ enum v4l2_ports
+ {
+ CAPTURE_PORT,
+ OUTPUT_PORT,
+ MAX_PORT
+ };
+
+#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
+
+ 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);
+ 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);
+
+ 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 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(vdpp_allocatorproperty *buffer_prop);
+ OMX_ERRORTYPE set_buffer_req(vdpp_allocatorproperty *buffer_prop);
+ OMX_ERRORTYPE start_port_reconfig();
+
+ int stream_off(OMX_U32 port);
+ void adjust_timestamp(OMX_S64 &act_timestamp);
+ void set_frame_rate(OMX_S64 act_timestamp);
+ OMX_ERRORTYPE enable_extradata(OMX_U32 requested_extradata, bool enable = true);
+ OMX_ERRORTYPE update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn);
+ 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 vdpp_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
+ );
+
+ void setFormatParams(int pixelFormat, double bytesperpixel[], unsigned char *planesCount);
+
+ int openInput(const char* inputName);
+
+ /**
+ * int clip2 - return an integer value in 2 to the nth power
+ * legacy code from video decoder (rounded up till 256)
+ *
+ */
+ 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;
+ }
+ /**
+ * int paddedFrameWidth - return frame width in a multiple of 128 (rounded up).
+ *
+ * @width - the original frame width.
+ */
+ inline int paddedFrameWidth128(int width)
+ {
+ return (((width + 127) / 128 )* 128);
+ }
+
+ /**
+ * int paddedFrameWidth32 - return frame width in a multiple of 32 (rounded up).
+ *
+ * @width - the original frame width.
+ */
+ inline int paddedFrameWidth32(int width)
+ {
+ return (((width + 31) / 32 )* 32);
+ }
+
+ /**
+ * int roundToNearestInt - round to nearest integer value.
+ *
+ * @value - the decimal value to be rounded to nearest integer.
+ */
+ inline int roundToNearestInt(double value)
+ {
+ if((ceil(value) - value) > 0.5)
+ return floor(value);
+ else
+ return ceil(value);
+ }
+
+ 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);
+ }
+ }
+
+#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;
+ //sem to handle the minimum procesing of commands
+ sem_t m_cmd_lock;
+ bool m_error_propogated;
+
+ // 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;
+
+ int input_qbuf_count;
+ int input_dqbuf_count;
+ int output_qbuf_count;
+ int output_dqbuf_count;
+
+#ifdef OUTPUT_BUFFER_LOG
+ int output_buffer_write_counter;
+ int input_buffer_write_counter;
+#endif
+ // 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;
+
+ // 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;
+
+ /*Variables for arbitrary Byte parsing support*/
+ omx_cmd_queue m_input_pending_q;
+ omx_cmd_queue m_input_free_q;
+
+ 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;
+
+ OMX_S64 prev_ts;
+ bool rst_prev_ts;
+ OMX_U32 frm_int;
+
+ struct vdpp_allocatorproperty op_buf_rcnfg;
+ bool in_reconfig;
+ OMX_U32 client_extradata;
+#ifdef _ANDROID_
+ bool m_debug_timestamp;
+ bool perf_flag;
+ OMX_U32 proc_frms, latency;
+ bool m_enable_android_native_buffers;
+ bool m_use_android_native_buffers;
+ bool m_debug_extradata;
+ bool m_debug_concealedmb;
+#endif
+
+ OMX_PARAM_PORTDEFINITIONTYPE m_port_def;
+
+ int capture_capability;
+ int output_capability;
+ bool streaming[MAX_PORT];
+ OMX_CONFIG_RECTTYPE rectangle;
+ int prev_n_filled_len;
+
+ bool msg_thread_created;
+ bool async_thread_created;
+
+ unsigned int m_fill_output_msg;
+ bool client_set_fps;
+ bool interlace_user_flag;
+ // OMX extensions
+ VdppExtensionData_t mExtensionData;
+};
+#endif // __OMX_VDPP_H__
diff --git a/msmcobalt/videopp/src/omx_vdpp.cpp b/msmcobalt/videopp/src/omx_vdpp.cpp
new file mode 100644
index 0000000..390c37e
--- /dev/null
+++ b/msmcobalt/videopp/src/omx_vdpp.cpp
@@ -0,0 +1,7595 @@
+/*---------------------------------------------------------------------------------------
+Copyright (c) 2013-2015, 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_vdpp.cpp
+ This module contains the implementation of the OpenMAX video post-processing component.
+
+*//*========================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+#define LOG_NDEBUG 0
+#include <string.h>
+#include <pthread.h>
+#include <sys/prctl.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include "omx_vdpp.h"
+#include <fcntl.h>
+#include <limits.h>
+#include <media/msm_media_info.h>
+
+#ifndef _ANDROID_
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#endif //_ANDROID_
+
+#ifdef _ANDROID_
+#include <cutils/properties.h>
+#undef USE_EGL_IMAGE_GPU
+#endif
+
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+#include <gralloc_priv.h>
+#endif
+
+#ifdef INPUT_BUFFER_LOG
+int inputBufferFile;
+char inputfilename[] = "/sdcard/input-bitstream";
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+int outputBufferFile;
+char outputfilename[] = "/sdcard/output.yuv";
+#endif
+#ifdef OUTPUT_EXTRADATA_LOG
+FILE *outputExtradataFile;
+char ouputextradatafilename[] = "/data/extradata";
+#endif
+
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#ifdef _ANDROID_
+ extern "C"{
+ #include<utils/Log.h>
+ }
+#endif//_ANDROID_
+
+#define POLL_TIMEOUT 0x7fffffff //10000//
+#define MEM_DEVICE "/dev/ion"
+#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
+
+#define DEFAULT_FPS 30
+#define MAX_INPUT_ERROR DEFAULT_FPS
+#define MAX_SUPPORTED_FPS 120
+
+#define SZ_4K 0x1000
+
+#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)
+
+#ifndef STUB_VPU
+void* async_message_thread (void *input)
+{
+ int extra_idx = 0;
+ int rc = 0;
+ OMX_BUFFERHEADERTYPE *buffer;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ struct pollfd pfd[2];
+ struct v4l2_buffer v4l2_buf;
+ struct v4l2_event dqevent;
+ omx_vdpp *omx = reinterpret_cast<omx_vdpp*>(input);
+ pfd[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
+ pfd[0].fd = omx->drv_ctx.video_vpu_fd;
+ pfd[1].events = POLLIN | POLLPRI | POLLERR;
+ pfd[1].fd = omx->m_ctrl_in;
+
+ memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
+ DEBUG_PRINT_LOW("omx_vdpp: Async thread start\n");
+ prctl(PR_SET_NAME, (unsigned long)"VdppCallBackThread", 0, 0, 0);
+ while (1)
+ {
+ rc = poll(pfd, 2, POLL_TIMEOUT);
+
+ if (!rc) {
+ DEBUG_PRINT_HIGH("Poll timedout\n");
+ break; // no input buffers EOS reached
+ } else if (rc < 0) {
+ DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
+ break;
+ }
+ //DEBUG_PRINT_LOW("async_message_thread 1 POLL_TIMEOUT = 0x%x", POLL_TIMEOUT);
+
+ if (pfd[1].revents & (POLLIN | POLLPRI | POLLERR))
+ {
+ DEBUG_PRINT_HIGH("pipe event, exit async thread");
+ break;
+ }
+
+ // output buffer ready for fbd
+ if ((pfd[0].revents & POLLIN) || (pfd[0].revents & POLLRDNORM)) {
+ //DEBUG_PRINT_LOW("async_message_thread 1\n");
+ struct vdpp_msginfo vdpp_msg;
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ v4l2_buf.memory = V4L2_MEMORY_USERPTR;
+ v4l2_buf.length = omx->drv_ctx.output_num_planes;
+ v4l2_buf.m.planes = plane;
+ while(!ioctl(pfd[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
+ DEBUG_PRINT_LOW("async_message_thread 2\n");
+ vdpp_msg.msgcode=VDPP_MSG_RESP_OUTPUT_BUFFER_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ vdpp_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
+
+ // driver returns ION buffer address, but case VDPP_MSG_RESP_OUTPUT_BUFFER_DONE
+ // will pass mmaped address to upper layer, and then driver sets it when returnning
+ // DQBUF for output buffers.
+ extra_idx = EXTRADATA_IDX(omx->drv_ctx.output_num_planes);
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ // this len is used in fill_buffer_done buffer->nFilledLen
+ // is different from FTBProxy plane[0].length
+ vdpp_msg.msgdata.output_frame.len= v4l2_buf.m.planes[0].bytesused + v4l2_buf.m.planes[extra_idx].bytesused;
+ //DEBUG_PRINT_HIGH("async_message_thread 2.5 omx->drv_ctx.op_buf.buffer_size = %d, plane[0].bytesused = %d, plane[%d].bytesused = %d\n", omx->drv_ctx.op_buf.buffer_size, v4l2_buf.m.planes[0].bytesused, extra_idx, v4l2_buf.m.planes[extra_idx].bytesused);
+ }
+ else {
+ vdpp_msg.msgdata.output_frame.len=v4l2_buf.m.planes[0].bytesused;
+ //DEBUG_PRINT_HIGH("async_message_thread 2.5 - 2 plane[0].bytesused = %d\n", v4l2_buf.m.planes[0].bytesused);
+ }
+ vdpp_msg.msgdata.output_frame.bufferaddr=(void*)v4l2_buf.m.planes[0].m.userptr;
+
+ // currently V4L2 driver just passes timestamp to maple FW, and maple FW
+ // pass the timestamp back to OMX
+ vdpp_msg.msgdata.output_frame.time_stamp = *(uint64_t *)(&v4l2_buf.timestamp);
+
+ //DEBUG_PRINT_HIGH("async_message_thread 2.6.0 v4l2_buf.timestamp.tv_sec = 0x%08lx, v4l2_buf.timestamp.tv_usec = 0x%08lx\n", v4l2_buf.timestamp.tv_sec, v4l2_buf.timestamp.tv_usec);
+ if (omx->async_message_process(input,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH(" async_message_thread Exited \n");
+ break;
+ }
+ }
+ }
+ // input buffer ready for empty buffer done (ebd)
+ if((pfd[0].revents & POLLOUT) || (pfd[0].revents & POLLWRNORM)) {
+ struct vdpp_msginfo vdpp_msg;
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ v4l2_buf.memory = V4L2_MEMORY_USERPTR;
+ v4l2_buf.length = omx->drv_ctx.input_num_planes;
+ v4l2_buf.m.planes = plane;
+ DEBUG_PRINT_LOW("async_message_thread 3\n");
+ while(!ioctl(pfd[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
+ vdpp_msg.msgcode=VDPP_MSG_RESP_INPUT_BUFFER_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ vdpp_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
+
+ extra_idx = EXTRADATA_IDX(omx->drv_ctx.input_num_planes);
+ if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
+ vdpp_msg.msgdata.output_frame.len=v4l2_buf.m.planes[0].bytesused + v4l2_buf.m.planes[extra_idx].bytesused; // user doesn't need this for ebd, just set in case is used
+ //DEBUG_PRINT_HIGH("async_message_thread 3.5 plane[0].bytesused = %d, plane[extra_idx].bytesused = %d\n", v4l2_buf.m.planes[0].bytesused, v4l2_buf.m.planes[extra_idx].bytesused);
+ }
+ else {
+ vdpp_msg.msgdata.output_frame.len=v4l2_buf.m.planes[0].bytesused;
+ //DEBUG_PRINT_HIGH("async_message_thread 3.5 - 2 plane[0].bytesused = %d\n", v4l2_buf.m.planes[0].bytesused);
+ }
+ if (omx->async_message_process(input,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH(" async_message_thread Exited \n");
+ break;
+ }
+ }
+ }
+ if (pfd[0].revents & POLLPRI){
+ DEBUG_PRINT_HIGH("async_message_thread 4\n");
+ memset(&dqevent, 0, sizeof(struct v4l2_event));
+ rc = ioctl(pfd[0].fd, VIDIOC_DQEVENT, &dqevent);
+ if(dqevent.type == VPU_EVENT_HW_ERROR)
+ {
+ struct vdpp_msginfo vdpp_msg;
+ vdpp_msg.msgcode=VDPP_MSG_EVT_HW_ERROR;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ DEBUG_PRINT_HIGH(" SYS Error Recieved \n");
+ if (omx->async_message_process(input,&vdpp_msg) < 0)
+ {
+ DEBUG_PRINT_HIGH(" async_message_thread Exited \n");
+ break;
+ }
+ }
+ else if (dqevent.type == VPU_EVENT_FLUSH_DONE) {
+ struct vdpp_msginfo vdpp_msg;
+ enum v4l2_buf_type buf_type;
+ memcpy(&buf_type, dqevent.u.data, sizeof(buf_type));
+ if(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == buf_type)
+ {
+ vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_INPUT_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ DEBUG_PRINT_HIGH("VDPP Input Flush Done Recieved \n");
+ if (omx->async_message_process(input,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
+ break;
+ }
+ }
+ else if(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type)
+ {
+ vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_OUTPUT_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ DEBUG_PRINT_HIGH("VDPP Output Flush Done Recieved \n");
+ if (omx->async_message_process(input,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH("\n async_message_thread Exited \n");
+ break;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH(" Wrong buf_type recieved %d\n", buf_type);
+ }
+ }
+ else if(dqevent.type == VPU_EVENT_ACTIVE_REGION_CHANGED)
+ {
+ DEBUG_PRINT_HIGH(" VPU_EVENT_ACTIVE_REGION_CHANGED\n");
+ struct vdpp_msginfo vdpp_msg;
+ vdpp_msg.msgcode=VDPP_MSG_EVT_ACTIVE_REGION_DETECTION_STATUS;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+
+ // get the active region dection result struct from the event associated data
+ memcpy(&vdpp_msg.msgdata.ar_result, dqevent.u.data, sizeof(v4l2_rect));
+ DEBUG_PRINT_HIGH(" VPU_EVENT_ACTIVE_REGION_CHANGED Recieved \n");
+ if(omx->m_ar_callback_setup)
+ {
+ if (omx->async_message_process(input,&vdpp_msg) < 0)
+ {
+ DEBUG_PRINT_HIGH(" async_message_thread Exited \n");
+ break;
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH(" VPU Some Event recieved \n");
+ continue;
+ }
+
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdpp: Async thread stop\n");
+ return NULL;
+}
+#else // use stub to simulate vpu events for now
+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_vdpp *omx = reinterpret_cast<omx_vdpp*>(input);
+
+ pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
+ pfd.fd = omx->drv_ctx.video_vpu_fd;
+ int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
+ DEBUG_PRINT_HIGH("omx_vdpp: Async thread start\n");
+ prctl(PR_SET_NAME, (unsigned long)"VdppCallBackThread", 0, 0, 0);
+ while (1)
+ {
+ DEBUG_PRINT_HIGH("omx_vdpp: Async thread start 0\n");
+ sem_wait(&(omx->drv_ctx.async_lock));
+ DEBUG_PRINT_HIGH("omx_vdpp: Async thread start pfd.revents = %d\n", pfd.revents);
+ if ((omx->drv_ctx.etb_ftb_info.ftb_cnt > 0))
+ {
+ DEBUG_PRINT_LOW("async_message_thread 1 omx->drv_ctx.etb_ftb_info.ftb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.ftb_cnt);
+ struct vdpp_msginfo vdpp_msg;
+ unsigned p1 = 0;
+ unsigned p2 = 0;
+ unsigned ident = 0;
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ v4l2_buf.memory = V4L2_MEMORY_USERPTR;
+ omx->m_index_q_ftb.pop_entry(&p1,&p2,&ident);
+ v4l2_buf.index = ident;
+ v4l2_buf.bytesused = omx->drv_ctx.etb_ftb_info.ftb_len;
+ omx->drv_ctx.etb_ftb_info.ftb_cnt--;
+ DEBUG_PRINT_HIGH("async_message_thread 1.5 omx->drv_ctx.etb_ftb_info.ftb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.ftb_cnt);
+ /*while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) */{
+ DEBUG_PRINT_LOW("async_message_thread 2\n", rc);
+ vdpp_msg.msgcode=VDPP_MSG_RESP_OUTPUT_BUFFER_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ vdpp_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
+ vdpp_msg.msgdata.output_frame.len=v4l2_buf.bytesused;
+ vdpp_msg.msgdata.output_frame.bufferaddr=(void*)v4l2_buf.m.userptr;
+
+ vdpp_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
+ (uint64_t)v4l2_buf.timestamp.tv_usec;
+ if (omx->async_message_process(input,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH(" async_message_thread Exited \n");
+ break;
+ }
+ }
+ }
+ if(omx->drv_ctx.etb_ftb_info.etb_cnt > 0) {
+ struct vdpp_msginfo vdpp_msg;
+ unsigned p1 = 0;
+ unsigned p2 = 0;
+ unsigned ident = 0;
+ v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ v4l2_buf.memory = V4L2_MEMORY_USERPTR;
+
+ omx->m_index_q_etb.pop_entry(&p1,&p2,&ident);
+ v4l2_buf.index = ident;
+ DEBUG_PRINT_LOW("async_message_thread 3 omx->drv_ctx.etb_ftb_info.etb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.etb_cnt);
+ omx->drv_ctx.etb_ftb_info.etb_cnt--;
+ DEBUG_PRINT_LOW("async_message_thread 4 omx->drv_ctx.etb_ftb_info.etb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.etb_cnt);
+
+ /*while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf))*/ {
+ vdpp_msg.msgcode=VDPP_MSG_RESP_INPUT_BUFFER_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ vdpp_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
+ if (omx->async_message_process(input,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH(" async_message_thread Exited \n");
+ break;
+ }
+ }
+ }
+
+ if(omx->drv_ctx.thread_exit)
+ {
+ break;
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdpp: Async thread stop\n");
+ return NULL;
+}
+#endif
+
+void* message_thread(void *input)
+{
+ omx_vdpp* omx = reinterpret_cast<omx_vdpp*>(input);
+ unsigned char id;
+ int n;
+
+ DEBUG_PRINT_LOW("omx_vdpp: message thread start\n");
+ prctl(PR_SET_NAME, (unsigned long)"VideoPostProcessingMsgThread", 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("ERROR: read from pipe failed, ret %d errno %d", n, errno);
+ break;
+ }
+ }
+ DEBUG_PRINT_HIGH("omx_vdpp: message thread stop\n");
+ return 0;
+}
+
+void post_message(omx_vdpp *omx, unsigned char id)
+{
+ int ret_value;
+ //DEBUG_PRINT_LOW("omx_vdpp: post_message %d pipe out 0x%x\n", id,omx->m_pipe_out);
+ ret_value = write(omx->m_pipe_out, &id, 1);
+ //DEBUG_PRINT_HIGH("post_message to pipe done %d\n",ret_value);
+}
+
+// omx_cmd_queue destructor
+omx_vdpp::omx_cmd_queue::~omx_cmd_queue()
+{
+ // Nothing to do
+}
+
+// omx cmd queue constructor
+omx_vdpp::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_vdpp::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_vdpp::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_vdpp::omx_cmd_queue::get_q_msg_type()
+{
+ return m_q[m_read].id;
+}
+
+#ifdef _ANDROID_
+omx_vdpp::ts_arr_list::ts_arr_list()
+{
+ //initialize timestamps array
+ memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
+}
+omx_vdpp::ts_arr_list::~ts_arr_list()
+{
+ //free m_ts_arr_list?
+}
+
+bool omx_vdpp::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_vdpp::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_vdpp::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_vdpp);
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::omx_vdpp
+
+DESCRIPTION
+ Constructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_vdpp::omx_vdpp(): m_ar_callback_setup(false),
+ 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),
+ input_qbuf_count(0),
+ input_dqbuf_count(0),
+ output_qbuf_count(0),
+ output_dqbuf_count(0),
+#ifdef OUTPUT_BUFFER_LOG
+ output_buffer_write_counter(0),
+ input_buffer_write_counter(0),
+#endif
+ 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_in_alloc_cnt(0),
+ m_platform_list(NULL),
+ m_platform_entry(NULL),
+ m_pmem_info(NULL),
+ psource_frame (NULL),
+ pdest_frame (NULL),
+ m_inp_heap_ptr (NULL),
+ m_phdr_pmem_ptr(NULL),
+ m_heap_inp_bm_count (0),
+ prev_ts(LLONG_MAX),
+ rst_prev_ts(true),
+ frm_int(0),
+ in_reconfig(false),
+ client_extradata(0),
+ m_enable_android_native_buffers(OMX_FALSE),
+ m_use_android_native_buffers(OMX_FALSE),
+ client_set_fps(false),
+ interlace_user_flag(false)
+{
+ DEBUG_PRINT_LOW("In OMX vdpp Constructor");
+
+ memset(&m_cmp,0,sizeof(m_cmp));
+ memset(&m_cb,0,sizeof(m_cb));
+ memset (&drv_ctx,0,sizeof(drv_ctx));
+ 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
+
+ drv_ctx.timestamp_adjust = false;
+ drv_ctx.video_vpu_fd = -1;
+ pthread_mutex_init(&m_lock, NULL);
+ sem_init(&m_cmd_lock,0,0);
+ streaming[CAPTURE_PORT] = false;
+ streaming[OUTPUT_PORT] = false;
+
+ m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
+
+#ifdef STUB_VPU
+ drv_ctx.thread_exit = false;
+ sem_init(&(drv_ctx.async_lock),0,0);
+#endif
+}
+
+static OMX_ERRORTYPE subscribe_to_events(int fd)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ struct v4l2_event_subscription sub;
+ int rc;
+ if (fd < 0) {
+ DEBUG_PRINT_ERROR("Invalid input: %d\n", fd);
+ return OMX_ErrorBadParameter;
+ }
+
+#ifndef STUB_VPU
+ sub.type = V4L2_EVENT_ALL;
+ rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
+ if (rc < 0)
+ {
+ DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x\n", sub.type);
+ eRet = OMX_ErrorNotImplemented;
+ }
+#endif
+
+ return eRet;
+}
+
+
+static OMX_ERRORTYPE unsubscribe_to_events(int fd)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ struct v4l2_event_subscription sub;
+
+ int rc;
+ if (fd < 0) {
+ DEBUG_PRINT_ERROR("Invalid input: %d\n", fd);
+ return OMX_ErrorBadParameter;
+ }
+
+#ifndef STUB_VPU
+ memset(&sub, 0, sizeof(sub));
+ sub.type = V4L2_EVENT_ALL;
+ rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x\n", sub.type);
+ }
+#endif
+
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::~omx_vdpp
+
+DESCRIPTION
+ Destructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_vdpp::~omx_vdpp()
+{
+ m_pmem_info = NULL;
+ DEBUG_PRINT_HIGH("In OMX vdpp 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");
+
+#ifdef STUB_VPU
+ DEBUG_PRINT_HIGH("drv_ctx.etb_ftb_info.ftb_cnt = %d, drv_ctx.etb_ftb_info.etb_cnt = %d", drv_ctx.etb_ftb_info.ftb_cnt, drv_ctx.etb_ftb_info.etb_cnt);
+ drv_ctx.etb_ftb_info.ftb_cnt = 0;
+ drv_ctx.etb_ftb_info.etb_cnt = 0;
+ sem_post (&(drv_ctx.async_lock));
+ drv_ctx.thread_exit = true;
+#endif
+ // notify async thread to exit
+ DEBUG_PRINT_LOW("write control pipe to notify async thread to exit");
+ write(m_ctrl_out, "1", 1);
+
+ if (async_thread_created)
+ pthread_join(async_thread_id,NULL);
+ DEBUG_PRINT_HIGH("async_thread exits");
+ unsubscribe_to_events(drv_ctx.video_vpu_fd);
+ close(drv_ctx.video_vpu_fd);
+ pthread_mutex_destroy(&m_lock);
+ sem_destroy(&m_cmd_lock);
+
+#ifdef STUB_VPU
+ sem_destroy(&(drv_ctx.async_lock));
+#endif
+ if(m_ctrl_in) close(m_ctrl_in);
+ if(m_ctrl_out) close(m_ctrl_out);
+ m_ctrl_in = -1;
+ m_ctrl_out = -1;
+ DEBUG_PRINT_HIGH("Exit OMX vdpp Destructor");
+}
+
+int release_buffers(omx_vdpp* obj, enum vdpp_buffer buffer_type) {
+ struct v4l2_requestbuffers bufreq;
+ int rc = 0;
+#ifndef STUB_VPU
+ if (buffer_type == VDPP_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_vpu_fd,VIDIOC_REQBUFS, &bufreq);
+ }else if(buffer_type == VDPP_BUFFER_TYPE_INPUT) {
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = 0;
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ rc = ioctl(obj->drv_ctx.video_vpu_fd,VIDIOC_REQBUFS, &bufreq);
+ }
+#endif
+ return rc;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::process_event_cb
+
+DESCRIPTION
+ IL Client callbacks are generated through this routine. The VDPP
+ 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_vdpp::process_event_cb(void *ctxt, unsigned char id)
+{
+ signed p1; // Parameter - 1
+ signed p2; // Parameter - 2
+ unsigned ident;
+ unsigned qsize=0; // qsize
+ omx_vdpp *pThis = (omx_vdpp *) 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);
+
+ // first check command queue
+ qsize = pThis->m_cmd_q.m_size;
+ if(qsize)
+ {
+ pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
+ //DEBUG_PRINT_HIGH("process_event_cb m_cmd_q.pop_entry ident = %d", ident);
+ }
+
+ // then check ftb queue
+ 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);
+ DEBUG_PRINT_HIGH("process_event_cb, p1 = 0x%08x, p2 = 0x%08x, ident = 0x%08x", p1, p2, ident);
+ }
+ }
+
+ // last check etb queue
+ 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(" OMX_CommandStateSet complete, m_state = %d, pThis->m_cb.EventHandler = %p",
+ pThis->m_state, pThis->m_cb.EventHandler);
+ 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(" 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(" OMX_CommandPortDisable complete for port [%d], pThis->in_reconfig = %d", p2, pThis->in_reconfig);
+ 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, VDPP_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;
+ }
+ }
+ if (p2 == OMX_CORE_INPUT_PORT_INDEX)
+ {
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX);
+ if(release_buffers(pThis, VDPP_BUFFER_TYPE_INPUT))
+ DEBUG_PRINT_HIGH("Failed to release output buffers\n");
+ OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.ip_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(" 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;
+ break;
+ case OMX_COMPONENT_GENERATE_ETB:
+ if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR(" empty_this_buffer_proxy failure");
+ pThis->omx_report_error ();
+ }
+ break;
+
+ case OMX_COMPONENT_GENERATE_FTB:
+ {
+ DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_FTB p2 = 0x%08x", p2);
+ if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
+ (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR(" 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 != VDPP_S_SUCCESS && p2 != VDPP_S_INPUT_BITSTREAM_ERR)
+ {
+ DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_EBD failure");
+ pThis->omx_report_error ();
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_EBD 1");
+ if (p2 == VDPP_S_INPUT_BITSTREAM_ERR && p1)
+ {
+ pThis->m_inp_err_count++;
+ DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_EBD 2");
+ //pThis->time_stamp_dts.remove_time_stamp(
+ //((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
+ //(pThis->drv_ctx.interlace != VDPP_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(" empty_buffer_done failure");
+ pThis->omx_report_error ();
+ }
+ DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EBD 4");
+ if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
+ {
+ DEBUG_PRINT_ERROR(" Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
+ pThis->omx_report_error ();
+ }
+ }
+ break;
+ case OMX_COMPONENT_GENERATE_FBD:
+ if (p2 != VDPP_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR(" 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(" 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(" WARNING: Unexpected flush from driver");
+ }
+ else
+ {
+ pThis->execute_input_flush();
+ if (pThis->m_cb.EventHandler)
+ {
+ if (p2 != VDPP_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR("OMX_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->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR(" Failed to call streamoff on OUTPUT Port \n");
+ pThis->omx_report_error ();
+ } else {
+ DEBUG_PRINT_HIGH(" Successful to call streamoff on OUTPUT Port \n");
+ pThis->streaming[OUTPUT_PORT] = false;
+ }
+ if (!pThis->output_flush_progress)
+ {
+ DEBUG_PRINT_LOW(" Input flush done hence issue stop");
+ pThis->post_event ((unsigned int)NULL, VDPP_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(" Driver flush o/p Port complete");
+ if (!pThis->output_flush_progress)
+ {
+ DEBUG_PRINT_ERROR(" WARNING: Unexpected flush from driver");
+ }
+ else
+ {
+ pThis->execute_output_flush();
+ if (pThis->m_cb.EventHandler)
+ {
+ if (p2 != VDPP_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR(" 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);
+
+ }
+ }
+
+ DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH 1 \n");
+
+ if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
+ {
+ DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH 2 \n");
+ if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
+ DEBUG_PRINT_ERROR(" Failed to call streamoff on CAPTURE Port \n");
+ pThis->omx_report_error ();
+ break;
+ }
+ pThis->streaming[CAPTURE_PORT] = false;
+ DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH 3 pThis->input_flush_progress =%d \n", pThis->input_flush_progress);
+ if (!pThis->input_flush_progress)
+ {
+ DEBUG_PRINT_LOW(" Output flush done hence issue stop");
+ pThis->post_event ((unsigned int)NULL, VDPP_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(" Rxd OMX_COMPONENT_GENERATE_START_DONE");
+
+ if (pThis->m_cb.EventHandler)
+ {
+ if (p2 != VDPP_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR(" 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_vpu_fd,
+ VDPP_IOCTL_CMD_PAUSE,NULL ) < */0)
+ {
+ DEBUG_PRINT_ERROR(" VDPP_IOCTL_CMD_PAUSE failed");
+ pThis->omx_report_error ();
+ }
+ }
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_LOW(" 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 != VDPP_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 != VDPP_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR(" 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 VDPP 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 != VDPP_S_SUCCESS)
+ {
+ DEBUG_PRINT_ERROR(" 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 = %p", pThis->m_cb.EventHandler);
+ pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
+ OMX_EventCmdComplete,OMX_CommandStateSet,
+ OMX_StateIdle,NULL);
+ DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_STOP_DONE cb finished");
+ }
+ }
+ }
+ 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 (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 != V4L2_FIELD_NONE/*VDPP_InterlaceFrameProgressive*/)
+ {
+ OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
+ OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
+ if (pThis->drv_ctx.interlace == V4L2_FIELD_INTERLACED_TB/*VDPP_InterlaceInterleaveFrameTopFieldFirst*/)
+ format = OMX_InterlaceInterleaveFrameTopFieldFirst;
+ else if (pThis->drv_ctx.interlace == V4L2_FIELD_INTERLACED_BT/*VDPP_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(" OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
+ pThis->omx_report_error ();
+ break;
+
+ case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
+ DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
+ pThis->omx_report_unsupported_setting();
+ 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__);
+ }
+ }
+ // extensions
+ case OMX_COMPONENT_GENERATE_ACTIVE_REGION_DETECTION_STATUS:
+ {
+ struct v4l2_rect * ar_result = (struct v4l2_rect *) p1;
+ QOMX_ACTIVEREGIONDETECTION_STATUSTYPE arstatus;
+ arstatus.nSize = sizeof(QOMX_ACTIVEREGIONDETECTION_STATUSTYPE);
+ arstatus.nPortIndex = 0;
+ arstatus.bDetected = OMX_TRUE;
+ memcpy(&arstatus.sDetectedRegion, ar_result, sizeof(QOMX_RECTTYPE));
+ DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_ACTIVE_REGION_DETECTION_STATUS");
+ // data2 should be (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetectionStatus
+ // pdata should be QOMX_ACTIVEREGIONDETECTION_STATUSTYPE
+ 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, (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetectionStatus, &arstatus);
+ } 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_vdpp::update_resolution(uint32_t width, uint32_t height, uint32_t stride, uint32_t scan_lines)
+{
+ int format_changed = 0;
+ if ((height != drv_ctx.video_resolution_input.frame_height) ||
+ (width != drv_ctx.video_resolution_input.frame_width)) {
+ DEBUG_PRINT_HIGH("NOTE: W/H %d (%d), %d (%d)\n",
+ width, drv_ctx.video_resolution_input.frame_width,
+ height,drv_ctx.video_resolution_input.frame_height);
+ format_changed = 1;
+ }
+ drv_ctx.video_resolution_input.frame_height = height;
+ drv_ctx.video_resolution_input.frame_width = width;
+ drv_ctx.video_resolution_input.scan_lines = scan_lines;
+ drv_ctx.video_resolution_input.stride = stride;
+ rectangle.nLeft = 0;
+ rectangle.nTop = 0;
+ rectangle.nWidth = drv_ctx.video_resolution_input.frame_width;
+ rectangle.nHeight = drv_ctx.video_resolution_input.frame_height;
+ return format_changed;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::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_vdpp::component_init(OMX_STRING role)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ struct v4l2_format fmt;
+ int fds[2];
+ int fctl[2];
+ int ret=0;
+ int i = 0;
+ int sessionNum = 0;
+
+ errno = 0;
+
+#ifndef STUB_VPU
+ drv_ctx.video_vpu_fd = openInput("msm_vpu");
+#else
+ drv_ctx.video_vpu_fd = 1;
+#endif
+ DEBUG_PRINT_HIGH(" omx_vdpp::component_init(): Open returned fd %d, errno %d",
+ drv_ctx.video_vpu_fd, errno);
+
+ if(drv_ctx.video_vpu_fd == 0){
+ DEBUG_PRINT_ERROR("omx_vdpp:: Got fd as 0 for vpu, Opening again\n");
+ drv_ctx.video_vpu_fd = openInput("msm_vpu");
+ }
+
+ if(drv_ctx.video_vpu_fd < 0)
+ {
+ DEBUG_PRINT_ERROR("omx_vdpp::Comp Init Returning failure, errno %d\n", errno);
+ return OMX_ErrorInsufficientResources;
+ }
+
+#ifndef STUB_VPU
+ // query number of sessions and attach to session #1
+ /* Check how many sessions are suported by H/W */
+ ret = ioctl(drv_ctx.video_vpu_fd, VPU_QUERY_SESSIONS,
+ &drv_ctx.sessionsSupported);
+ if (ret < 0)
+ {
+ DEBUG_PRINT_ERROR("QUERY_SESSIONS: VPU_QUERY_SESSIONS failed.");
+ close(drv_ctx.video_vpu_fd);
+ drv_ctx.video_vpu_fd = 0;
+ return OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH("QUERY_SESSIONS: The number of sessions supported are %d.",
+ drv_ctx.sessionsSupported);
+ }
+#endif
+
+ /* Attach Client to Session. */
+ sessionNum = VDPP_SESSION;
+
+#ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VPU_ATTACH_TO_SESSION, &sessionNum);
+ if (ret < 0)
+ {
+ if( errno == EINVAL )
+ DEBUG_PRINT_ERROR("VPU_ATTACH_TO_SESSION: session %d is out of valid "
+ "range.", sessionNum);
+ else if( errno == EBUSY)
+ DEBUG_PRINT_ERROR("VPU_ATTACH_TO_SESSION: max. allowed number of"
+ "clients attached to session.");
+ else
+ DEBUG_PRINT_ERROR("VPU_ATTACH_TO_SESSION: failed for unknown reason.");
+ return OMX_ErrorUndefined;
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH("VPU_ATTACH_TO_SESSION: client successfully attached "
+ "to session.");
+ }
+#endif
+ drv_ctx.sessionAttached = sessionNum;
+
+ drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
+ drv_ctx.frame_rate.fps_denominator = 1;
+
+ ret = subscribe_to_events(drv_ctx.video_vpu_fd);
+
+ /* create control pipes */
+ if (!ret)
+ {
+ if(pipe(fctl))
+ {
+ DEBUG_PRINT_ERROR("pipe creation failed\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ int temp2[2];
+ if(fctl[0] == 0 || fctl[1] == 0)
+ {
+ if (pipe (temp2))
+ {
+ DEBUG_PRINT_ERROR("pipe creation failed\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ fctl[0] = temp2 [0];
+ fctl[1] = temp2 [1];
+ }
+ m_ctrl_in = fctl[0];
+ m_ctrl_out = fctl[1];
+
+ fcntl(m_ctrl_in, F_SETFL, O_NONBLOCK);
+ fcntl(m_ctrl_out, F_SETFL, O_NONBLOCK);
+ }
+ }
+
+ if (!ret) {
+ async_thread_created = true;
+ ret = pthread_create(&async_thread_id,0,async_message_thread,this);
+ }
+ if(ret) {
+ DEBUG_PRINT_ERROR(" Failed to create async_message_thread \n");
+ async_thread_created = false;
+ return OMX_ErrorInsufficientResources;
+ }
+
+#ifdef INPUT_BUFFER_LOG
+ inputBufferFile = open(inputfilename, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR);
+ if(inputBufferFile < 0)
+ {
+ DEBUG_PRINT_ERROR(" Failed to create inputBufferFile 0, errno = %d\n", errno);
+ }
+
+#endif
+
+#ifdef OUTPUT_BUFFER_LOG
+ outputBufferFile = open(outputfilename, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR);
+ if(outputBufferFile < 0)
+ {
+ DEBUG_PRINT_ERROR(" Failed to create outputBufferFile 0 , errno = %d\n", errno);
+ }
+#endif
+
+#ifdef OUTPUT_EXTRADATA_LOG
+ outputExtradataFile = open (ouputextradatafilename, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR);
+ if(outputExtradataFile == -1)
+ {
+ DEBUG_PRINT_ERROR(" Failed to create outputExtradataFile , errno = %d\n", errno);
+ }
+#endif
+
+ // Copy the role information which provides the vdpp kind
+ strlcpy(drv_ctx.kind,role,128);
+
+ // Default set to progressive mode for 8084. drv_ctx.interlace will be changed by
+ // interlace format filed of OMX buffer header extra data. User can also overwrite
+ // this setting by OMX_IndexParamInterlaceFormat
+ drv_ctx.interlace = V4L2_FIELD_NONE;
+
+ // Default input pixel format
+ output_capability=V4L2_PIX_FMT_NV12;
+
+ if (eRet == OMX_ErrorNone)
+ {
+ // set default output format to V4L2_PIX_FMT_NV12. User can use SetParam
+ // with OMX_IndexParamVideoPortFormat to set vdpp output format
+ drv_ctx.output_format = V4L2_PIX_FMT_NV12;
+ capture_capability = V4L2_PIX_FMT_NV12;
+
+ struct v4l2_capability cap;
+#ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_QUERYCAP, &cap);
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to query capabilities\n");
+ return OMX_ErrorUndefined;
+ } 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);
+
+ if ((cap.capabilities & V4L2_CAP_STREAMING) == 0)
+ {
+ DEBUG_PRINT_ERROR("device does not support streaming i/o\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+#endif
+ // set initial input h/w and pixel format
+ update_resolution(640, 480, 640, 480);
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
+ if (V4L2_FIELD_NONE == drv_ctx.interlace)
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ }
+ else
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
+ }
+ fmt.fmt.pix_mp.pixelformat = output_capability;
+
+ // NV12 has 2 planes.
+ /* Set format for each plane. */
+ setFormatParams(output_capability, drv_ctx.input_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[i] * fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[0]); // NV12 UV plane has the same width as Y, but 1/2 YH
+ DEBUG_PRINT_HIGH(" fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n ", i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+#ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
+
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set format on output port\n");
+ return OMX_ErrorUndefined;
+ }
+ DEBUG_PRINT_HIGH(" Set Format was successful drv_ctx.interlace = %d\n ", drv_ctx.interlace);
+#endif
+ // set initial output format
+ // initial input/output resolution are the same. portdefinition changes both
+ memset(&fmt, 0, sizeof(fmt));
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d", fmt.fmt.pix_mp.width,
+ fmt.fmt.pix_mp.height);
+
+ setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
+ drv_ctx.output_bytesperpixel[i] *
+ fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]);
+ DEBUG_PRINT_HIGH(" fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n ", i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+#ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
+ if (ret < 0)
+ {
+ DEBUG_PRINT_ERROR("VIDIOC_S_FMT setup VP output format error");
+ return OMX_ErrorUndefined;
+ }
+#endif
+ // update initial output resolution
+ drv_ctx.video_resolution_output.frame_height = fmt.fmt.pix_mp.height;
+ drv_ctx.video_resolution_output.frame_width = fmt.fmt.pix_mp.width;
+ drv_ctx.video_resolution_output.scan_lines = fmt.fmt.pix_mp.height;
+ drv_ctx.video_resolution_output.stride = fmt.fmt.pix_mp.width;
+
+ if (ret) {
+ DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
+ return OMX_ErrorUndefined;
+ }
+ DEBUG_PRINT_HIGH(" Set Format was successful \n ");
+
+ /*Get the Buffer requirements for input and output ports*/
+ drv_ctx.ip_buf.buffer_type = VDPP_BUFFER_TYPE_INPUT;
+ drv_ctx.op_buf.buffer_type = VDPP_BUFFER_TYPE_OUTPUT;
+
+ drv_ctx.op_buf.alignment=SZ_4K;
+ drv_ctx.ip_buf.alignment=SZ_4K;
+
+ m_state = OMX_StateLoaded;
+
+ 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);
+
+ /* create pipes for message thread*/
+ 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;
+ }
+ fds[0] = temp1 [0];
+ fds[1] = temp1 [1];
+ }
+ m_pipe_in = fds[0];
+ m_pipe_out = fds[1];
+ msg_thread_created = true;
+ ret = pthread_create(&msg_thread_id,0,message_thread,this);
+
+ if(ret < 0)
+ {
+ DEBUG_PRINT_ERROR(" component_init(): message_thread creation failed");
+ msg_thread_created = false;
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ }
+
+ if (eRet != OMX_ErrorNone)
+ {
+ DEBUG_PRINT_ERROR(" Component Init Failed");
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH(" omx_vdpp::component_init() success");
+ }
+
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::GetComponentVersion
+
+DESCRIPTION
+ Returns the component version.
+
+PARAMETERS
+ TBD.
+
+RETURN VALUE
+ OMX_ErrorNone.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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_vdpp::SendCommand
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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(" send_command: Recieved a Command from Client cmd = %d", cmd);
+ 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(" 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(" send_command: Command Processed cmd = %d\n", cmd);
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::SendCommand
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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(" send_command_proxy(): cmd = %d", cmd);
+ DEBUG_PRINT_HIGH("end_command_proxy(): Current State %d, Expected State %d",
+ 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\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;
+ 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_vpu_fd,VDPP_IOCTL_CMD_START,
+ NULL) < */0)
+ {
+ DEBUG_PRINT_ERROR(" VDPP_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(" 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(" 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(" PAUSE Command Issued");
+ m_state = OMX_StatePause;
+ bFlag = 1;
+ }
+ /* Requesting transition from Executing to Loaded */
+ else if(eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR(" 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(" 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(" 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(" 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(" 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(" 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(" 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(" 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(" 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(" 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(" send_command_proxy(): OMX_CommandFlush issued "
+ "with param1: 0x%x", param1);
+ if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
+ { // do not call flush ioctl if there is no buffer queued. Just return callback
+#ifndef STUB_VPU // VPU stub doesn't set any streaming flag
+ if(!streaming[OUTPUT_PORT])
+ {
+ m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,OMX_CommandFlush,
+ OMX_CORE_INPUT_PORT_INDEX,NULL );
+ sem_posted = 1;
+ sem_post (&m_cmd_lock);
+ }
+ else
+#endif
+ {
+ 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: %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(" 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(" send_command_proxy(): OMX_CommandPortDisable issued"
+ "with param1: %lu m_state = %d, streaming[OUTPUT_PORT] = %d", param1, m_state, streaming[OUTPUT_PORT]);
+ 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);
+ DEBUG_PRINT_LOW("OMX_CommandPortDisable 1");
+ }
+ else
+ {
+ BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
+ DEBUG_PRINT_LOW("OMX_CommandPortDisable 2");
+ if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
+ {
+ if(!sem_posted)
+ {
+ sem_posted = 1;
+ sem_post (&m_cmd_lock);
+ }
+ if(!streaming[OUTPUT_PORT])
+ {
+ DEBUG_PRINT_LOW("OMX_CommandPortDisable 3 ");
+ //IL client calls disable port and then free buffers.
+ //from free buffer, disable port done event will be sent
+ }
+ else
+ {
+ 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(" Disable output Port command recieved m_state = %d", m_state);
+ 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_vdpp::ExecuteOmxFlush
+
+DESCRIPTION
+ Executes the OMX flush.
+
+PARAMETERS
+ flushtype - input flush(1)/output flush(0)/ both.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_vdpp::execute_omx_flush(OMX_U32 flushType)
+{
+ bool bRet = false;
+ struct v4l2_requestbuffers bufreq;
+ struct vdpp_msginfo vdpp_msg;
+ enum v4l2_buf_type buf_type;
+ unsigned i = 0;
+
+ DEBUG_PRINT_LOW("in %s flushType = %d", __func__, flushType);
+ memset((void *)&vdpp_msg,0,sizeof(vdpp_msg));
+
+ switch (flushType)
+ {
+ case OMX_CORE_INPUT_PORT_INDEX:
+ input_flush_progress = true;
+
+ break;
+ case OMX_CORE_OUTPUT_PORT_INDEX:
+ output_flush_progress = true;
+
+ break;
+ default:
+ input_flush_progress = true;
+ output_flush_progress = true;
+ }
+
+ DEBUG_PRINT_HIGH("omx_vdpp::execute_omx_flush m_ftb_q.m_size = %d, m_etb_q.m_size = %d\n", m_ftb_q.m_size, m_etb_q.m_size);
+ // vpu doesn't have flush right now, simulate flush done from here
+#ifdef STUB_VPU
+ {
+ // dq output
+ if(output_flush_progress)
+ {
+ vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_OUTPUT_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ DEBUG_PRINT_HIGH("Simulate VDPP Output Flush Done Recieved From Driver\n");
+ if (async_message_process(this,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH(" VDPP Output Flush Done returns < 0 \n");
+ }
+ }
+
+ // dq input
+ if(input_flush_progress)
+ {
+ vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_INPUT_DONE;
+ vdpp_msg.status_code=VDPP_S_SUCCESS;
+ DEBUG_PRINT_HIGH("Simulate VDPP Input Flush Done Recieved From Driver \n");
+ if (async_message_process(this,&vdpp_msg) < 0) {
+ DEBUG_PRINT_HIGH(" VDPP Input Flush Done returns < 0 \n");
+ }
+
+ }
+
+ }
+#else
+ // flush input port
+ if(input_flush_progress)
+ {
+ buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+
+ if(ioctl(drv_ctx.video_vpu_fd, VPU_FLUSH_BUFS, &buf_type))
+ {
+ DEBUG_PRINT_ERROR("VDPP input Flush error! \n");
+ return false;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("VDPP input Flush success! \n");
+ }
+ }
+
+ // flush output port
+ if(output_flush_progress)
+ {
+ buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+ if(ioctl(drv_ctx.video_vpu_fd, VPU_FLUSH_BUFS, &buf_type))
+ {
+ DEBUG_PRINT_ERROR("VDPP output Flush error! \n");
+ return false;
+ }
+ else
+ {
+ DEBUG_PRINT_LOW("VDPP output Flush success! \n");
+ }
+ }
+#endif
+
+ return bRet;
+}
+/*=========================================================================
+FUNCTION : execute_output_flush
+
+DESCRIPTION
+ Executes the OMX flush at OUTPUT PORT.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+==========================================================================*/
+bool omx_vdpp::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(" Initiate Output Flush, m_ftb_q.m_size = %d", m_ftb_q.m_size);
+ while (m_ftb_q.m_size)
+ {
+ DEBUG_PRINT_LOW(" 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(" 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;
+
+ DEBUG_PRINT_HIGH(" OMX flush o/p Port complete PenBuf(%d), output_qbuf_count(%d), output_dqbuf_count(%d)",
+ pending_output_buffers, output_qbuf_count, output_dqbuf_count);
+ return bRet;
+}
+/*=========================================================================
+FUNCTION : execute_input_flush
+
+DESCRIPTION
+ Executes the OMX flush at INPUT PORT.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+==========================================================================*/
+bool omx_vdpp::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(" Initiate Input Flush \n");
+
+ pthread_mutex_lock(&m_lock);
+ DEBUG_PRINT_LOW(" Check if the Queue is empty \n");
+ while (m_etb_q.m_size)
+ {
+ DEBUG_PRINT_LOW(" m_etb_q.m_size = %d \n", m_etb_q.m_size);
+ m_etb_q.pop_entry(&p1,&p2,&ident);
+ DEBUG_PRINT_LOW("ident = %d \n", ident);
+ if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
+ {
+ DEBUG_PRINT_LOW(" 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(" 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(" Flush Input OMX_COMPONENT_GENERATE_EBD %p",
+ (OMX_BUFFERHEADERTYPE *)p1);
+ empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
+ }
+ }
+
+ pthread_mutex_unlock(&m_lock);
+ input_flush_progress = false;
+
+ 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), input_qbuf_count(%d), input_dqbuf_count(%d)",
+ pending_input_buffers, input_qbuf_count, input_dqbuf_count);
+ return bRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::SendCommandEvent
+
+DESCRIPTION
+ Send the event to VDPP pipe. This is needed to generate the callbacks
+ in VDPP thread context.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_vdpp::post_event(unsigned int p1,
+ unsigned int p2,
+ unsigned int id)
+{
+ bool bRet = false;
+
+ pthread_mutex_lock(&m_lock);
+ //DEBUG_PRINT_LOW("m_fill_output_msg = %d, OMX_COMPONENT_GENERATE_FBD = %d, id = %d", m_fill_output_msg, OMX_COMPONENT_GENERATE_FBD, id);
+ if (id == m_fill_output_msg ||
+ id == OMX_COMPONENT_GENERATE_FBD)
+ {
+ //DEBUG_PRINT_LOW(" post_event p2 = 0x%x, id = 0x%x", p2, id);
+ 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, id = %d",this, id);
+ post_message(this, id);
+
+ pthread_mutex_unlock(&m_lock);
+
+ return bRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::GetParameter
+
+DESCRIPTION
+ OMX Get Parameter method implementation
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_INOUT OMX_PTR paramData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ DEBUG_PRINT_HIGH("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_ERROR("Get Param in Invalid paramData \n");
+ return OMX_ErrorBadParameter;
+ }
+ //DEBUG_PRINT_HIGH("get_parameter 1 : \n");
+ 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 (OMX_CORE_INPUT_PORT_INDEX == portFmt->nPortIndex)
+ {
+ if (0 == portFmt->nIndex)
+ {
+ portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;//OMX_COLOR_FormatYUV420Planar;//OMX_COLOR_FormatUnused;
+ portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
+ " NoMore compression formats\n");
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+ else if (OMX_CORE_OUTPUT_PORT_INDEX == portFmt->nPortIndex)
+ {
+ portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
+
+ if(0 == portFmt->nIndex)
+ portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+ else
+ {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
+ " NoMore Color formats\n");
+ eRet = OMX_ErrorNoMore;
+ }
+ DEBUG_PRINT_ERROR("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(OMX_CORE_INPUT_PORT_INDEX == bufferSupplierType->nPortIndex)
+ bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
+ else if (OMX_CORE_OUTPUT_PORT_INDEX == bufferSupplierType->nPortIndex)
+ bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
+ else
+ eRet = OMX_ErrorBadPortIndex;
+
+
+ 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_INPUT_PORT_INDEX) || (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
+ {
+ nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_MM_HEAP;
+ DEBUG_PRINT_HIGH("ION:non_secure_mode: nUsage 0x%lx",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(" 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 input WxH(%d x %d) SxSH(%d x %d)\n",
+ drv_ctx.video_resolution_input.frame_width,
+ drv_ctx.video_resolution_input.frame_height,
+ drv_ctx.video_resolution_input.stride,
+ drv_ctx.video_resolution_input.scan_lines);
+
+ DEBUG_PRINT_LOW(" get_parameter returning output WxH(%d x %d) SxSH(%d x %d)\n",
+ drv_ctx.video_resolution_output.frame_width,
+ drv_ctx.video_resolution_output.frame_height,
+ drv_ctx.video_resolution_output.stride,
+ drv_ctx.video_resolution_output.scan_lines);
+
+ return eRet;
+}
+
+#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
+OMX_ERRORTYPE omx_vdpp::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<android_native_buffer_t> 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;
+
+ 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_vdpp::Setparameter
+
+DESCRIPTION
+ OMX Set Parameter method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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;
+ int i = 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;
+
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
+ (int)portDefn->format.video.nFrameHeight,
+ (int)portDefn->format.video.nFrameWidth);
+
+ if(OMX_CORE_OUTPUT_PORT_INDEX == portDefn->nPortIndex)
+ {
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
+
+ unsigned int buffer_size;
+ memset(&fmt, 0, sizeof(fmt));
+
+ // set output resolution based on port definition. scan_lines and stride settings need
+ // to match format setting requirement (QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)
+ {
+ DEBUG_PRINT_LOW(" SetParam OP: WxH(%lu x %lu)\n",
+ portDefn->format.video.nFrameWidth,
+ portDefn->format.video.nFrameHeight);
+ if (portDefn->format.video.nFrameHeight != 0x0 &&
+ portDefn->format.video.nFrameWidth != 0x0)
+ {
+ drv_ctx.video_resolution_output.frame_height = portDefn->format.video.nFrameHeight;
+ drv_ctx.video_resolution_output.frame_width = portDefn->format.video.nFrameWidth;
+ drv_ctx.video_resolution_output.scan_lines = paddedFrameWidth32(portDefn->format.video.nFrameHeight);
+ drv_ctx.video_resolution_output.stride = paddedFrameWidth128(portDefn->format.video.nFrameWidth);
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d, drv_ctx.video_resolution_output.stride = %d, drv_ctx.video_resolution_output.scan_lines = %d", fmt.fmt.pix_mp.width,
+ fmt.fmt.pix_mp.height, drv_ctx.video_resolution_output.stride, drv_ctx.video_resolution_output.scan_lines);
+ // NV12 has 2 planes.
+ /* Set format for each plane. */
+ setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[i] * fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]); // both plane have the same plane stride
+ DEBUG_PRINT_HIGH("before VIDIOC_S_FMT (op) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+
+ }
+
+#ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ DEBUG_PRINT_HIGH("after VIDIOC_S_FMT (op) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+
+ if (ret)
+ {
+ DEBUG_PRINT_ERROR(" Set Resolution failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+#endif
+ {
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+
+ // eRet = get_buffer_req(&drv_ctx.ip_buf);
+ }
+
+ }
+ }
+ 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_CORE_INPUT_PORT_INDEX == portDefn->nPortIndex)
+ {
+ // TODO for 8092 the frame rate code below can be enabled to debug frame rate
+#ifdef FRC_ENABLE
+ 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_HIGH("set_parameter: frm_int(%lu) fps(%.2f)",
+ frm_int, drv_ctx.frame_rate.fps_numerator /
+ (float)drv_ctx.frame_rate.fps_denominator);
+
+ 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;
+ memset(&sparm, 0, sizeof(struct v4l2_streamparm));
+ sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ sparm.parm.output = oparm;
+ if (ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_PARM, &sparm)) {
+ DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
+ performance might be affected");
+ eRet = OMX_ErrorHardware;
+ }
+ }
+#endif
+ memset(&fmt, 0, sizeof(fmt));
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
+ if(drv_ctx.video_resolution_input.frame_height !=
+ portDefn->format.video.nFrameHeight ||
+ drv_ctx.video_resolution_input.frame_width !=
+ portDefn->format.video.nFrameWidth)
+ {
+ DEBUG_PRINT_LOW(" 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.nStride,
+ (portDefn->format.video.nSliceHeight));
+
+ // decoder stride information is not used in S_FMT and QBUF, since paddedWidth
+ // will ensure the buffer length/size is always aligned with 128 bytes, which
+ // has the same effect as stride.
+ // output has Width 720, and nStride = 768
+ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
+ if (V4L2_FIELD_NONE == drv_ctx.interlace)
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ }
+ else
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
+ }
+ fmt.fmt.pix_mp.pixelformat = output_capability;
+
+ // NV12 has 2 planes.
+ /* Set format for each plane. */
+ setFormatParams(output_capability, drv_ctx.input_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[i] * fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[0]); // both plane have the same plane stride
+ DEBUG_PRINT_HIGH("before VIDIOC_S_FMT (ip) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+
+#ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
+ // for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ // {
+ //DEBUG_PRINT_HIGH("after VIDIOC_S_FMT (ip) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ // }
+ if (ret)
+ {
+ DEBUG_PRINT_ERROR(" Set Resolution failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+#endif
+ {
+ DEBUG_PRINT_HIGH("after VIDIOC_S_FMT (ip) drv_ctx.interlace = %d", drv_ctx.interlace);
+ // set output resolution the same as input
+ drv_ctx.video_resolution_output.frame_height = portDefn->format.video.nFrameHeight;
+ drv_ctx.video_resolution_output.frame_width = portDefn->format.video.nFrameWidth;
+ drv_ctx.video_resolution_output.scan_lines = paddedFrameWidth32(portDefn->format.video.nSliceHeight);
+ drv_ctx.video_resolution_output.stride = paddedFrameWidth128(portDefn->format.video.nStride);
+
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d, drv_ctx.video_resolution_output.stride = %d, drv_ctx.video_resolution_output.scan_lines = %d", fmt.fmt.pix_mp.width,
+ fmt.fmt.pix_mp.height, drv_ctx.video_resolution_output.stride, drv_ctx.video_resolution_output.scan_lines);
+ // NV12 has 2 planes.
+ /* Set format for each plane. */
+ setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[i] * fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]); // both plane have the same plane stride
+ DEBUG_PRINT_HIGH("before VIDIOC_S_FMT op fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+
+ #ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ DEBUG_PRINT_HIGH("after VIDIOC_S_FMT op fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+
+ if (ret)
+ {
+ DEBUG_PRINT_ERROR(" Set Resolution failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+ #endif
+ {
+ // get buffer req for input, output buffer size is
+ // determined by output pixel format and output resolution
+ //eRet = get_buffer_req(&drv_ctx.op_buf);
+ eRet = get_buffer_req(&drv_ctx.ip_buf);
+ }
+ }
+ }
+ }
+
+ if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
+ /*|| portDefn->nBufferSize >= drv_ctx.ip_buf.buffer_size*/)
+ // only allocate larger size
+ {
+ DEBUG_PRINT_HIGH("portDefn->nBufferCountActual = %lu portDefn->nBufferSize = %lu, drv_ctx.ip_buf.buffer_size=%d \n", portDefn->nBufferCountActual, portDefn->nBufferSize, drv_ctx.ip_buf.buffer_size);
+ vdpp_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
+ drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
+ //if(portDefn->nBufferSize >= drv_ctx.ip_buf.buffer_size)
+ //{
+ // drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
+ // (~(buffer_prop->alignment - 1));
+ // DEBUG_PRINT_HIGH("drv_ctx.ip_buf.buffer_size = %d, buffer_prop->alignment = %d\n", drv_ctx.ip_buf.buffer_size, buffer_prop->alignment);
+ //}
+ 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(OMX_CORE_OUTPUT_PORT_INDEX == portFmt->nPortIndex)
+ {
+ uint32_t op_format;
+
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+
+ // TODO based on output format
+ // update OMX format type for additional output format supported by 8084
+ if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
+ (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
+ op_format = (uint32_t)V4L2_PIX_FMT_NV12;
+ else if(portFmt->eColorFormat ==
+ (OMX_COLOR_FORMATTYPE)
+ QOMX_COLOR_FormatYVU420SemiPlanar)
+ op_format = V4L2_PIX_FMT_NV21;
+ else
+ eRet = OMX_ErrorBadParameter;
+
+ if(eRet == OMX_ErrorNone)
+ {
+ drv_ctx.output_format = op_format;
+ capture_capability = op_format;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+
+ DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d", fmt.fmt.pix_mp.width,
+ fmt.fmt.pix_mp.height);
+
+ setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
+ drv_ctx.output_bytesperpixel[i] *
+ fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]);
+ }
+#ifndef STUB_VPU
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
+ if(ret)
+ {
+ DEBUG_PRINT_ERROR(" Set output format failed");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+#endif
+ {
+ eRet = get_buffer_req(&drv_ctx.op_buf);
+ }
+ }
+ }
+ }
+ 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;
+ }
+
+ // no component role yet
+ /* if(!strncmp(drv_ctx.kind, "OMX.qcom.video.vidpp",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if(!strncmp((char*)comp_role->cRole,"video.vidpp",OMX_MAX_STRINGNAME_SIZE))
+ {
+ strlcpy((char*)m_cRole,"video.vidpp",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;
+
+ }
+#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;
+ }
+ DEBUG_PRINT_HIGH("OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: enableNativeBuffers %d\n", m_enable_android_native_buffers);
+ }
+ break;
+ case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
+ {
+ eRet = use_android_native_buffer(hComp, paramData);
+ }
+ break;
+#endif
+ case OMX_QcomIndexParamInterlaceExtraData:
+ eRet = enable_extradata(OMX_INTERLACE_EXTRADATA,
+ ((QOMX_ENABLETYPE *)paramData)->bEnable);
+
+ break;
+ case OMX_IndexParamInterlaceFormat:
+ {
+ OMX_INTERLACEFORMATTYPE *interlaceFormat = ( OMX_INTERLACEFORMATTYPE *)paramData;
+ DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamInterlaceFormat %ld\n",
+ interlaceFormat->nFormat);
+
+ if(OMX_InterlaceInterleaveFrameBottomFieldFirst == (OMX_U32)interlaceFormat->nFormat)
+ {
+ drv_ctx.interlace = V4L2_FIELD_INTERLACED_BT;
+ DEBUG_PRINT_LOW("set_parameter: V4L2_FIELD_INTERLACED_BT");
+ interlace_user_flag = true;
+ }
+ else if(OMX_InterlaceInterleaveFrameTopFieldFirst == (OMX_U32)interlaceFormat->nFormat)
+ {
+ drv_ctx.interlace = V4L2_FIELD_INTERLACED_TB;
+ DEBUG_PRINT_LOW("set_parameter: V4L2_FIELD_INTERLACED_TB");
+ interlace_user_flag = true;
+ }
+ else if(OMX_InterlaceFrameProgressive == (OMX_U32)interlaceFormat->nFormat)
+ {
+ drv_ctx.interlace = V4L2_FIELD_NONE;
+ DEBUG_PRINT_LOW("set_parameter: V4L2_FIELD_NONE");
+ interlace_user_flag = true;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Setparameter: unknown param %lu\n", interlaceFormat->nFormat);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ break;
+ default:
+ {
+ DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::GetConfig
+
+DESCRIPTION
+ OMX Get Config Method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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_IndexConfigCommonOutputCrop:
+ {
+ OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
+ memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
+ break;
+ }
+
+ // OMX extensions
+ case OMX_QcomIndexConfigActiveRegionDetectionStatus:
+ break;
+
+ default:
+ {
+ DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
+ eRet = OMX_ErrorBadParameter;
+ }
+
+ }
+
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::SetConfig
+
+DESCRIPTION
+ OMX Set Config method implementation
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::set_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_IN OMX_PTR configData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ struct vpu_control control;
+ int result = 0;
+
+ DEBUG_PRINT_LOW("omx_vdpp::set_config \n");
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ switch ((unsigned long)configIndex)
+ {
+ // OMX extensions
+ case OMX_QcomIndexConfigActiveRegionDetection:
+ {
+ struct vpu_ctrl_active_region_param *ard = &control.data.active_region_param;
+ memset(&control, 0, sizeof(control));
+ control.control_id = VPU_CTRL_ACTIVE_REGION_PARAM;
+ mExtensionData.activeRegionDetectionDirtyFlag = true;
+ memcpy(&(mExtensionData.activeRegionDetection),
+ configData,
+ sizeof(mExtensionData.activeRegionDetection));
+
+ /* Set control. */
+ ard->enable = mExtensionData.activeRegionDetection.bEnable;
+ ard->num_exclusions = mExtensionData.activeRegionDetection.nNumExclusionRegions;
+ memcpy(&(ard->detection_region), &(mExtensionData.activeRegionDetection.sROI), sizeof(QOMX_RECTTYPE));
+ if(ard->num_exclusions > 0)
+ {
+ memcpy(&(ard->detection_region), &(mExtensionData.activeRegionDetection.sExclusionRegions), (ard->num_exclusions * sizeof(QOMX_RECTTYPE)));
+ }
+
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ACTIVE_REGION_MEASURE : "
+ "top %d left %d width %d height %d",
+ ard->detection_region.top, ard->detection_region.left,
+ ard->detection_region.width, ard->detection_region.height);
+#ifndef STUB_VPU
+ result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
+ if (result < 0)
+ {
+ DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_ACTIVE_REGION_MEASURE failed, result = %d", result);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+ {
+ mExtensionData.activeRegionDetectionDirtyFlag = false;
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ACTIVE_REGION_MEASURE set to: "
+ "top %d left %d width %d height %d",
+ ard->detection_region.top, ard->detection_region.left,
+ ard->detection_region.width, ard->detection_region.height);
+ }
+#endif
+ break;
+ }
+
+ case OMX_QcomIndexConfigScalingMode:
+ {
+ struct vpu_ctrl_standard *anmph = &control.data.standard;
+ memset(&control, 0, sizeof(control));
+ control.control_id = VPU_CTRL_ANAMORPHIC_SCALING;
+ mExtensionData.scalingModeDirtyFlag = true;
+ memcpy(&(mExtensionData.scalingMode),
+ configData,
+ sizeof(mExtensionData.scalingMode));
+
+ /* Set control. */
+ anmph->enable = 1;
+ anmph->value = mExtensionData.scalingMode.eScaleMode;
+
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ANAMORPHIC_SCALING %d, anmph->enable = %d", anmph->value, anmph->enable);
+#ifndef STUB_VPU
+ result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
+ if (result < 0)
+ {
+ DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_ANAMORPHIC_SCALING failed, result = %d", result);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+ {
+ mExtensionData.scalingModeDirtyFlag = false;
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ANAMORPHIC_SCALING set to %d", anmph->value);
+ }
+#endif
+ break;
+ }
+
+ case OMX_QcomIndexConfigNoiseReduction:
+ {
+ struct vpu_ctrl_auto_manual *nr = &control.data.auto_manual;
+ memset(&control, 0, sizeof(control));
+ control.control_id = VPU_CTRL_NOISE_REDUCTION;
+ mExtensionData.noiseReductionDirtyFlag = true;
+ memcpy(&(mExtensionData.noiseReduction),
+ configData,
+ sizeof(mExtensionData.noiseReduction));
+
+ /* Set control. */
+ nr->enable = mExtensionData.noiseReduction.bEnable;
+ nr->auto_mode = mExtensionData.noiseReduction.bAutoMode;
+ nr->value = mExtensionData.noiseReduction.nNoiseReduction;
+
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_NOISE_REDUCTION %d, nr->enable = %d, nr->auto_mode = %d", nr->value, nr->enable, nr->auto_mode);
+#ifndef STUB_VPU
+ result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
+ if (result < 0)
+ {
+ DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_NOISE_REDUCTION failed, result = %d", result);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+ {
+ mExtensionData.noiseReductionDirtyFlag = false;
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_NOISE_REDUCTION set to %d", nr->value);
+ }
+#endif
+ break;
+ }
+
+ case OMX_QcomIndexConfigImageEnhancement:
+ {
+ struct vpu_ctrl_auto_manual *ie = &control.data.auto_manual;
+ memset(&control, 0, sizeof(control));
+ control.control_id = VPU_CTRL_IMAGE_ENHANCEMENT;
+ mExtensionData.imageEnhancementDirtyFlag = true;
+ memcpy(&(mExtensionData.imageEnhancement),
+ configData,
+ sizeof(mExtensionData.imageEnhancement));
+
+ /* Set control. */
+ ie->enable = mExtensionData.imageEnhancement.bEnable;
+ ie->auto_mode = mExtensionData.imageEnhancement.bAutoMode;
+ ie->value = mExtensionData.imageEnhancement.nImageEnhancement;
+
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_IMAGE_ENHANCEMENT %d, ie->enable = %d, ie->auto_mode = %d", ie->value, ie->enable, ie->auto_mode);
+#ifndef STUB_VPU
+ result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
+ if (result < 0)
+ {
+ DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_IMAGE_ENHANCEMENT failed, result = %d", result);
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ else
+ {
+ mExtensionData.imageEnhancementDirtyFlag = false;
+ DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_IMAGE_ENHANCEMENT set to %d", ie->value);
+ }
+#endif
+ break;
+ }
+#ifdef FRC_ENABLE
+ case OMX_IndexVendorVideoFrameRate:
+ {
+
+ OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
+ DEBUG_PRINT_HIGH("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;
+ memset(&sparm, 0, sizeof(struct v4l2_streamparm));
+ sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ sparm.parm.output = oparm;
+#ifndef STUB_VPU
+ if (ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_PARM, &sparm)) {
+ DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
+ performance might be affected");
+ eRet = OMX_ErrorHardware;
+ }
+#endif
+ client_set_fps = true;
+ } else {
+ DEBUG_PRINT_ERROR("Frame rate not supported.");
+ eRet = OMX_ErrorUnsupportedSetting;
+ }
+ } else {
+ DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
+ client_set_fps = false;
+ }
+ } else { // 8084 doesn't support FRC (only 8092 does). only input framerate setting is supported.
+ DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
+ (int)config->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ }
+ break;
+#endif
+ case OMX_IndexConfigCallbackRequest:
+ {
+ OMX_CONFIG_CALLBACKREQUESTTYPE *callbackRequest = (OMX_CONFIG_CALLBACKREQUESTTYPE *) configData;
+ DEBUG_PRINT_HIGH("OMX_IndexConfigCallbackRequest %d", callbackRequest->bEnable);
+
+ if (callbackRequest->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
+ if ((callbackRequest->bEnable) && (OMX_QcomIndexConfigActiveRegionDetectionStatus == (OMX_QCOM_EXTN_INDEXTYPE)callbackRequest->nIndex))
+ {
+ m_ar_callback_setup = true;
+ }
+ }
+ }
+ break;
+ case OMX_IndexConfigCommonOutputCrop:
+ {
+ OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
+ memcpy(&rectangle, rect, sizeof(OMX_CONFIG_RECTTYPE));
+ break;
+ }
+ default:
+ {
+ DEBUG_PRINT_ERROR("set_config: unknown param 0x%08x\n",configIndex);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::GetExtensionIndex
+
+DESCRIPTION
+ OMX GetExtensionIndex method implementaion. <TBD>
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_STRING paramName,
+ OMX_OUT OMX_INDEXTYPE* indexType)
+{
+ DEBUG_PRINT_LOW("omx_vdpp::get_extension_index %s\n", paramName);
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+#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;
+ DEBUG_PRINT_HIGH("OMX.google.android.index.enableAndroidNativeBuffers");
+ }
+ else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
+ *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
+ DEBUG_PRINT_HIGH("OMX.google.android.index.useAndroidNativeBuffer2");
+ }
+ 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;
+ DEBUG_PRINT_HIGH("OMX.google.android.index.useAndroidNativeBuffer");
+ }
+ else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
+ *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
+ DEBUG_PRINT_HIGH("OMX.google.android.index.getAndroidNativeBufferUsage");
+ }
+#endif
+
+ /* VIDPP extension
+ */
+ else if(!strncmp(paramName,
+ OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS,
+ sizeof(OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS) - 1))
+ {
+ DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS 0x%x \n", OMX_QcomIndexConfigActiveRegionDetectionStatus);
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetectionStatus;
+ }
+ else if(!strncmp(paramName,
+ OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION,
+ sizeof(OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION) - 1))
+ {
+ DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION 0x%x \n", OMX_QcomIndexConfigActiveRegionDetection);
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetection;
+ }
+ else if(!strncmp(paramName,
+ OMX_QCOM_INDEX_CONFIG_SCALING_MODE,
+ sizeof(OMX_QCOM_INDEX_CONFIG_SCALING_MODE) - 1))
+ {
+ DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_SCALING_MODE 0x%x \n", OMX_QcomIndexConfigScalingMode);
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigScalingMode;
+ }
+ else if(!strncmp(paramName,
+ OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION,
+ sizeof(OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION) - 1))
+ {
+ DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION 0x%x \n", OMX_QcomIndexConfigNoiseReduction);
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigNoiseReduction;
+ }
+ else if(!strncmp(paramName,
+ OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT,
+ sizeof(OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT) - 1))
+ {
+ DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT 0x%x \n", OMX_QcomIndexConfigImageEnhancement);
+ *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigImageEnhancement;
+ }
+
+ else {
+ DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
+ return OMX_ErrorNotImplemented;
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::GetState
+
+DESCRIPTION
+ Returns the state information back to the caller.<TBD>
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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_vdpp::ComponentTunnelRequest
+
+DESCRIPTION
+ OMX Component Tunnel Request method implementation. <TBD>
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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;
+}
+
+OMX_ERRORTYPE omx_vdpp::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 vdpp_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;
+
+ DEBUG_PRINT_HIGH("Inside omx_vdpp::use_output_buffer buffer = %p, bytes= %lu", buffer, bytes);
+
+ if (!m_out_mem_ptr) {
+ DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers buffer = %p, bytes= %lu", buffer, bytes);
+ eRet = allocate_output_headers();
+ }
+
+ 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) {
+ DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 1\n");
+ if (m_use_android_native_buffers) {
+ DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 2\n");
+ UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
+ sp<android_native_buffer_t> nBuf = params->nativeBuffer;
+ handle = (private_handle_t *)nBuf->handle;
+ privateAppData = params->pAppPrivate;
+ } else {
+ DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 3\n");
+ handle = (private_handle_t *)buff;
+ privateAppData = appData;
+ }
+
+ if(!handle) {
+ DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ 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 defined(_ANDROID_ICS_)
+ native_buffer[i].nativehandle = handle;
+ native_buffer[i].privatehandle = handle;
+#endif
+ drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
+ drv_ctx.ptr_outputbuffer[i].offset = 0;
+ drv_ctx.ptr_outputbuffer[i].bufferaddr = NULL;
+ drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
+ drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
+ DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 5 drv_ctx.ptr_outputbuffer[i].bufferaddr = %p, size1=%d, size2=%d\n",
+ drv_ctx.ptr_outputbuffer[i].bufferaddr,
+ drv_ctx.op_buf.buffer_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, 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;
+ }
+
+ 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(" align_pmem_buffers() failed");
+ close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+ {
+ 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(!buffer) {
+ DEBUG_PRINT_ERROR(" 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 || !pmem_list->entryList || !pmem_list->entryList->entry ||
+ !pmem_list->nEntries ||
+ pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
+ DEBUG_PRINT_ERROR(" 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;
+ }
+
+ *bufferHdr = (m_out_mem_ptr + i );
+
+ memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
+ sizeof (vdpp_bufferpayload));
+
+ DEBUG_PRINT_HIGH(" 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 );
+#ifndef STUB_VPU
+ DEBUG_PRINT_LOW("use_output_buffer: i = %d, streaming[CAPTURE_PORT] = %d ", i, streaming[CAPTURE_PORT]);
+ // stream on output port
+ 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_vpu_fd, VIDIOC_STREAMON,&buf_type)) {
+ DEBUG_PRINT_ERROR("V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE STREAMON failed \n ");
+ return OMX_ErrorInsufficientResources;
+ } else {
+ streaming[CAPTURE_PORT] = true;
+ DEBUG_PRINT_HIGH("V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE STREAMON Successful \n ");
+ }
+ }
+#endif
+
+ (*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_vdpp::use_input_heap_buffers
+
+DESCRIPTION
+ OMX Use Buffer Heap allocation method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None , if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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)
+{
+ OMX_PTR privateAppData = NULL;
+#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
+ private_handle_t *handle = NULL;
+#endif
+ OMX_U8 *buff = buffer;
+
+ DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if(!m_inp_heap_ptr)
+ {
+ DEBUG_PRINT_LOW("Inside %s 0, %p\n", __FUNCTION__, buffer);
+ m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
+ calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
+ drv_ctx.ip_buf.actualcount);
+ }
+
+ if(!m_phdr_pmem_ptr)
+ {
+ DEBUG_PRINT_LOW("Inside %s 0-1, %p\n", __FUNCTION__, buffer);
+ 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)
+ {
+ DEBUG_PRINT_LOW("Inside %s 2 m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d\n", __FUNCTION__, 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));
+ // update this buffer for native window buffer in etb
+ // OMXNodeInstance::useGraphicBuffer2_l check if pBuffer and pAppPrivate are
+ // the same value as passed in. If not, useGraphicBuffer2_l will exit on error
+ //
+ 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;
+ // save mmapped native window buffer address to pPlatformPrivate
+ // use this mmaped buffer address in etb_proxy
+#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
+ /*if(m_enable_android_native_buffers) */{
+ if (m_use_android_native_buffers) {
+ UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
+ sp<android_native_buffer_t> nBuf = params->nativeBuffer;
+ handle = (private_handle_t *)nBuf->handle;
+ privateAppData = params->pAppPrivate;
+ } else {
+ handle = (private_handle_t *)buff;
+ privateAppData = appData;
+ //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 3\n");
+ }
+
+ if(!handle) {
+ DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ if ((OMX_U32)handle->size < drv_ctx.ip_buf.buffer_size) {
+ DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
+ " expected %u, got %lu",
+ drv_ctx.ip_buf.buffer_size, (OMX_U32)handle->size);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_use_android_native_buffers) {
+ buff = (OMX_U8*)mmap(0, handle->size,
+ PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
+ //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 4 buff = %p\n", buff);
+ if (buff == MAP_FAILED) {
+ DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ // we only need to copy this buffer (read only), no need to preserver this handle
+ // this handle is saved for write-unlock in use_output_buffer case
+#if defined(_ANDROID_ICS_)
+ //native_buffer[i].nativehandle = handle;
+ //native_buffer[i].privatehandle = handle;
+#endif
+ m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate = buff;
+ //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 5 m_inp_heap_ptr = %p, m_inp_heap_ptr[%lu].pPlatformPrivate = %p, m_inp_heap_ptr[%lu].pBuffer = %p\n",
+ // m_inp_heap_ptr, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pBuffer);
+ }
+#endif
+ *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
+ // user passes buffer in, but we need ION buffer
+ //DEBUG_PRINT_LOW("Inside %s 6 *bufferHdr = %p, byts = %lu \n", __FUNCTION__, *bufferHdr, bytes);
+ 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],
+ (unsigned)NULL, (unsigned)NULL))
+ {
+ DEBUG_PRINT_ERROR("ERROR:Free_q is full");
+ return OMX_ErrorInsufficientResources;
+ }
+ m_in_alloc_cnt++;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("All i/p buffers have been set! m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d", m_in_alloc_cnt, drv_ctx.ip_buf.actualcount);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::use_input_buffers
+
+DESCRIPTION
+ OMX Use Buffer method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None , if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::use_input_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)
+{
+ OMX_PTR privateAppData = NULL;
+ OMX_BUFFERHEADERTYPE *input = NULL;
+#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
+ private_handle_t *handle = NULL;
+#endif
+ OMX_U8 *buff = buffer;
+ unsigned int i = 0;
+
+ DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if(!m_inp_heap_ptr)
+ {
+ DEBUG_PRINT_LOW("Inside %s 0, %p\n", __FUNCTION__, buffer);
+ m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
+ calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
+ drv_ctx.ip_buf.actualcount);
+ }
+
+ if(!m_phdr_pmem_ptr)
+ {
+ DEBUG_PRINT_LOW("Inside %s 0-1, %p\n", __FUNCTION__, buffer);
+ 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)
+ {
+ DEBUG_PRINT_LOW("Inside %s 2 m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d\n", __FUNCTION__, 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));
+ // update this buffer for native window buffer in etb
+ // OMXNodeInstance::useGraphicBuffer2_l check if pBuffer and pAppPrivate are
+ // the same value as passed in. If not, useGraphicBuffer2_l will exit on error
+ //
+ 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;
+ // save mmapped native window buffer address to pPlatformPrivate
+ // use this mmaped buffer address in etb_proxy
+#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
+ /*if(m_enable_android_native_buffers) */{
+ if (m_use_android_native_buffers) {
+ UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
+ sp<android_native_buffer_t> nBuf = params->nativeBuffer;
+ handle = (private_handle_t *)nBuf->handle;
+ privateAppData = params->pAppPrivate;
+ } else {
+ handle = (private_handle_t *)buff;
+ privateAppData = appData;
+ DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 3\n");
+ }
+
+ if(!handle) {
+ DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ if ((OMX_U32)handle->size < drv_ctx.ip_buf.buffer_size) {
+ DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
+ " expected %u, got %lu",
+ drv_ctx.ip_buf.buffer_size, (OMX_U32)handle->size);
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_use_android_native_buffers) {
+ buff = (OMX_U8*)mmap(0, (handle->size - drv_ctx.ip_buf.frame_size),
+ PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, drv_ctx.ip_buf.frame_size);
+
+ DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 4 buff = %p, size1=%d, size2=%d\n", buff,
+ drv_ctx.ip_buf.buffer_size,
+ handle->size);
+ if (buff == MAP_FAILED) {
+ DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ // we only need to copy this buffer (read only), no need to preserver this handle
+ // this handle is saved for write-unlock in use_output_buffer case
+#if defined(_ANDROID_ICS_)
+ //native_buffer[i].nativehandle = handle;
+ //native_buffer[i].privatehandle = handle;
+#endif
+ m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate = buff;
+ //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 5 m_inp_heap_ptr = %p, m_inp_heap_ptr[%lu].pPlatformPrivate = %p, m_inp_heap_ptr[%lu].pBuffer = %p\n",
+ // m_inp_heap_ptr, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pBuffer);
+ }
+#endif
+ *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
+
+ 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 vdpp_bufferpayload *) \
+ calloc ((sizeof (struct vdpp_bufferpayload)),drv_ctx.ip_buf.actualcount);
+
+ if (drv_ctx.ptr_inputbuffer == NULL)
+ {
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+
+ 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)
+ {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc;
+
+ m_phdr_pmem_ptr[m_in_alloc_cnt] = (m_inp_mem_ptr + i);
+
+ drv_ctx.ptr_inputbuffer [i].bufferaddr = buff;
+ drv_ctx.ptr_inputbuffer [i].pmem_fd = handle->fd;
+ drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
+ drv_ctx.ptr_inputbuffer [i].mmaped_size = handle->size - drv_ctx.ip_buf.frame_size;
+ drv_ctx.ptr_inputbuffer [i].offset = 0;
+
+ input = m_phdr_pmem_ptr[m_in_alloc_cnt];
+ BITMASK_SET(&m_inp_bm_count,i);
+ DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer Buffer address %p of pmem",*bufferHdr);
+
+ input->pBuffer = (OMX_U8 *)buff;
+ 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]; // used in empty_this_buffer_proxy
+
+ DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer input->pBuffer %p of pmem, input->pInputPortPrivate = %p",input->pBuffer, input->pInputPortPrivate);
+ DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer memset drv_ctx.ip_buf.buffer_size = %d\n", drv_ctx.ip_buf.buffer_size);
+
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+
+ if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
+ (unsigned)NULL, (unsigned)NULL))
+ {
+ DEBUG_PRINT_ERROR("ERROR:Free_q is full");
+ return OMX_ErrorInsufficientResources;
+ }
+ m_in_alloc_cnt++;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("All i/p buffers have been set! m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d", m_in_alloc_cnt, drv_ctx.ip_buf.actualcount);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::UseBuffer
+
+DESCRIPTION
+ OMX Use Buffer method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None , if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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 vdpp_setbuffer_cmd setbuffers;
+
+ if ((bufferHdr == NULL) || (bytes == 0) || (/*!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);
+ error = use_input_buffers(hComp, bufferHdr, port, appData, bytes, buffer); // option to use vdec buffer
+
+ else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
+ error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
+ 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);
+ }
+ }
+ DEBUG_PRINT_LOW("Use Buffer error = %d", error);
+ return error;
+}
+
+OMX_ERRORTYPE omx_vdpp::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;
+
+ // decrease m_in_alloc_cnt so use_input_heap_buffer can be called
+ // again after port re-enable
+ m_in_alloc_cnt--;
+ DEBUG_PRINT_LOW("free_input_buffer Free Input Buffer index = %d, m_in_alloc_cnt = %lu",index, m_in_alloc_cnt);
+
+ if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
+ DEBUG_PRINT_LOW("Free Input ION Buffer index = %d",index);
+ if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
+ struct vdpp_setbuffer_cmd setbuffers;
+ setbuffers.buffer_type = VDPP_BUFFER_TYPE_INPUT;
+ memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
+ sizeof (vdpp_bufferpayload));
+ {
+ 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 = %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);
+ }
+
+ // If drv_ctx.ip_buf_ion_info is NULL then ION buffer is passed from upper layer.
+ // don't close fd and free this buffer, leave upper layer close and free this buffer
+ drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
+ if(drv_ctx.ip_buf_ion_info != NULL)
+ {
+ close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
+ #ifdef USE_ION
+ free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
+ #endif
+ }
+
+ }
+ }
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdpp::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(" Free output Buffer index = %d",index);
+
+ if (index < drv_ctx.op_buf.actualcount
+ && drv_ctx.ptr_outputbuffer)
+ {
+ DEBUG_PRINT_LOW(" Free output Buffer index = %d addr = %p", index,
+ drv_ctx.ptr_outputbuffer[index].bufferaddr);
+
+ struct vdpp_setbuffer_cmd setbuffers;
+ setbuffers.buffer_type = VDPP_BUFFER_TYPE_OUTPUT;
+ memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
+ sizeof (vdpp_bufferpayload));
+#ifdef _ANDROID_
+ if(m_enable_android_native_buffers) {
+ DEBUG_PRINT_LOW(" Free output Buffer android pmem_fd=%d", drv_ctx.ptr_outputbuffer[index].pmem_fd);
+ if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
+ DEBUG_PRINT_LOW(" Free output Buffer android 2 bufferaddr=%p, mmaped_size=%d",
+ drv_ctx.ptr_outputbuffer[index].bufferaddr,
+ drv_ctx.ptr_outputbuffer[index].mmaped_size);
+ if( NULL != drv_ctx.ptr_outputbuffer[index].bufferaddr)
+ {
+ 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)
+ {
+ {
+ 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 = %p",
+ drv_ctx.ptr_outputbuffer[index].mmaped_size * drv_ctx.op_buf.actualcount,
+ drv_ctx.ptr_outputbuffer[index].bufferaddr);
+ munmap (drv_ctx.ptr_outputbuffer[index].bufferaddr,
+ drv_ctx.ptr_outputbuffer[index].mmaped_size * drv_ctx.op_buf.actualcount);
+ }
+ 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_
+ }
+#endif
+ if (release_output_done()) {
+ //free_extradata();
+ }
+ }
+
+ return OMX_ErrorNone;
+
+}
+
+OMX_ERRORTYPE omx_vdpp::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) || (m_phdr_pmem_ptr == NULL))
+ {
+ DEBUG_PRINT_ERROR(" 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;
+ 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],
+ (unsigned)NULL, (unsigned)NULL))
+ {
+ DEBUG_PRINT_ERROR("ERROR:Free_q is full");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ return eRet;
+
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::AllocateInputBuffer
+
+DESCRIPTION
+ Helper function for allocate buffer in the input pin
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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 vdpp_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(" Requested Size is wrong %lu expected 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 vdpp_bufferpayload *) \
+ calloc ((sizeof (struct vdpp_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 vdpp_ion *) \
+ calloc ((sizeof (struct vdpp_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)
+ {
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane;
+ int rc;
+ DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer Allocate input Buffer, drv_ctx.ip_buf.buffer_size = %d", drv_ctx.ip_buf.buffer_size);
+#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, 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;
+#endif
+
+ {
+ 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(" Map Failed to allocate input buffer");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ *bufferHdr = (m_inp_mem_ptr + i);
+
+ 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;
+
+ input = *bufferHdr;
+ BITMASK_SET(&m_inp_bm_count,i);
+ DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer Buffer address %p of pmem",*bufferHdr);
+
+ 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]; // used in empty_this_buffer_proxy
+
+ DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer input->pBuffer %p of pmem, input->pInputPortPrivate = %p",input->pBuffer, input->pInputPortPrivate);
+ memset(buf_addr, 0, drv_ctx.ip_buf.buffer_size);
+ DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer memset drv_ctx.ip_buf.buffer_size = %d\n", drv_ctx.ip_buf.buffer_size);
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::AllocateOutputBuffer
+
+DESCRIPTION
+ Helper fn for AllocateBuffer in the output pin
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything went well.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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 vdpp_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(" Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
+ drv_ctx.op_buf.actualcount,
+ drv_ctx.op_buf.buffer_size);
+ int nBufHdrSize = 0;
+ int pmem_fd = -1;
+ unsigned char *pmem_baseaddress = NULL;
+
+ DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
+ drv_ctx.op_buf.actualcount);
+ nBufHdrSize = drv_ctx.op_buf.actualcount *
+ sizeof(OMX_BUFFERHEADERTYPE);
+#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, 0);
+ if (ion_device_fd < 0) {
+ return OMX_ErrorInsufficientResources;
+ }
+ pmem_fd = fd_ion_data.fd;
+#endif
+
+ {
+ 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(" 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);
+
+ drv_ctx.ptr_outputbuffer = (struct vdpp_bufferpayload *)\
+ calloc (sizeof(struct vdpp_bufferpayload),
+ drv_ctx.op_buf.actualcount);
+ drv_ctx.ptr_respbuffer = (struct vdpp_output_frameinfo *)\
+ calloc (sizeof (struct vdpp_output_frameinfo),
+ drv_ctx.op_buf.actualcount);
+#ifdef USE_ION
+ drv_ctx.op_buf_ion_info = (struct vdpp_ion *)\
+ calloc (sizeof(struct vdpp_ion),
+ drv_ctx.op_buf.actualcount);
+
+ if (!drv_ctx.op_buf_ion_info) {
+ DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
+ return OMX_ErrorInsufficientResources;
+ }
+#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;
+
+ DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
+
+ 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;
+ bufHdr->pBuffer = NULL;
+ bufHdr->nOffset = 0;
+
+ drv_ctx.ptr_outputbuffer[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(" 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++;
+
+ }
+ }
+ else
+ {
+ if(m_out_mem_ptr)
+ {
+ free(m_out_mem_ptr);
+ m_out_mem_ptr = 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 %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;
+
+ drv_ctx.ptr_outputbuffer[i].buffer_len =
+ drv_ctx.op_buf.buffer_size;
+
+ *bufferHdr = (m_out_mem_ptr + i );
+ drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
+
+#ifndef STUB_VPU
+ 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_vpu_fd, VIDIOC_STREAMON,&buf_type);
+ if (rc) {
+ DEBUG_PRINT_ERROR("allocate_output_buffer STREAMON failed \n ");
+ return OMX_ErrorInsufficientResources;
+ } else {
+ streaming[CAPTURE_PORT] = true;
+ DEBUG_PRINT_HIGH("allocate_output_buffer STREAMON Successful \n ");
+ }
+ }
+#endif
+
+ (*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_vdpp::AllocateBuffer
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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 \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)
+ {
+ eRet = allocate_input_heap_buffer(hComp,bufferHdr,port,appData,bytes);
+ }
+ else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
+ {
+ 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 == 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_vdpp::FreeBuffer
+
+DESCRIPTION
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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 vdpp 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(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(!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(" Free pmem Buffer index %d",nPortIndex);
+ if(m_phdr_pmem_ptr)
+ free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
+ }
+ 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 \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 - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
+ 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;
+ 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_vdpp::EmptyThisBuffer
+
+DESCRIPTION
+ This routine is used to push the video frames to VDPP.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything went successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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;
+
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer buffer = %p, buffer->pBuffer = %p, buffer->pPlatformPrivate = %p, buffer->nFilledLen = %lu\n",
+ // buffer, buffer->pBuffer, buffer->pPlatformPrivate, buffer->nFilledLen);
+ if(m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ if (buffer == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ if (!m_inp_bEnabled)
+ {
+ DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
+ {
+ DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ 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]; // change heap buffer address to ION buffer address
+ //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("ERROR:ETB nBufferIndex is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ DEBUG_PRINT_HIGH("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
+ buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
+
+ set_frame_rate(buffer->nTimeStamp);
+ post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
+
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::empty_this_buffer_proxy
+
+DESCRIPTION
+ This routine is used to push the video decoder output frames to
+ the VDPP.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything went successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ int i=0;
+ unsigned nPortIndex = 0;
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ struct vdpp_bufferpayload *temp_buffer;
+ unsigned p1 = 0;
+ unsigned p2 = 0;
+
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 1\n");
+ /*Should we generate a Aync error event*/
+ if (buffer == NULL || buffer->pInputPortPrivate == NULL)
+ {
+ DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
+ return OMX_ErrorBadParameter;
+ }
+
+ nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
+ DEBUG_PRINT_HIGH("omx_vdpp::empty_this_buffer_proxy 2 nPortIndex = %d, buffer->nFilledLen = %lu\n", nPortIndex, buffer->nFilledLen);
+ if (nPortIndex > drv_ctx.ip_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
+ nPortIndex);
+ return OMX_ErrorBadParameter;
+ }
+
+ pending_input_buffers++;
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 3 pending_input_buffers = %d\n", pending_input_buffers);
+ /* return zero length and not an EOS buffer */
+ if ((buffer->nFilledLen == 0) &&
+ ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
+ {
+ DEBUG_PRINT_HIGH(" return zero legth buffer");
+ post_event ((unsigned int)buffer,VDPP_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorNone;
+ }
+
+ // check OMX_BUFFERFLAG_EXTRADATA for interlaced information
+ // and set it to drv_ctx.interlace if returned interlace mode
+ // doesn't match drv_ctx.interlace.
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 3 buffer->nFlags = 0x%x interlace_user_flag = %d ", buffer->nFlags, interlace_user_flag);
+ if(((buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) != 0) && (false == interlace_user_flag))
+ {
+ OMX_OTHER_EXTRADATATYPE *pExtra;
+ v4l2_field field = drv_ctx.interlace;// V4L2_FIELD_NONE;
+ OMX_U8 *pTmp = buffer->pBuffer + buffer->nOffset + 3;
+
+ pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U32) pTmp) & ~3);
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 3 buffer->nFlags = 0x%x, pExtra->eType = 0x%x\n", buffer->nFlags, pExtra->eType);
+ // traverset the list of extra data sections
+ while(OMX_ExtraDataNone != pExtra->eType)
+ {
+ if(OMX_ExtraDataInterlaceFormat == (OMX_QCOM_EXTRADATATYPE)pExtra->eType)
+ {
+ OMX_STREAMINTERLACEFORMAT *interlace_format;
+ interlace_format = (OMX_STREAMINTERLACEFORMAT *)pExtra->data;
+
+ switch (interlace_format->nInterlaceFormats)
+ {
+ case OMX_InterlaceFrameProgressive:
+ {
+ field = V4L2_FIELD_NONE;
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy V4L2_FIELD_NONE");
+ break;
+ }
+ case OMX_InterlaceInterleaveFrameTopFieldFirst:
+ {
+ field = V4L2_FIELD_INTERLACED_TB;
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy V4L2_FIELD_INTERLACED_TB");
+ break;
+ }
+ case OMX_InterlaceInterleaveFrameBottomFieldFirst:
+ {
+ field = V4L2_FIELD_INTERLACED_BT;
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy V4L2_FIELD_INTERLACED_BT");
+ break;
+ }
+ case OMX_InterlaceFrameTopFieldFirst:
+ {
+ field = V4L2_FIELD_SEQ_TB;
+ break;
+ }
+ case OMX_InterlaceFrameBottomFieldFirst:
+ {
+ field = V4L2_FIELD_SEQ_BT;
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ }
+ pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) pExtra) + pExtra->nSize);
+ }
+
+ if(drv_ctx.interlace != field)
+ {
+ drv_ctx.interlace = field;
+
+ // set input port format based on the detected interlace mode
+ ret = set_buffer_req(&drv_ctx.ip_buf);
+ if(OMX_ErrorNone != ret)
+ {
+ DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid format setting");
+ return ret;
+ }
+ }
+ }
+
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 4 \n");
+ if(input_flush_progress == true)
+ {
+ DEBUG_PRINT_LOW(" Flush in progress return buffer ");
+ post_event ((unsigned int)buffer,VDPP_S_SUCCESS,
+ OMX_COMPONENT_GENERATE_EBD);
+ return OMX_ErrorNone;
+ }
+
+ temp_buffer = (struct vdpp_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_input_heap_buffer memcpy is used*/
+ temp_buffer->buffer_len = buffer->nFilledLen;
+
+
+ if (input_use_buffer)
+ {
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5 \n");
+ if (buffer->nFilledLen <= temp_buffer->buffer_len)
+ {
+ DEBUG_PRINT_HIGH("omx_vdpp::empty_this_buffer_proxy 5.1 temp_buffer->bufferaddr = %p, m_inp_heap_ptr[%d].pPlatformPrivate = %p, m_inp_heap_ptr[%d].nOffset = %lu\n",
+ temp_buffer->bufferaddr, nPortIndex, m_inp_heap_ptr[nPortIndex].pPlatformPrivate, nPortIndex, m_inp_heap_ptr[nPortIndex].nOffset);
+ //memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pPlatformPrivate + m_inp_heap_ptr[nPortIndex].nOffset),
+ // buffer->nFilledLen);
+ }
+ else
+ {
+ return OMX_ErrorBadParameter;
+ }
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5.2 \n");
+ }
+
+#ifdef INPUT_BUFFER_LOG
+ if ((inputBufferFile >= 0) && (input_buffer_write_counter < 10))
+ {
+ int stride = drv_ctx.video_resolution_input.stride; //w
+ int scanlines = drv_ctx.video_resolution_input.scan_lines; //h
+ DEBUG_PRINT_HIGH("omx_vdpp::empty_buffer_done 2.5 stride = %d, scanlines = %d , frame_height = %d", stride, scanlines, drv_ctx.video_resolution_input.frame_height);
+ char *temp = (char *)temp_buffer->bufferaddr;
+ unsigned i;
+ int bytes_written = 0;
+ for (i = 0; i < drv_ctx.video_resolution_input.frame_height; i++) {
+ bytes_written = write(inputBufferFile, temp, drv_ctx.video_resolution_input.frame_width);
+ temp += stride;
+ }
+ temp = (char *)(char *)temp_buffer->bufferaddr + stride * scanlines;
+ int stride_c = stride;
+ for(i = 0; i < drv_ctx.video_resolution_input.frame_height/2; i++) {
+ bytes_written += write(inputBufferFile, temp, drv_ctx.video_resolution_input.frame_width);
+ temp += stride_c;
+ }
+ input_buffer_write_counter++;
+ }
+
+ if(input_buffer_write_counter >= 10 )
+ {
+ close(inputBufferFile);
+ }
+#endif
+
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5.3 \n");
+ if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
+ {
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5.4 \n");
+ buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
+ }
+
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ int extra_idx = 0;
+ int rc;
+ unsigned long print_count;
+
+ memset( (void *)&buf, 0, sizeof(buf));
+ memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
+
+ if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
+ { buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
+ DEBUG_PRINT_HIGH("temp_buffer->buffer_len = %d, buffer->nFlags = 0x%lx \n", temp_buffer->buffer_len, buffer->nFlags) ;
+ DEBUG_PRINT_HIGH(" INPUT EOS reached \n") ;
+ }
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ // The following fills v4l2_buffer structure
+ buf.index = nPortIndex;
+ buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ buf.field = drv_ctx.interlace;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ buf.length = drv_ctx.input_num_planes;
+
+ // currently V4L2 driver just passes timestamp to maple FW, and maple FW
+ // pass the timestamp back to OMX
+ *(uint64_t *)(&buf.timestamp) = buffer->nTimeStamp;
+
+ plane[0].bytesused = drv_ctx.video_resolution_input.frame_width *
+ drv_ctx.video_resolution_input.frame_height *
+ drv_ctx.input_bytesperpixel[0];//buffer->nFilledLen = 0 at this stage
+ plane[0].length = paddedFrameWidth128(drv_ctx.video_resolution_input.frame_width) *
+ drv_ctx.video_resolution_input.frame_height *
+ drv_ctx.input_bytesperpixel[0];
+ plane[0].m.userptr = temp_buffer->pmem_fd;
+ plane[0].reserved[0] = 0;
+ extra_idx = EXTRADATA_IDX(drv_ctx.input_num_planes);
+ if ((extra_idx > 0) && (extra_idx < VIDEO_MAX_PLANES)) {
+ plane[extra_idx].bytesused = drv_ctx.video_resolution_input.frame_width *
+ drv_ctx.video_resolution_input.frame_height *
+ drv_ctx.input_bytesperpixel[extra_idx];
+ plane[extra_idx].length = paddedFrameWidth128(drv_ctx.video_resolution_input.frame_width) *
+ drv_ctx.video_resolution_input.frame_height *
+ drv_ctx.input_bytesperpixel[extra_idx];
+
+
+ plane[extra_idx].m.userptr = temp_buffer->pmem_fd;
+ plane[extra_idx].reserved[0] = plane[0].reserved[0] + drv_ctx.video_resolution_input.stride * drv_ctx.video_resolution_input.scan_lines;
+ } 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.input_num_planes;
+ /*DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy: buffer->nFilledLen = %d, plane[0].bytesused = %d plane[0].length = %d,\
+ plane[extra_idx].bytesused = %d, plane[extra_idx].length = %d, plane[extra_idx].data_offset = %d plane[0].data_offset = %d\
+ buf.timestamp.tv_sec = 0x%08x, buf.timestamp.tv_usec = 0x%08x\n",
+ buffer->nFilledLen, plane[0].bytesused, plane[0].length, plane[extra_idx].bytesused, plane[extra_idx].length, plane[extra_idx].data_offset, plane[0].data_offset,
+ buf.timestamp.tv_sec, buf.timestamp.tv_usec);
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy: buffer->nTimeStamp = 0x%016llx; buf.timestamp.tv_sec = 0x%08lx, buf.timestamp.tv_usec = 0x%08lx\n",
+ buffer->nTimeStamp, buf.timestamp.tv_sec, buf.timestamp.tv_usec);*/
+
+ input_qbuf_count++;
+
+#ifdef STUB_VPU
+
+#else
+ rc = ioctl(drv_ctx.video_vpu_fd, VIDIOC_QBUF, &buf);
+ if(rc)
+ {
+ DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
+ return OMX_ErrorHardware;
+ }
+#endif
+
+ //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 15 \n");
+#ifndef STUB_VPU
+ if(!streaming[OUTPUT_PORT])
+ {
+ enum v4l2_buf_type buf_type;
+ int ret,r;
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 16 \n");
+ buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
+ ret=ioctl(drv_ctx.video_vpu_fd, VIDIOC_STREAMON,&buf_type);
+ if(!ret) {
+ DEBUG_PRINT_HIGH("V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE STREAMON Successful \n");
+ streaming[OUTPUT_PORT] = true;
+ } else{
+ DEBUG_PRINT_ERROR(" \n Failed to call streamon on V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \n");
+ return OMX_ErrorInsufficientResources;
+ }
+}
+#endif
+
+#ifdef STUB_VPU
+ drv_ctx.etb_ftb_info.etb_cnt++;
+ DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 15 drv_ctx.etb_ftb_info.etb_cnt = %d\n", drv_ctx.etb_ftb_info.etb_cnt);
+ m_index_q_etb.insert_entry(p1,p2,nPortIndex);
+ //drv_ctx.etb_ftb_info.etb_index = nPortIndex;
+ drv_ctx.etb_ftb_info.etb_len = buf.length;
+ sem_post (&(drv_ctx.async_lock));
+#endif
+ return ret;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::FillThisBuffer
+
+DESCRIPTION
+ IL client uses this method to release the frame buffer
+ after displaying them.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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("ERROR:FTB incorrect state operation, output port is disabled.");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (buffer == NULL ||
+ ((buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount))
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
+ {
+ DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+ //DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu", buffer, buffer->pBuffer, buffer->nFilledLen);
+ post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
+
+ return OMX_ErrorNone;
+}
+/* ======================================================================
+FUNCTION
+ omx_vdpp::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_vdpp::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 vdpp_bufferpayload *ptr_outputbuffer = NULL;
+ struct vdpp_output_frameinfo *ptr_respbuffer = NULL;
+ private_handle_t *handle = NULL;
+
+ unsigned p1 = 0;
+ unsigned p2 = 0;
+
+ nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_out_mem_ptr);
+
+ if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
+ return OMX_ErrorBadParameter;
+
+ DEBUG_PRINT_HIGH(" FTBProxy: nPortIndex = %d, bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu",
+ nPortIndex, bufferAdd, bufferAdd->pBuffer, buffer->nFilledLen);
+
+ /*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++;
+
+ // set from allocate_output_headers
+ ptr_respbuffer = (struct vdpp_output_frameinfo*)buffer->pOutputPortPrivate;
+ if (ptr_respbuffer)
+ {
+ ptr_outputbuffer = (struct vdpp_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;
+ }
+
+ int rc = 0;
+ struct v4l2_buffer buf;
+ struct v4l2_plane plane[VIDEO_MAX_PLANES];
+ int extra_idx = 0;
+ memset( (void *)&buf, 0, sizeof(buf));
+ memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
+
+ buf.index = nPortIndex;
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ buf.memory = V4L2_MEMORY_USERPTR;
+ buf.field = V4L2_FIELD_ANY;
+
+ buf.length = drv_ctx.output_num_planes;
+ plane[0].bytesused = drv_ctx.video_resolution_output.frame_width *
+ drv_ctx.video_resolution_output.frame_height *
+ drv_ctx.output_bytesperpixel[0];
+ plane[0].length = paddedFrameWidth128(drv_ctx.video_resolution_output.frame_width) *
+ drv_ctx.video_resolution_output.frame_height *
+ drv_ctx.output_bytesperpixel[0];
+
+ plane[0].m.userptr = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
+ plane[0].reserved[0] = 0;
+ extra_idx = EXTRADATA_IDX(drv_ctx.output_num_planes);
+ if ((extra_idx > 0) && (extra_idx < VIDEO_MAX_PLANES)) {
+ plane[extra_idx].bytesused = drv_ctx.video_resolution_output.frame_width *
+ drv_ctx.video_resolution_output.frame_height *
+ drv_ctx.output_bytesperpixel[extra_idx];
+ plane[extra_idx].length = paddedFrameWidth128(drv_ctx.video_resolution_output.frame_width) *
+ drv_ctx.video_resolution_output.frame_height *
+ drv_ctx.output_bytesperpixel[extra_idx];
+ plane[extra_idx].m.userptr = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
+ plane[extra_idx].reserved[0] = plane[0].reserved[0] + drv_ctx.video_resolution_output.stride * drv_ctx.video_resolution_output.scan_lines;// plane[0].length;
+ } 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;
+ // DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy: buffer->nFilledLen = %lu, plane[0].bytesused = %d plane[0].length = %d, \
+ // plane[extra_idx].bytesused = %d, plane[extra_idx].reserved[0] = 0x%x\n", \
+ // buffer->nFilledLen, plane[0].bytesused, plane[0].length, plane[extra_idx].bytesused, plane[extra_idx].reserved[0]);
+ //
+ //DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy 2 drv_ctx.ptr_outputbuffer[%d].bufferaddr = %p\n", nPortIndex,drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr);
+ //DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy 2 drv_ctx.ptr_outputbuffer[%d].offset = %d", nPortIndex,drv_ctx.ptr_outputbuffer[nPortIndex].offset);
+
+#ifdef STUB_VPU
+
+#else
+ rc = ioctl(drv_ctx.video_vpu_fd, VIDIOC_QBUF, &buf);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to qbuf to driver");
+ return OMX_ErrorHardware;
+ }
+#endif
+
+ output_qbuf_count++;
+ DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy 3\n");
+#ifdef STUB_VPU
+{
+ drv_ctx.etb_ftb_info.ftb_cnt++;
+ m_index_q_ftb.insert_entry(p1,p2,nPortIndex);
+ drv_ctx.etb_ftb_info.ftb_len = drv_ctx.op_buf.buffer_size;
+ sem_post (&(drv_ctx.async_lock));
+ DEBUG_PRINT_HIGH("omx_vdpp::fill_this_buffer_proxy 4 nPortIndex = %d, drv_ctx.etb_ftb_info.ftb_cnt = %d, drv_ctx.etb_ftb_info.ftb_len = %d\n",
+ nPortIndex, drv_ctx.etb_ftb_info.ftb_cnt, drv_ctx.etb_ftb_info.ftb_len);
+}
+#endif
+ return OMX_ErrorNone;
+
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::SetCallbacks
+
+DESCRIPTION
+ Set the callbacks.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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_vdpp::ComponentDeInit
+
+DESCRIPTION
+ Destroys the component and release memory allocated to the heap.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ unsigned i = 0;
+ DEBUG_PRINT_HIGH(" omx_vdpp::component_deinit");
+ if (OMX_StateLoaded != m_state)
+ {
+ DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
+ m_state);
+ DEBUG_PRINT_ERROR("Playback Ended - FAILED");
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH(" 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]);
+ }
+ }
+
+ /*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<drv_ctx.ip_buf.actualcount; i++ )
+ {
+ if (m_inp_mem_ptr)
+ free_input_buffer (&m_inp_mem_ptr[i]);
+ }
+ }
+ free_input_buffer_header();
+ free_output_buffer_header();
+
+ // Reset counters in mesg queues
+ m_ftb_q.m_size=0;
+ m_cmd_q.m_size=0;
+ m_etb_q.m_size=0;
+ m_index_q_ftb.m_size=0;
+ m_index_q_etb.m_size=0;
+ m_ftb_q.m_read = m_ftb_q.m_write =0;
+ m_cmd_q.m_read = m_cmd_q.m_write =0;
+ m_etb_q.m_read = m_etb_q.m_write =0;
+ m_index_q_ftb.m_read = m_index_q_ftb.m_write =0;
+ m_index_q_etb.m_read = m_index_q_etb.m_write =0;
+#ifdef _ANDROID_
+ if (m_debug_timestamp)
+ {
+ m_timestamp_list.reset_ts_list();
+ }
+#endif
+
+ DEBUG_PRINT_HIGH(" Close the driver instance");
+
+#ifdef INPUT_BUFFER_LOG
+ if (inputBufferFile)
+ close (inputBufferFile);
+#endif
+#ifdef OUTPUT_BUFFER_LOG
+ if (outputBufferFile)
+ close(outputBufferFile);
+#endif
+#ifdef OUTPUT_EXTRADATA_LOG
+ if (outputExtradataFile)
+ fclose (outputExtradataFile);
+#endif
+
+ DEBUG_PRINT_HIGH(" omx_vdpp::component_deinit() complete");
+ return OMX_ErrorNone;
+}
+/* ======================================================================
+FUNCTION
+ omx_vdpp::UseEGLImage
+
+DESCRIPTION
+ OMX Use EGL Image method implementation <TBD>.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Not Implemented error.
+
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::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)
+{
+ return OMX_ErrorNone;
+}
+/* ======================================================================
+FUNCTION
+ omx_vdpp::ComponentRoleEnum
+
+DESCRIPTION
+ OMX Component Role Enum method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_vdpp::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_U8* role,
+ OMX_IN OMX_U32 index)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ // no component role (TODO add it later once component role is determined)
+/*
+ if(!strncmp(drv_ctx.kind, "OMX.qcom.video.vidpp",OMX_MAX_STRINGNAME_SIZE))
+ {
+ if((0 == index) && role)
+ {
+ strlcpy((char *)role, "video.vidpp",OMX_MAX_STRINGNAME_SIZE);
+ DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
+ }
+ else
+ {
+ eRet = OMX_ErrorNoMore;
+ }
+ }
+*/
+ return eRet;
+}
+
+
+
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::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_vdpp::allocate_done(void)
+{
+ bool bRet = false;
+ bool bRet_In = false;
+ bool bRet_Out = false;
+
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_done 1\n");
+ bRet_In = allocate_input_done();
+ bRet_Out = allocate_output_done();
+
+ if(bRet_In && bRet_Out)
+ {
+ bRet = true;
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_done 2\n");
+ }
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_done 3\n");
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+ omx_vdpp::AllocateInputDone
+
+DESCRIPTION
+ Checks if I/P buffer pool is allocated by IL Client or not.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false.
+
+========================================================================== */
+bool omx_vdpp::allocate_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0;
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 1\n");
+ if (m_inp_mem_ptr == NULL)
+ {
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 2\n");
+ return bRet;
+ }
+ if(m_inp_mem_ptr )
+ {
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 3\n");
+ for(;i<drv_ctx.ip_buf.actualcount;i++)
+ {
+ if(BITMASK_ABSENT(&m_inp_bm_count,i))
+ {
+ break;
+ }
+ }
+ }
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 4 i = %d, drv_ctx.ip_buf.actualcount = %d\n", i, drv_ctx.ip_buf.actualcount);
+ if(i == drv_ctx.ip_buf.actualcount)
+ {
+ //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 5\n");
+ bRet = true;
+ //DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
+ }
+ if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
+ {
+ m_inp_bPopulated = OMX_TRUE;
+ }
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+ omx_vdpp::AllocateOutputDone
+
+DESCRIPTION
+ Checks if entire O/P buffer pool is allocated by IL Client or not.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false.
+
+========================================================================== */
+bool omx_vdpp::allocate_output_done(void)
+{
+ bool bRet = false;
+ unsigned j=0;
+
+ if (m_out_mem_ptr == NULL)
+ {
+ return bRet;
+ }
+
+ if (m_out_mem_ptr)
+ {
+ for(;j < drv_ctx.op_buf.actualcount;j++)
+ {
+ if(BITMASK_ABSENT(&m_out_bm_count,j))
+ {
+ break;
+ }
+ }
+ }
+
+ if(j == drv_ctx.op_buf.actualcount)
+ {
+ bRet = true;
+ DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
+ if(m_out_bEnabled)
+ m_out_bPopulated = OMX_TRUE;
+ }
+
+ return bRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::ReleaseDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_vdpp::release_done(void)
+{
+ bool bRet = false;
+
+ if(release_input_done())
+ {
+ if(release_output_done())
+ {
+ bRet = true;
+ }
+ }
+ return bRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_vdpp::ReleaseOutputDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_vdpp::release_output_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("omx_vdpp::release_output_done Value of m_out_mem_ptr %p",m_inp_mem_ptr);
+ if(m_out_mem_ptr)
+ {
+ for(;j < drv_ctx.op_buf.actualcount ; j++)
+ {
+ if(BITMASK_PRESENT(&m_out_bm_count,j))
+ {
+ break;
+ }
+ }
+ if(j == drv_ctx.op_buf.actualcount)
+ {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ }
+ else
+ {
+ m_out_bm_count = 0;
+ bRet = true;
+ }
+ return bRet;
+}
+/* ======================================================================
+FUNCTION
+ omx_vdpp::ReleaseInputDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_vdpp::release_input_done(void)
+{
+ bool bRet = false;
+ unsigned i=0,j=0;
+
+ DEBUG_PRINT_LOW("omx_vdpp::release_input_done Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
+ if(m_inp_mem_ptr)
+ {
+ for(;j<drv_ctx.ip_buf.actualcount;j++)
+ {
+ if( BITMASK_PRESENT(&m_inp_bm_count,j))
+ {
+ break;
+ }
+ }
+ if(j==drv_ctx.ip_buf.actualcount)
+ {
+ bRet = true;
+ }
+ }
+ else
+ {
+ bRet = true;
+ }
+ return bRet;
+}
+
+OMX_ERRORTYPE omx_vdpp::fill_buffer_done(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE * buffer)
+{
+ OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
+ //DEBUG_PRINT_LOW(" fill_buffer_done 1 : bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu",
+ // buffer, buffer->pBuffer, buffer->nFilledLen);
+
+ if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
+ {
+ DEBUG_PRINT_ERROR(" [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_HIGH(" fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu, buffer->nFlags = 0x%x",
+ buffer, buffer->pBuffer, buffer->nFilledLen, buffer->nFlags);
+ pending_output_buffers --;
+ output_dqbuf_count++;
+ if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ DEBUG_PRINT_HIGH(" 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(" In fill Buffer done call address %p , buffer->nFilledLen = %lu",buffer, buffer->nFilledLen);
+#ifdef OUTPUT_BUFFER_LOG
+ DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 1.5, output_buffer_write_counter = %d", output_buffer_write_counter);
+ if(outputBufferFile < 0)
+ {
+ DEBUG_PRINT_ERROR(" Failed to create outputBufferFile \n");
+ }
+ if (outputBufferFile && buffer->nFilledLen && (output_buffer_write_counter <= 10))
+ {
+ DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 2");
+ int buf_index = buffer - m_out_mem_ptr;
+ int stride = drv_ctx.video_resolution_output.stride; //w
+ int scanlines = drv_ctx.video_resolution_output.scan_lines; //h
+ char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; // mmap ION buffer addr
+ unsigned i;
+ int bytes_written = 0;
+ for (i = 0; i < drv_ctx.video_resolution_output.frame_height; i++) {
+ bytes_written = write(outputBufferFile, temp, drv_ctx.video_resolution_output.frame_width);
+ 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_output.frame_height/2; i++) {
+ bytes_written += write(outputBufferFile, temp, drv_ctx.video_resolution_output.frame_width);
+ temp += stride_c;
+ }
+ output_buffer_write_counter++;
+
+ if(output_buffer_write_counter > 10)
+ {
+ close(outputBufferFile);
+ DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 2.9 close ");
+ }
+ }
+#endif
+ //DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 3");
+
+ if (m_cb.FillBufferDone)
+ {
+ //DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 4");
+
+ if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
+ prev_ts = LLONG_MAX;
+ rst_prev_ts = true;
+ }
+
+ DEBUG_PRINT_HIGH("omx_vdpp::fill_buffer_done 5 ");
+ m_cb.FillBufferDone (hComp,m_app_data, buffer);
+ DEBUG_PRINT_HIGH(" After Fill Buffer Done callback");
+
+ }
+ else
+ {
+ return OMX_ErrorBadParameter;
+ }
+
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_vdpp::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(" 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--;
+ input_dqbuf_count++;
+
+ if(m_cb.EmptyBufferDone)
+ {
+ buffer->nFilledLen = 0;
+ if (input_use_buffer == true){
+ buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
+ }
+ DEBUG_PRINT_HIGH("!!! empty_buffer_done before callback: buffer = %p\n", buffer);
+ m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
+ }
+ return OMX_ErrorNone;
+}
+
+int omx_vdpp::async_message_process (void *context, void* message)
+{
+ omx_vdpp* omx = NULL;
+ struct vdpp_msginfo *vdpp_msg = NULL;
+ OMX_BUFFERHEADERTYPE* omxhdr = NULL;
+ struct v4l2_buffer *v4l2_buf_ptr = NULL;
+ struct vdpp_output_frameinfo *output_respbuf = NULL;
+ int rc=1;
+ //DEBUG_PRINT_LOW("async_message_process 0\n");
+ if (context == NULL || message == NULL)
+ {
+ DEBUG_PRINT_ERROR(" FATAL ERROR in omx_vdpp::async_message_process NULL Check");
+ return -1;
+ }
+ //DEBUG_PRINT_LOW("async_message_process 1\n");
+ vdpp_msg = (struct vdpp_msginfo *)message;
+
+ omx = reinterpret_cast<omx_vdpp*>(context);
+
+ switch (vdpp_msg->msgcode)
+ {
+
+ case VDPP_MSG_EVT_HW_ERROR:
+ omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
+ OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+ break;
+
+ case VDPP_MSG_RESP_START_DONE:
+ omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
+ OMX_COMPONENT_GENERATE_START_DONE);
+ break;
+
+ case VDPP_MSG_RESP_STOP_DONE:
+ omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
+ OMX_COMPONENT_GENERATE_STOP_DONE);
+ break;
+
+ case VDPP_MSG_RESP_RESUME_DONE:
+ omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
+ OMX_COMPONENT_GENERATE_RESUME_DONE);
+ break;
+
+ case VDPP_MSG_RESP_PAUSE_DONE:
+ omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
+ OMX_COMPONENT_GENERATE_PAUSE_DONE);
+ break;
+
+ case VDPP_MSG_RESP_FLUSH_INPUT_DONE:
+ omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
+ OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
+ break;
+ case VDPP_MSG_RESP_FLUSH_OUTPUT_DONE:
+ omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
+ OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
+ break;
+ case VDPP_MSG_RESP_INPUT_FLUSHED:
+ case VDPP_MSG_RESP_INPUT_BUFFER_DONE:
+ //DEBUG_PRINT_LOW(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 0");
+ v4l2_buf_ptr = (v4l2_buffer*)vdpp_msg->msgdata.input_frame_clientdata;
+ // Use v4l2_buf_ptr->index returned by VPU V4L2 driver to index into
+ // m_inp_mem_ptr. v4l2 driver right now returns the same index used in QBUF
+ // In the future the returned ION handle could be used in empty_buffer_done.
+ omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
+ DEBUG_PRINT_LOW(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 1 v4l2_buf_ptr->index = %d", v4l2_buf_ptr->index);
+ if (omxhdr == NULL ||
+ ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
+ {
+ //DEBUG_PRINT_ERROR(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 2");
+ omxhdr = NULL;
+ vdpp_msg->status_code = VDPP_S_EFATAL;
+ }
+ //DEBUG_PRINT_LOW(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 3");
+ // No need to update the omxhdr->nFilledLen using the plane[0].len + plane[1].len here.
+ // based on OMX 3.1.2.9.2, nFilledLen = 0 if input buffer is completely consumed in ebd.
+ // also refer to ebd code
+ omx->post_event ((unsigned int)omxhdr,vdpp_msg->status_code,
+ OMX_COMPONENT_GENERATE_EBD);
+ break;
+ case VDPP_MSG_RESP_OUTPUT_FLUSHED:
+ case VDPP_MSG_RESP_OUTPUT_BUFFER_DONE:
+
+ v4l2_buf_ptr = (v4l2_buffer*)vdpp_msg->msgdata.output_frame.client_data;
+ omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
+ DEBUG_PRINT_LOW("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 1 v4l2_buf_ptr->index = %d\n", v4l2_buf_ptr->index);
+
+ if (omxhdr && omxhdr->pOutputPortPrivate &&
+ ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
+ (((struct vdpp_output_frameinfo *)omxhdr->pOutputPortPrivate
+ - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
+ {
+ if ( vdpp_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
+ {
+ //DEBUG_PRINT_LOW("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 2, vdpp_msg->msgdata.output_frame.len = %d, omxhdr->nAllocLen = %ld\n", vdpp_msg->msgdata.output_frame.len, omxhdr->nAllocLen);
+ omxhdr->nFilledLen = vdpp_msg->msgdata.output_frame.len;
+ omxhdr->nOffset = vdpp_msg->msgdata.output_frame.offset;
+ omxhdr->nTimeStamp = vdpp_msg->msgdata.output_frame.time_stamp;
+ omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
+
+ //DEBUG_PRINT_LOW("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 2.5 omxhdr->nFilledLen = %ld\n", omxhdr->nFilledLen);
+ if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)
+ {
+ omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
+ //rc = -1;
+ }
+
+ // use mmaped ION buffer address
+ vdpp_msg->msgdata.output_frame.bufferaddr =
+ omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
+
+ output_respbuf = (struct vdpp_output_frameinfo *)\
+ omxhdr->pOutputPortPrivate;
+ output_respbuf->len = vdpp_msg->msgdata.output_frame.len;
+ output_respbuf->offset = vdpp_msg->msgdata.output_frame.offset;
+
+ if (omx->output_use_buffer)
+ memcpy ( omxhdr->pBuffer, (void *)
+ ((unsigned long)vdpp_msg->msgdata.output_frame.bufferaddr +
+ (unsigned long)vdpp_msg->msgdata.output_frame.offset),
+ vdpp_msg->msgdata.output_frame.len);
+ }
+ else
+ omxhdr->nFilledLen = 0;
+
+ //DEBUG_PRINT_HIGH("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 4 omxhdr->nFilledLen = %ld, OMX_COMPONENT_GENERATE_FBD = %d\n", omxhdr->nFilledLen, OMX_COMPONENT_GENERATE_FBD);
+
+ omx->post_event ((unsigned int)omxhdr, vdpp_msg->status_code,
+ OMX_COMPONENT_GENERATE_FBD);
+ }
+ else if (vdpp_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
+ omx->post_event ((unsigned int)NULL, vdpp_msg->status_code,
+ OMX_COMPONENT_GENERATE_EOS_DONE);
+ else
+ omx->post_event ((unsigned int)NULL, vdpp_msg->status_code,
+ OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+ break;
+ case VDPP_MSG_EVT_CONFIG_CHANGED:
+ DEBUG_PRINT_HIGH(" Port settings changed");
+ omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
+ OMX_COMPONENT_GENERATE_PORT_RECONFIG);
+ break;
+ case VDPP_MSG_EVT_ACTIVE_REGION_DETECTION_STATUS:
+ {
+ struct v4l2_rect * p_ar_result = &(vdpp_msg->msgdata.ar_result);
+ DEBUG_PRINT_HIGH(" Active Region Detection Status");
+ omx->post_event ((unsigned int)p_ar_result,
+ vdpp_msg->status_code,
+ OMX_COMPONENT_GENERATE_ACTIVE_REGION_DETECTION_STATUS);
+ break;
+ }
+ default:
+ break;
+ }
+
+
+ return rc;
+}
+
+#ifndef USE_ION
+bool omx_vdpp::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(" Aligment(%u) failed with pmem driver Sz(%lu)",
+ allocation.align, allocation.size);
+ return false;
+ }
+ return true;
+}
+#endif
+#ifdef USE_ION
+int omx_vdpp::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 vdpp_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 | O_DSYNC);
+ 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->len = buffer_size;
+
+ // the following settings are from vpu_test.c
+ alloc_data->align = 16;
+ alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
+ alloc_data->flags = 0;
+
+ rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
+ if (rc || !alloc_data->handle) {
+ DEBUG_PRINT_ERROR(" 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(" 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_vdpp::free_ion_memory(struct vdpp_ion *buf_ion_info) {
+
+ if(!buf_ion_info) {
+ DEBUG_PRINT_ERROR(" 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(" 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_vdpp::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_vdpp::free_input_buffer_header()
+{
+ input_use_buffer = false;
+
+ 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
+}
+
+int omx_vdpp::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);
+#ifndef STUB_VPU
+ rc = ioctl(drv_ctx.video_vpu_fd, VIDIOC_STREAMOFF, &btype);
+ if (rc) {
+ DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
+ } else {
+ streaming[v4l2_port] = false;
+ }
+#endif
+
+ return rc;
+}
+
+// return buffer_prop->actualcount and buffer_prop->buffer_size
+// based on ip/op format
+#ifdef STUB_VPU
+OMX_ERRORTYPE omx_vdpp::get_buffer_req(vdpp_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_HIGH("omx_vdpp::get_buffer_req GetBufReq IN: ActCnt(%d) Size(%d)",
+ buffer_prop->actualcount, buffer_prop->buffer_size);
+
+ if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT){
+
+ bufreq.count = VP_INPUT_BUFFER_COUNT_INTERLACE;
+ }else if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_OUTPUT){
+
+ bufreq.count = VP_OUTPUT_BUFFER_COUNT;
+ }else
+ {
+ DEBUG_PRINT_HIGH("omx_vdpp:: wrong buffer type");
+ }
+
+ {
+ 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);
+ {
+ buffer_prop->buffer_size = drv_ctx.video_resolution_input.frame_height *
+ paddedFrameWidth128(drv_ctx.video_resolution_input.frame_width) *
+ 3 / 2; // hardcoded size for stub NV12
+ }
+ buf_size = buffer_prop->buffer_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;
+}
+
+// set buffer_prop->actualcount through VIDIOC_REQBUFS
+OMX_ERRORTYPE omx_vdpp::set_buffer_req(vdpp_allocatorproperty *buffer_prop)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned buf_size = 0;
+ struct v4l2_format fmt;
+ struct v4l2_requestbuffers bufreq;
+ int ret;
+ DEBUG_PRINT_HIGH("omx_vdpp::set_buffer_req 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;
+ }
+
+ return eRet;
+}
+#else
+// call VIDIOC_REQBUFS to set the initial number of buffers that app wants to
+// use in streaming
+// return buffer_prop->buffer_size and ip/op resolution based on ip/op format
+OMX_ERRORTYPE omx_vdpp::get_buffer_req(vdpp_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;
+
+ memset((void *)&fmt, 0, sizeof(v4l2_format));
+ memset((void *)&bufreq, 0, sizeof(v4l2_requestbuffers));
+ DEBUG_PRINT_HIGH("GetBufReq IN: ActCnt(%d) Size(%d) buffer_prop->buffer_type (%d), streaming[OUTPUT_PORT] (%d), streaming[CAPTURE_PORT] (%d)",
+ buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type, streaming[OUTPUT_PORT], streaming[CAPTURE_PORT]);
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ if(buffer_prop->buffer_type == VDPP_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;
+ bufreq.count = VP_INPUT_BUFFER_COUNT_INTERLACE;
+ }else if (buffer_prop->buffer_type == VDPP_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;
+ bufreq.count = VP_OUTPUT_BUFFER_COUNT;
+ }else {eRet = OMX_ErrorBadParameter;}
+ if(eRet==OMX_ErrorNone){
+ ret = ioctl(drv_ctx.video_vpu_fd,VIDIOC_REQBUFS, &bufreq);
+ }
+ if(ret)
+ {
+ DEBUG_PRINT_ERROR("GetBufReq Requesting buffer requirements failed 1");
+ 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->buffer_type(%d) fmt.fmt.pix_mp.pixelformat (0x%08x)",
+ buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type, fmt.fmt.pix_mp.pixelformat);
+
+ if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT)
+ {
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
+ if (V4L2_FIELD_NONE == drv_ctx.interlace)
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ }
+ else
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
+ }
+
+ }
+ else
+ {
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ }
+
+ //ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_G_FMT, &fmt);
+ // S_FMT is always called before get_buffer_req
+ // we should be able to use G_FMT to get fmt info.
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_TRY_FMT, &fmt);
+ //ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_G_FMT, &fmt);
+
+ if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT)
+ {
+ drv_ctx.input_num_planes = fmt.fmt.pix_mp.num_planes;
+ drv_ctx.video_resolution_input.frame_height = fmt.fmt.pix_mp.height;
+ drv_ctx.video_resolution_input.frame_width = fmt.fmt.pix_mp.width;
+ DEBUG_PRINT_HIGH("GetBufReq drv_ctx.video_resolution_input.frame_height = %d, drv_ctx.video_resolution_input.frame_width = %d ",
+ drv_ctx.video_resolution_input.frame_height, drv_ctx.video_resolution_input.frame_width);
+ }
+ else
+ {
+ drv_ctx.output_num_planes = fmt.fmt.pix_mp.num_planes;
+ drv_ctx.video_resolution_output.frame_height = fmt.fmt.pix_mp.height;
+ drv_ctx.video_resolution_output.frame_width = fmt.fmt.pix_mp.width;
+ DEBUG_PRINT_HIGH("GetBufReq drv_ctx.video_resolution_output.frame_height = %d, drv_ctx.video_resolution_output.frame_width = %d ",
+ drv_ctx.video_resolution_output.frame_height, drv_ctx.video_resolution_output.frame_width);
+ }
+
+ buffer_prop->frame_size = paddedFrameWidth32(fmt.fmt.pix_mp.height) *
+ paddedFrameWidth128(fmt.fmt.pix_mp.width) *
+ 3 / 2;
+ DEBUG_PRINT_HIGH("GetBufReq fmt.fmt.pix_mp.num_planes = %d, fmt.fmt.pix_mp.height = %d, fmt.fmt.pix_mp.width = %d, buffer_prop->frame_size = %d \n",
+ fmt.fmt.pix_mp.num_planes, fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width, buffer_prop->frame_size);
+
+
+ if(ret)
+ {
+ DEBUG_PRINT_ERROR("GetBufReq Requesting buffer requirements failed 2");
+ 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;
+ if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT)
+ {
+ extra_idx = EXTRADATA_IDX(drv_ctx.input_num_planes);
+ }
+ else
+ {
+ extra_idx = EXTRADATA_IDX(drv_ctx.output_num_planes);
+ }
+
+ if ((extra_idx > 0) && (extra_idx < VIDEO_MAX_PLANES)) {
+ extra_data_size = fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
+ DEBUG_PRINT_HIGH("omx_vdpp::get_buffer_req extra_data_size: %d\n", extra_data_size);
+ } 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)
+ {
+ DEBUG_PRINT_HIGH("Interlace extra data enabled!");
+ 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
+ }
+ // update buffer_prop->buffer_size to include plane 1 buffer size
+ // so only 1 ION buffer will be allocated for each input/output buffer
+ if (extra_data_size > 0)
+ {
+ buf_size += extra_data_size;
+ }
+
+ 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; // client_extra_data_size defaults to 0
+ 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->buffer_type(%d)",
+ buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type);
+ return eRet;
+}
+
+// set buffer_prop->actualcount through VIDIOC_REQBUFS
+OMX_ERRORTYPE omx_vdpp::set_buffer_req(vdpp_allocatorproperty *buffer_prop)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ unsigned buf_size = 0;
+ unsigned i = 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);
+ memset((void *)&fmt, 0, sizeof(v4l2_format));
+ memset((void *)&bufreq, 0, sizeof(v4l2_requestbuffers));
+ 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
+ {
+
+ if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT){
+ fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = output_capability;
+
+ if (V4L2_FIELD_NONE == drv_ctx.interlace)
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ }
+ else
+ {
+ fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
+ }
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
+
+ setFormatParams(output_capability, drv_ctx.input_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
+ drv_ctx.input_bytesperpixel[i] *
+ fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[0]); // both plane have the same plane stride
+ }
+ } else if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_OUTPUT) {
+ fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ fmt.fmt.pix_mp.pixelformat = capture_capability;
+ fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
+ fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
+ fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
+
+ setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
+ for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
+ {
+ fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
+ drv_ctx.output_bytesperpixel[i] *
+ fmt.fmt.pix_mp.height);
+ fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]);
+ DEBUG_PRINT_HIGH("set_buffer_req fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n ", i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
+ }
+ } else {eRet = OMX_ErrorBadParameter;}
+
+ ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
+ if (ret)
+ {
+ DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ else
+ {
+ DEBUG_PRINT_HIGH("set_buffer_req drv_ctx.interlace = %d", drv_ctx.interlace);
+ }
+
+ bufreq.memory = V4L2_MEMORY_USERPTR;
+ bufreq.count = buffer_prop->actualcount;
+ if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT) {
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+ } else if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_OUTPUT) {
+ bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+ } else {eRet = OMX_ErrorBadParameter;}
+
+ if (eRet==OMX_ErrorNone) {
+ ret = ioctl(drv_ctx.video_vpu_fd,VIDIOC_REQBUFS, &bufreq);
+ }
+
+ if (ret)
+ {
+ DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
+ 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;
+ }
+
+ }
+ return eRet;
+}
+#endif
+
+OMX_ERRORTYPE omx_vdpp::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if (!portDefn)
+ {
+ return OMX_ErrorBadParameter;
+ }
+ DEBUG_PRINT_LOW("omx_vdpp::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 (OMX_CORE_INPUT_PORT_INDEX == 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_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;//OMX_COLOR_FormatYUV420Planar;//OMX_COLOR_FormatUnused;
+ portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ portDefn->bEnabled = m_inp_bEnabled;
+ portDefn->bPopulated = m_inp_bPopulated;
+ portDefn->format.video.nFrameHeight = drv_ctx.video_resolution_input.frame_height;
+ portDefn->format.video.nFrameWidth = drv_ctx.video_resolution_input.frame_width;
+ portDefn->format.video.nStride = drv_ctx.video_resolution_input.stride;
+ portDefn->format.video.nSliceHeight = drv_ctx.video_resolution_input.scan_lines;
+ }
+ else if (OMX_CORE_OUTPUT_PORT_INDEX == portDefn->nPortIndex)
+ {
+ portDefn->eDir = OMX_DirOutput;
+ portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
+ portDefn->nBufferCountMin = drv_ctx.op_buf.mincount;
+ portDefn->nBufferSize = drv_ctx.op_buf.buffer_size;
+ portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
+ portDefn->bEnabled = m_out_bEnabled;
+ portDefn->bPopulated = m_out_bPopulated;
+ portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
+
+ // video_resolution_output.frame_height is retrieved from get_bufreq
+ portDefn->format.video.nFrameHeight = drv_ctx.video_resolution_output.frame_height;
+ portDefn->format.video.nFrameWidth = drv_ctx.video_resolution_output.frame_width;
+ portDefn->format.video.nStride = drv_ctx.video_resolution_output.stride;
+ portDefn->format.video.nSliceHeight = drv_ctx.video_resolution_output.scan_lines;
+ }
+ else
+ {
+ portDefn->eDir = OMX_DirMax;
+ DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
+ (int)portDefn->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ DEBUG_PRINT_HIGH("update_portdef for %lu Width = %lu Height = %lu Stride = %ld SliceHeight = %lu portDefn->format.video.eColorFormat = %d \n", portDefn->nPortIndex,
+ portDefn->format.video.nFrameWidth,
+ portDefn->format.video.nFrameHeight,
+ portDefn->format.video.nStride,
+ portDefn->format.video.nSliceHeight,
+ portDefn->format.video.eColorFormat);
+ return eRet;
+
+}
+
+OMX_ERRORTYPE omx_vdpp::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)\n",
+ drv_ctx.op_buf.actualcount);
+ nBufHdrSize = drv_ctx.op_buf.actualcount *
+ sizeof(OMX_BUFFERHEADERTYPE);
+
+ DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d \n",nBufHdrSize,
+ sizeof(OMX_BUFFERHEADERTYPE));
+
+ m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
+
+ drv_ctx.ptr_outputbuffer = (struct vdpp_bufferpayload *) \
+ calloc (sizeof(struct vdpp_bufferpayload),
+ drv_ctx.op_buf.actualcount);
+ drv_ctx.ptr_respbuffer = (struct vdpp_output_frameinfo *)\
+ calloc (sizeof (struct vdpp_output_frameinfo),
+ drv_ctx.op_buf.actualcount);
+#ifdef USE_ION
+ drv_ctx.op_buf_ion_info = (struct vdpp_ion * ) \
+ calloc (sizeof(struct vdpp_ion),drv_ctx.op_buf.actualcount);
+
+ if (!drv_ctx.op_buf_ion_info) {
+ DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
+ return OMX_ErrorInsufficientResources;
+ }
+#endif
+
+ if(m_out_mem_ptr && drv_ctx.ptr_outputbuffer
+ && drv_ctx.ptr_respbuffer)
+ {
+ bufHdr = m_out_mem_ptr;
+ DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
+
+ 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;
+ bufHdr->pBuffer = NULL; // since no buffer is allocated
+
+ 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++;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p]\n",\
+ m_out_mem_ptr);
+ if(m_out_mem_ptr)
+ {
+ free(m_out_mem_ptr);
+ m_out_mem_ptr = 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_vdpp::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("ERROR: 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("ERROR: fill_buffer_done() failed!\n");
+ omx_report_error ();
+ }
+ break;
+ }
+ }
+}
+
+void omx_vdpp::set_frame_rate(OMX_S64 act_timestamp)
+{
+// No framerate control on 8084 VPU. This API is for 8092.
+#ifdef FRC_ENABLE
+ 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(%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_vpu_fd, VIDIOC_S_PARM, &sparm))
+ {
+ DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
+ performance might be affected");
+ }
+
+ }
+ }
+ }
+ prev_ts = act_timestamp;
+#endif
+}
+
+void omx_vdpp::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;
+ }
+}
+
+OMX_ERRORTYPE omx_vdpp::enable_extradata(OMX_U32 requested_extradata, bool enable)
+{
+ OMX_ERRORTYPE ret = OMX_ErrorNone;
+ if(m_state != OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ DEBUG_PRINT_ERROR("enable_extradata: actual[%lx] requested[%lx] enable[%d]",
+ client_extradata, requested_extradata, enable);
+
+ if (enable)
+ client_extradata |= requested_extradata;
+ else
+ client_extradata = client_extradata & ~requested_extradata;
+
+ return ret;
+}
+
+void omx_vdpp::setFormatParams(int pixelFormat, double bytesperpixel[], unsigned char *planesCount)
+{
+ /*24 RGB-8-8-8 */
+ switch (pixelFormat)
+ {
+ case V4L2_PIX_FMT_RGB24:
+ *planesCount = 0;
+ bytesperpixel[0] = 3;
+ break;
+
+ /*32 ARGB-8-8-8-8 */
+ case V4L2_PIX_FMT_RGB32:
+ *planesCount = 0;
+ bytesperpixel[0] = 4;
+ break;
+
+ /*32 ARGB-2-10-10-10*/
+ case V4L2_PIX_FMT_XRGB2:
+ *planesCount = 0;
+ bytesperpixel[0] = 4;
+ break;
+
+ /*24 BGR-8-8-8 */
+ case V4L2_PIX_FMT_BGR24:
+ *planesCount = 0;
+ bytesperpixel[0] = 3;
+ break;
+
+ /*32 BGRX-8-8-8-8 */
+ case V4L2_PIX_FMT_BGR32:
+ *planesCount = 0;
+ bytesperpixel[0] = 4;
+ break;
+
+ /*32 XBGR-2-10-10-10*/
+ case V4L2_PIX_FMT_XBGR2:
+ *planesCount = 0;
+ bytesperpixel[0] = 4;
+ break;
+
+ /*12 YUV 4:2:0 semi-planar*/
+ case V4L2_PIX_FMT_NV12:
+ *planesCount = 2;
+ bytesperpixel[0] = 1;
+ bytesperpixel[1] = 0.5;
+ break;
+
+ /*12 YVU 4:2:0 semi-planar*/
+ case V4L2_PIX_FMT_NV21:
+ *planesCount = 2;
+ bytesperpixel[0] = 1;
+ bytesperpixel[1] = 0.5;
+ break;
+
+ /* 16 YUYV 4:2:2 interleaved*/
+ case V4L2_PIX_FMT_YUYV:
+ *planesCount = 2;
+ bytesperpixel[0] = 2;
+ bytesperpixel[1] = 0.5;
+ break;
+
+ /* 16 YVYU 4:2:2 interleaved*/
+ case V4L2_PIX_FMT_YVYU:
+ *planesCount = 1;
+ bytesperpixel[0] = 2;
+ break;
+
+ /* 16 VYUY 4:2:2 interleaved*/
+ case V4L2_PIX_FMT_VYUY:
+ *planesCount = 1;
+ bytesperpixel[0] = 2;
+ break;
+
+ /* 16 UYVY 4:2:2 interleaved*/
+ case V4L2_PIX_FMT_UYVY:
+ *planesCount = 1;
+ bytesperpixel[0] = 2;
+ break;
+
+ default:
+ DEBUG_PRINT_ERROR("%s: ERROR: pixel format %d is not supported!\n",
+ __func__, pixelFormat);
+ }
+
+}
+
+int omx_vdpp::openInput(const char* inputName)
+{
+ int fd = -1;
+ const char *dirname = "/sys/class/video4linux";
+ char devname[PATH_MAX];
+ char dev[PATH_MAX];
+ char *filename;
+ DIR *dir;
+ struct dirent *de;
+ dir = opendir(dirname);
+ if(dir == NULL)
+ return -1;
+ strlcpy(dev, dirname, sizeof(dev));
+ filename = dev + strlen(dev);
+ *filename++ = '/';
+ while((de = readdir(dir)))
+ {
+ if(de->d_name[0] == '.' &&
+ (de->d_name[1] == '\0' ||
+ (de->d_name[1] == '.' && de->d_name[2] == '\0')))
+ continue;
+ strlcpy(filename, de->d_name, PATH_MAX - sizeof(dev) - 1);
+ /*DEBUG_PRINT_LOW("Filename found: %s\n", filename);*/
+ char name[80];
+ int fd_devname;
+ int result;
+ strlcpy(devname, dev, sizeof(devname));
+ strlcat(devname, "/name", sizeof(devname));
+ /*DEBUG_PRINT_LOW("opening name file: %s\n", devname);*/
+ /* find and read device node names from sys/conf/video4linux dir*/
+ fd_devname = open(devname,O_RDONLY);
+ if(fd_devname < 0)
+ DEBUG_PRINT_ERROR("openInput: could not find device name.\n");
+ result = read(fd_devname, name, strlen(inputName));
+ if(result < 0)
+ {
+ DEBUG_PRINT_ERROR("openInput: could not read device name.\n");
+ }
+ else
+ {
+ if(!strcmp(name, inputName))
+ {
+ close(fd_devname);
+ /* open the vpu driver node found from /dev dir */
+ char temp[80];
+ strlcpy(temp, "/dev/", sizeof(temp));
+ strlcat(temp, filename, sizeof(temp));
+ DEBUG_PRINT_LOW("openInput: opening device: %s\n", temp);
+ fd = open(temp, O_RDWR | O_NONBLOCK);
+ if(fd < 0)
+ DEBUG_PRINT_ERROR("openInput: Error opening device %s\n", temp);
+ else
+ break;
+ }
+ }
+ close(fd_devname);
+ }
+ closedir(dir);
+ ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);
+ return fd;
+}