summaryrefslogtreecommitdiff
path: root/mm-video-v4l2
diff options
context:
space:
mode:
authorVaibhav Deshu Venkatesh <vdeshuve@codeaurora.org>2017-07-27 18:19:13 -0700
committerVaibhav Deshu Venkatesh <vdeshuve@codeaurora.org>2017-08-18 12:11:40 -0700
commitff86043037b4b58b16f3515a1536e3289a4709dd (patch)
tree0a7a63150a336c22363a02ef3754953c42cb15e2 /mm-video-v4l2
parentde6a3125066053967d448ad73ca95d4b9fe957fb (diff)
downloadmedia-ff86043037b4b58b16f3515a1536e3289a4709dd.tar.gz
mm-video-v4l2: Publish supported profile/level correctly
Get supported profile/level from driver and publish them correctly to client from OMX. CRs-Fixed: 2054346 Change-Id: I56c8d1631445e02dd0330d664802d044cce4a26e
Diffstat (limited to 'mm-video-v4l2')
-rw-r--r--mm-video-v4l2/vidc/common/inc/vidc_common.h66
-rw-r--r--mm-video-v4l2/vidc/common/src/vidc_common.cpp227
-rw-r--r--mm-video-v4l2/vidc/vdec/inc/omx_vdec.h1
-rw-r--r--mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp182
-rw-r--r--mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h3
-rw-r--r--mm-video-v4l2/vidc/venc/inc/omx_video_base.h3
-rw-r--r--mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h1
-rw-r--r--mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h2
-rw-r--r--mm-video-v4l2/vidc/venc/src/omx_video_base.cpp83
-rw-r--r--mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp5
-rw-r--r--mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp288
11 files changed, 552 insertions, 309 deletions
diff --git a/mm-video-v4l2/vidc/common/inc/vidc_common.h b/mm-video-v4l2/vidc/common/inc/vidc_common.h
new file mode 100644
index 00000000..012b246d
--- /dev/null
+++ b/mm-video-v4l2/vidc/common/inc/vidc_common.h
@@ -0,0 +1,66 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2017, 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 <unordered_map>
+
+using pl_map = std::unordered_map<int, int>;
+using codec_map = std::unordered_map<int, pl_map *>;
+
+class profile_level_converter {
+ static pl_map profile_avc_omx_to_v4l2;
+ static pl_map profile_hevc_omx_to_v4l2;
+ static pl_map profile_mpeg2_omx_to_v4l2;
+ static pl_map level_avc_omx_to_v4l2;
+ static pl_map level_hevc_omx_to_v4l2;
+ static pl_map level_vp8_omx_to_v4l2;
+ static pl_map level_mpeg2_omx_to_v4l2;
+ static pl_map profile_avc_v4l2_to_omx;
+ static pl_map profile_hevc_v4l2_to_omx;
+ static pl_map profile_mpeg2_v4l2_to_omx;
+ static pl_map level_avc_v4l2_to_omx;
+ static pl_map level_hevc_v4l2_to_omx;
+ static pl_map level_vp8_v4l2_to_omx;
+ static pl_map level_mpeg2_v4l2_to_omx;
+
+ static codec_map profile_omx_to_v4l2_map;
+ static codec_map profile_v4l2_to_omx_map;
+ static codec_map level_omx_to_v4l2_map;
+ static codec_map level_v4l2_to_omx_map;
+
+ //Constructor that initializes and performs the mapping
+ profile_level_converter() = delete;
+ static bool find_item(pl_map *map, int key, int *value);
+ static bool find_map(codec_map map, int key, pl_map **value_map);
+
+ public:
+ static void init();
+ static bool convert_v4l2_profile_to_omx(int codec, int v4l2_profile, int *omx_profile);
+ static bool convert_omx_profile_to_v4l2(int codec, int omx_profile, int *v4l2_profile);
+ static bool convert_v4l2_level_to_omx(int codec, int v4l2_level, int *omx_level);
+ static bool convert_omx_level_to_v4l2(int codec, int omx_level, int *v4l2_level);
+};
diff --git a/mm-video-v4l2/vidc/common/src/vidc_common.cpp b/mm-video-v4l2/vidc/common/src/vidc_common.cpp
index 931e7c53..6336ef38 100644
--- a/mm-video-v4l2/vidc/common/src/vidc_common.cpp
+++ b/mm-video-v4l2/vidc/common/src/vidc_common.cpp
@@ -30,5 +30,232 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <utils/Log.h>
#include "vidc_debug.h"
+#include "vidc_common.h"
+#include "OMX_Core.h"
+#include "OMX_QCOMExtns.h"
+#include "OMX_VideoExt.h"
+#include "OMX_IndexExt.h"
+#include <linux/videodev2.h>
int debug_level = PRIO_ERROR;
+
+
+pl_map profile_level_converter::profile_avc_omx_to_v4l2 ({
+ {QOMX_VIDEO_AVCProfileConstrainedBaseline,
+ V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE},
+ {QOMX_VIDEO_AVCProfileBaseline,
+ V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE},
+ {QOMX_VIDEO_AVCProfileMain,
+ V4L2_MPEG_VIDEO_H264_PROFILE_MAIN},
+ {QOMX_VIDEO_AVCProfileConstrainedHigh,
+ V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH},
+ {QOMX_VIDEO_AVCProfileHigh,
+ V4L2_MPEG_VIDEO_H264_PROFILE_HIGH}
+ });
+
+pl_map profile_level_converter::profile_avc_v4l2_to_omx ({});
+
+pl_map profile_level_converter::profile_hevc_omx_to_v4l2 ({
+ {OMX_VIDEO_HEVCProfileMain,
+ V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN},
+ {OMX_VIDEO_HEVCProfileMain10,
+ V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10},
+ });
+
+pl_map profile_level_converter::profile_hevc_v4l2_to_omx ({});
+
+pl_map profile_level_converter::profile_mpeg2_omx_to_v4l2 ({
+ {OMX_VIDEO_MPEG2ProfileSimple,
+ V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_SIMPLE},
+ {OMX_VIDEO_MPEG2ProfileMain,
+ V4L2_MPEG_VIDC_VIDEO_MPEG2_PROFILE_MAIN},
+ });
+
+pl_map profile_level_converter::profile_mpeg2_v4l2_to_omx ({});
+
+pl_map profile_level_converter::level_avc_omx_to_v4l2 ({
+ {OMX_VIDEO_AVCLevel1, V4L2_MPEG_VIDEO_H264_LEVEL_1_0},
+ {OMX_VIDEO_AVCLevel11, V4L2_MPEG_VIDEO_H264_LEVEL_1_1},
+ {OMX_VIDEO_AVCLevel12, V4L2_MPEG_VIDEO_H264_LEVEL_1_2},
+ {OMX_VIDEO_AVCLevel13, V4L2_MPEG_VIDEO_H264_LEVEL_1_3},
+ {OMX_VIDEO_AVCLevel1b, V4L2_MPEG_VIDEO_H264_LEVEL_1B},
+ {OMX_VIDEO_AVCLevel2, V4L2_MPEG_VIDEO_H264_LEVEL_2_0},
+ {OMX_VIDEO_AVCLevel21, V4L2_MPEG_VIDEO_H264_LEVEL_2_1},
+ {OMX_VIDEO_AVCLevel22, V4L2_MPEG_VIDEO_H264_LEVEL_2_2},
+ {OMX_VIDEO_AVCLevel3, V4L2_MPEG_VIDEO_H264_LEVEL_3_0},
+ {OMX_VIDEO_AVCLevel31, V4L2_MPEG_VIDEO_H264_LEVEL_3_1},
+ {OMX_VIDEO_AVCLevel32, V4L2_MPEG_VIDEO_H264_LEVEL_3_2},
+ {OMX_VIDEO_AVCLevel4, V4L2_MPEG_VIDEO_H264_LEVEL_4_0},
+ {OMX_VIDEO_AVCLevel41, V4L2_MPEG_VIDEO_H264_LEVEL_4_1},
+ {OMX_VIDEO_AVCLevel42, V4L2_MPEG_VIDEO_H264_LEVEL_4_2},
+ {OMX_VIDEO_AVCLevel5, V4L2_MPEG_VIDEO_H264_LEVEL_5_0},
+ {OMX_VIDEO_AVCLevel51, V4L2_MPEG_VIDEO_H264_LEVEL_5_1},
+ {OMX_VIDEO_AVCLevel52, V4L2_MPEG_VIDEO_H264_LEVEL_5_2},
+ });
+
+pl_map profile_level_converter::level_avc_v4l2_to_omx ({});
+
+pl_map profile_level_converter::level_hevc_omx_to_v4l2 ({
+ {OMX_VIDEO_HEVCMainTierLevel1, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1},
+ {OMX_VIDEO_HEVCMainTierLevel2, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2},
+ {OMX_VIDEO_HEVCMainTierLevel21, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1},
+ {OMX_VIDEO_HEVCMainTierLevel3, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3},
+ {OMX_VIDEO_HEVCMainTierLevel31, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1},
+ {OMX_VIDEO_HEVCMainTierLevel4, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4},
+ {OMX_VIDEO_HEVCMainTierLevel41, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1},
+ {OMX_VIDEO_HEVCMainTierLevel5, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5},
+ {OMX_VIDEO_HEVCMainTierLevel51, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1},
+ {OMX_VIDEO_HEVCMainTierLevel52, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2},
+ {OMX_VIDEO_HEVCMainTierLevel6, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6},
+ {OMX_VIDEO_HEVCMainTierLevel61, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1},
+ {OMX_VIDEO_HEVCMainTierLevel62, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2},
+ {OMX_VIDEO_HEVCHighTierLevel1, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1},
+ {OMX_VIDEO_HEVCHighTierLevel2, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2},
+ {OMX_VIDEO_HEVCHighTierLevel21, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1},
+ {OMX_VIDEO_HEVCHighTierLevel3, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3},
+ {OMX_VIDEO_HEVCHighTierLevel31, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1},
+ {OMX_VIDEO_HEVCHighTierLevel4, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4},
+ {OMX_VIDEO_HEVCHighTierLevel41, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1},
+ {OMX_VIDEO_HEVCHighTierLevel5, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5},
+ {OMX_VIDEO_HEVCHighTierLevel51, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1},
+ {OMX_VIDEO_HEVCHighTierLevel52, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2},
+ {OMX_VIDEO_HEVCHighTierLevel6, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6},
+ {OMX_VIDEO_HEVCHighTierLevel61, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1},
+ {OMX_VIDEO_HEVCHighTierLevel62, V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_2},
+ });
+
+pl_map profile_level_converter::level_hevc_v4l2_to_omx ({});
+
+pl_map profile_level_converter::level_vp8_omx_to_v4l2 ({
+ {OMX_VIDEO_VP8Level_Version0, V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0},
+ {OMX_VIDEO_VP8Level_Version1, V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_1},
+ {OMX_VIDEO_VP8Level_Version2, V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_2},
+ {OMX_VIDEO_VP8Level_Version3, V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_3},
+ });
+
+pl_map profile_level_converter::level_vp8_v4l2_to_omx ({});
+
+pl_map profile_level_converter::level_mpeg2_omx_to_v4l2 ({
+ {OMX_VIDEO_MPEG2LevelLL, V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_0},
+ {OMX_VIDEO_MPEG2LevelML, V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_1},
+ {OMX_VIDEO_MPEG2LevelHL, V4L2_MPEG_VIDC_VIDEO_MPEG2_LEVEL_2},
+ });
+
+pl_map profile_level_converter::level_mpeg2_v4l2_to_omx ({});
+
+codec_map profile_level_converter::profile_omx_to_v4l2_map ({
+ {V4L2_PIX_FMT_H264, &profile_avc_omx_to_v4l2},
+ {V4L2_PIX_FMT_HEVC, &profile_hevc_omx_to_v4l2},
+ {V4L2_PIX_FMT_MPEG2, &profile_mpeg2_omx_to_v4l2},
+ });
+
+codec_map profile_level_converter::profile_v4l2_to_omx_map ({
+ {V4L2_PIX_FMT_H264, &profile_avc_v4l2_to_omx},
+ {V4L2_PIX_FMT_HEVC, &profile_hevc_v4l2_to_omx},
+ {V4L2_PIX_FMT_MPEG2, &profile_mpeg2_v4l2_to_omx},
+ });
+
+codec_map profile_level_converter::level_omx_to_v4l2_map ({
+ {V4L2_PIX_FMT_H264, &level_avc_omx_to_v4l2},
+ {V4L2_PIX_FMT_HEVC, &level_hevc_omx_to_v4l2},
+ {V4L2_PIX_FMT_MPEG2, &level_mpeg2_omx_to_v4l2},
+ {V4L2_PIX_FMT_VP8, &level_vp8_omx_to_v4l2},
+ /* VP9 uses same levels */
+ {V4L2_PIX_FMT_VP9, &level_vp8_omx_to_v4l2},
+ });
+
+codec_map profile_level_converter::level_v4l2_to_omx_map ({
+ {V4L2_PIX_FMT_H264, &level_avc_v4l2_to_omx},
+ {V4L2_PIX_FMT_HEVC, &level_hevc_v4l2_to_omx},
+ {V4L2_PIX_FMT_MPEG2, &level_mpeg2_v4l2_to_omx},
+ {V4L2_PIX_FMT_VP8, &level_vp8_v4l2_to_omx},
+ /* VP9 uses same levels */
+ {V4L2_PIX_FMT_VP9, &level_vp8_v4l2_to_omx},
+ });
+
+void reverse_map(pl_map source_map, pl_map &dest_map)
+{
+ pl_map::iterator it;
+
+ for(it = source_map.begin(); it != source_map.end(); it++) {
+ dest_map[it->second] = it->first;
+ }
+ return;
+}
+
+void profile_level_converter::init()
+{
+ reverse_map(profile_avc_omx_to_v4l2, profile_avc_v4l2_to_omx);
+ reverse_map(profile_hevc_omx_to_v4l2, profile_hevc_v4l2_to_omx);
+ reverse_map(profile_mpeg2_omx_to_v4l2, profile_mpeg2_v4l2_to_omx);
+ reverse_map(level_avc_omx_to_v4l2, level_avc_v4l2_to_omx);
+ reverse_map(level_hevc_omx_to_v4l2, level_hevc_v4l2_to_omx);
+ reverse_map(level_vp8_omx_to_v4l2, level_vp8_v4l2_to_omx);
+ reverse_map(level_mpeg2_omx_to_v4l2, level_mpeg2_v4l2_to_omx);
+}
+
+bool profile_level_converter::find_map(codec_map map, int key, pl_map **value_map)
+{
+ codec_map::iterator map_it;
+
+ map_it = map.find (key);
+ if (map_it == map.end()) {
+ DEBUG_PRINT_ERROR(" Invalid codec : %d Cannot find map for this codec", key);
+ return false;
+ }
+ *value_map = map_it->second;
+ return true;
+}
+
+bool profile_level_converter::find_item(pl_map *map, int key, int *value)
+{
+ pl_map::iterator it;
+
+ it = map->find (key);
+ if (it == map->end()) {
+ DEBUG_PRINT_ERROR(" Invalid key : %d Cannot find key in map ", key);
+ return false;
+ }
+ *value = it->second;
+ return true;
+}
+
+bool profile_level_converter::convert_v4l2_profile_to_omx(int codec, int v4l2_profile, int *omx_profile)
+{
+ pl_map *profile_map;
+
+ if (!find_map(profile_v4l2_to_omx_map, codec, &profile_map))
+ return false;
+
+ return find_item(profile_map, v4l2_profile, omx_profile);
+}
+
+bool profile_level_converter::convert_omx_profile_to_v4l2(int codec, int omx_profile, int *v4l2_profile)
+{
+ pl_map *profile_map;
+
+ if (!find_map(profile_omx_to_v4l2_map, codec, &profile_map))
+ return false;
+
+ return find_item(profile_map, omx_profile, v4l2_profile);
+}
+
+bool profile_level_converter::convert_v4l2_level_to_omx(int codec, int v4l2_level, int *omx_level)
+{
+ pl_map *level_map;
+
+ if (!find_map(level_v4l2_to_omx_map, codec, &level_map))
+ return false;
+
+ return find_item(level_map, v4l2_level, omx_level);
+}
+
+bool profile_level_converter::convert_omx_level_to_v4l2(int codec, int omx_level, int *v4l2_level)
+{
+ pl_map *level_map;
+
+ if (!find_map(level_omx_to_v4l2_map, codec, &level_map))
+ return false;
+
+ return find_item(level_map, omx_level, v4l2_level);
+}
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index a0fe4633..fe29239d 100644
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -1346,6 +1346,7 @@ class omx_vdec: public qc_omx_component
void convert_hdr_info_to_metadata(HDRStaticInfo& hdr_info, ColorMetaData &color_mdata);
void get_preferred_color_aspects(ColorAspects& preferredColorAspects);
void get_preferred_hdr_info(HDRStaticInfo& preferredHDRInfo);
+ bool vdec_query_cap(struct v4l2_queryctrl &cap);
};
enum instance_state {
diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
index 797cc49c..c18fd93b 100644
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -48,6 +48,7 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <unistd.h>
#include <errno.h>
#include "omx_vdec.h"
+#include "vidc_common.h"
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>
@@ -864,6 +865,8 @@ omx_vdec::omx_vdec(): m_error_propogated(false),
m_color_space = EXCEPT_BT2020;
init_color_aspects_map();
+
+ profile_level_converter::init();
}
static const int event_type[] = {
@@ -3376,78 +3379,131 @@ bool omx_vdec::post_event(unsigned long p1,
return bRet;
}
+bool inline omx_vdec::vdec_query_cap(struct v4l2_queryctrl &cap) {
+
+ if (ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCTRL, &cap)) {
+ DEBUG_PRINT_ERROR("Query caps for id = %u failed\n", cap.id);
+ return false;
+ }
+ return true;
+}
+
OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
{
OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ struct v4l2_queryctrl profile_cap, level_cap;
+ int v4l2_profile;
+ int avc_profiles[5] = { QOMX_VIDEO_AVCProfileConstrainedBaseline,
+ QOMX_VIDEO_AVCProfileBaseline,
+ QOMX_VIDEO_AVCProfileMain,
+ QOMX_VIDEO_AVCProfileConstrainedHigh,
+ QOMX_VIDEO_AVCProfileHigh };
+ int hevc_profiles[2] = { OMX_VIDEO_HEVCProfileMain,
+ OMX_VIDEO_HEVCProfileMain10 };
+ int mpeg2_profiles[2] = { OMX_VIDEO_MPEG2ProfileSimple,
+ OMX_VIDEO_MPEG2ProfileMain};
+
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_AVCLevel51;
- 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 if (profileLevelType->nProfileIndex == 2) {
- profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
- 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.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;
- }
+ memset(&level_cap, 0, sizeof(struct v4l2_queryctrl));
+ memset(&profile_cap, 0, sizeof(struct v4l2_queryctrl));
+
+ if (output_capability == V4L2_PIX_FMT_H264) {
+ level_cap.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+ profile_cap.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+ } else if (output_capability == V4L2_PIX_FMT_VP8 ||
+ output_capability == V4L2_PIX_FMT_VP9) {
+ level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
+ } else if (output_capability == V4L2_PIX_FMT_HEVC) {
+ level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
+ profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
+ } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
+ level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_LEVEL;
+ profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_MPEG2_PROFILE;
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported Invalid codec");
+ return OMX_ErrorInvalidComponent;
+ }
+
+ if (profile_cap.id) {
+ if(!vdec_query_cap(profile_cap)) {
+ DEBUG_PRINT_ERROR("Getting capabilities for profile failed");
+ return OMX_ErrorHardware;
+ }
+ }
+
+ if (level_cap.id) {
+ if(!vdec_query_cap(level_cap)) {
+ DEBUG_PRINT_ERROR("Getting capabilities for level failed");
+ return OMX_ErrorHardware;
+ }
+ }
+
+ /* Get the corresponding omx level from v4l2 level */
+ if (!profile_level_converter::convert_v4l2_level_to_omx(output_capability, level_cap.maximum, (int *)&profileLevelType->eLevel)) {
+ DEBUG_PRINT_ERROR("Invalid level, cannot find corresponding v4l2 level : %d ", level_cap.maximum);
+ return OMX_ErrorHardware;
+ }
+
+ /* For given profile index get corresponding profile that needs to be supported */
+ if (profileLevelType->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (output_capability == V4L2_PIX_FMT_H264) {
+ if (profileLevelType->nProfileIndex < (sizeof(avc_profiles)/sizeof(int))) {
+ profileLevelType->eProfile = avc_profiles[profileLevelType->nProfileIndex];
} else {
- DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
- eRet = OMX_ErrorNoMore;
+ DEBUG_PRINT_LOW("AVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ return OMX_ErrorNoMore;
+ }
+ } else if (output_capability == V4L2_PIX_FMT_VP8 ||
+ output_capability == V4L2_PIX_FMT_VP9) {
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
+ } else {
+ DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ return OMX_ErrorNoMore;
+ }
+ /* Driver has no notion of VP8 profile. Only one profile is supported. Return this */
+ return OMX_ErrorNone;
+ } else if (output_capability == V4L2_PIX_FMT_HEVC) {
+ if (profileLevelType->nProfileIndex < (sizeof(hevc_profiles)/sizeof(int))) {
+ profileLevelType->eProfile = hevc_profiles[profileLevelType->nProfileIndex];
+ } else {
+ DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ return OMX_ErrorNoMore;
+ }
+ } else if (output_capability == V4L2_PIX_FMT_MPEG2) {
+ if (profileLevelType->nProfileIndex < (sizeof(mpeg2_profiles)/sizeof(int))) {
+ profileLevelType->eProfile = mpeg2_profiles[profileLevelType->nProfileIndex];
+ } else {
+ DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ return 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;
}
+
+ /* Check if the profile is supported by driver or not */
+ /* During query caps of profile driver sends a mask of */
+ /* of all v4l2 profiles supported(in the flags field) */
+ if (!profile_level_converter::convert_omx_profile_to_v4l2(output_capability, profileLevelType->eProfile, &v4l2_profile)) {
+ DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
+ return OMX_ErrorHardware;
+ }
+
+ if(!((profile_cap.flags >> v4l2_profile) & 0x1)) {
+ DEBUG_PRINT_ERROR("%s: Invalid index corresponding profile not supported : %d ",__FUNCTION__, profileLevelType->eProfile);
+ eRet = OMX_ErrorNoMore;
+ }
+
+ 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;
}
diff --git a/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h b/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h
index 8c68ce3d..f3f72b61 100644
--- a/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h
+++ b/mm-video-v4l2/vidc/venc/inc/omx_swvenc_mpeg4.h
@@ -141,6 +141,9 @@ class omx_venc: public omx_video
OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE */*SupportedPattern*/) {
return false;
}
+ OMX_ERRORTYPE dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE */*profileLevelType*/) {
+ return OMX_ErrorNone;
+ }
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/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
index 12fcdf0c..d8981254 100644
--- a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -292,6 +292,7 @@ class omx_video: public qc_omx_component
virtual bool dev_buffer_ready_to_queue(OMX_BUFFERHEADERTYPE *buffer) = 0;
virtual bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
OMX_U32 * /*nMaxBLayers*/, OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE */*SupportedPattern*/) = 0;
+ virtual OMX_ERRORTYPE dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *) = 0;
#ifdef _ANDROID_ICS_
void omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer);
#endif
@@ -583,7 +584,7 @@ class omx_video: public qc_omx_component
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;
diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
index 7419c005..1b8f462d 100644
--- a/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
+++ b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
@@ -85,6 +85,7 @@ class omx_venc: public omx_video
bool dev_get_batch_size(OMX_U32 *);
bool dev_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
OMX_U32 * /*nMaxBLayers*/, OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE */*SupportedPattern*/);
+ OMX_ERRORTYPE dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *);
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/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
index e2f0ab54..165c0a82 100644
--- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
+++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -45,6 +45,7 @@ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "omx_video_common.h"
#include "omx_video_base.h"
#include "omx_video_encoder.h"
+#include "vidc_common.h"
#include <linux/videodev2.h>
#include <media/msm_vidc.h>
#include <poll.h>
@@ -337,6 +338,7 @@ class venc_dev
bool venc_get_batch_size(OMX_U32 *size);
bool venc_get_temporal_layer_caps(OMX_U32 * /*nMaxLayers*/,
OMX_U32 * /*nMaxBLayers*/, OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE */*SupportedPattern*/);
+ OMX_ERRORTYPE venc_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType);
bool venc_check_for_hybrid_hp(OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern);
bool venc_check_for_hierp(OMX_VIDEO_ANDROID_TEMPORALLAYERINGPATTERNTYPE ePattern);
int venc_find_hier_type(OMX_VIDEO_PARAM_ANDROID_TEMPORALLAYERINGTYPE &temporalSettings);
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
index a14fb60f..06a75161 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -1656,7 +1656,7 @@ OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
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);
+ eRet = dev_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);
@@ -4635,87 +4635,6 @@ void omx_video::complete_pending_buffer_done_cbs()
}
}
-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_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 (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_HEVCMainTierLevel51;
- } 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;
-}
-
#ifdef USE_ION
int omx_video::alloc_map_ion_memory(int size,
struct ion_allocation_data *alloc_data,
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
index 74be593c..659aa880 100644
--- a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -2199,6 +2199,11 @@ bool omx_venc::dev_get_temporal_layer_caps(OMX_U32 *nMaxLayers,
return handle->venc_get_temporal_layer_caps(nMaxLayers, nMaxBLayers, eSupportedPattern);
}
+OMX_ERRORTYPE omx_venc::dev_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
+{
+ return handle->venc_get_supported_profile_level(profileLevelType);
+}
+
bool omx_venc::dev_loaded_start()
{
return handle->venc_loaded_start();
diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
index 635c89b8..5f5ccfe6 100644
--- a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -200,6 +200,8 @@ venc_dev::venc_dev(class omx_venc *venc_class)
strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
mUseAVTimerTimestamps = false;
+
+ profile_level_converter::init();
}
venc_dev::~venc_dev()
@@ -983,6 +985,112 @@ int venc_dev::venc_set_format(int format)
return rc;
}
+OMX_ERRORTYPE venc_dev::venc_get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ struct v4l2_queryctrl profile_cap, level_cap;
+ int v4l2_profile;
+ int avc_profiles[5] = { QOMX_VIDEO_AVCProfileConstrainedBaseline,
+ QOMX_VIDEO_AVCProfileBaseline,
+ QOMX_VIDEO_AVCProfileMain,
+ QOMX_VIDEO_AVCProfileConstrainedHigh,
+ QOMX_VIDEO_AVCProfileHigh };
+ int hevc_profiles[2] = { OMX_VIDEO_HEVCProfileMain,
+ OMX_VIDEO_HEVCProfileMain10 };
+
+ if (!profileLevelType)
+ return OMX_ErrorBadParameter;
+
+ memset(&level_cap, 0, sizeof(struct v4l2_queryctrl));
+ memset(&profile_cap, 0, sizeof(struct v4l2_queryctrl));
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ level_cap.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
+ profile_cap.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ level_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
+ profile_cap.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
+ } else {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported Invalid codec");
+ return OMX_ErrorInvalidComponent;
+ }
+
+ if (profile_cap.id) {
+ if(!venc_query_cap(profile_cap)) {
+ DEBUG_PRINT_ERROR("Getting capabilities for profile failed");
+ return OMX_ErrorHardware;
+ }
+ }
+
+ if (level_cap.id) {
+ if(!venc_query_cap(level_cap)) {
+ DEBUG_PRINT_ERROR("Getting capabilities for level failed");
+ return OMX_ErrorHardware;
+ }
+ }
+
+ /* Get the corresponding omx level from v4l2 level */
+ if (!profile_level_converter::convert_v4l2_level_to_omx(m_sVenc_cfg.codectype, level_cap.maximum, (int *)&profileLevelType->eLevel)) {
+ DEBUG_PRINT_ERROR("Invalid level, cannot find corresponding v4l2 level : %d ", level_cap.maximum);
+ return OMX_ErrorHardware;
+ }
+
+ /* For given profile index get corresponding profile that needs to be supported */
+ if (profileLevelType->nPortIndex != 1) {
+ DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on output port only %u",
+ (unsigned int)profileLevelType->nPortIndex);
+ return OMX_ErrorBadPortIndex;
+ }
+
+ if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+ if (profileLevelType->nProfileIndex < (sizeof(avc_profiles)/sizeof(int))) {
+ profileLevelType->eProfile = avc_profiles[profileLevelType->nProfileIndex];
+ } else {
+ DEBUG_PRINT_LOW("AVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ return OMX_ErrorNoMore;
+ }
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
+ if (profileLevelType->nProfileIndex == 0) {
+ profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain;
+ } else {
+ DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ return OMX_ErrorNoMore;
+ }
+ /* Driver has no notion of VP8 profile and there is only one profile supported. Hence return here */
+ return OMX_ErrorNone;
+ } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+ if (profileLevelType->nProfileIndex < (sizeof(hevc_profiles)/sizeof(int))) {
+ profileLevelType->eProfile = hevc_profiles[profileLevelType->nProfileIndex];
+ } else {
+ DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+ (unsigned int)profileLevelType->nProfileIndex);
+ return OMX_ErrorNoMore;
+ }
+ }
+
+ /* Check if the profile is supported by driver or not */
+ /* During query caps of profile driver sends a mask of */
+ /* of all v4l2 profiles supported(in the flags field) */
+ if (!profile_level_converter::convert_omx_profile_to_v4l2(m_sVenc_cfg.codectype, profileLevelType->eProfile, &v4l2_profile)) {
+ DEBUG_PRINT_ERROR("Invalid profile, cannot find corresponding omx profile");
+ return OMX_ErrorHardware;
+ }
+
+ DEBUG_PRINT_INFO("v4l2 profile : %d flags : %d ", v4l2_profile, profile_cap.flags);
+ if(!((profile_cap.flags >> v4l2_profile) & 0x1)) {
+ DEBUG_PRINT_ERROR("%s: Invalid index corresponding profile not supported : %d ",__FUNCTION__, profileLevelType->eProfile);
+ eRet = OMX_ErrorNoMore;
+ }
+
+ 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;
+}
+
OMX_ERRORTYPE venc_dev::allocate_extradata(struct extradata_buffer_info *extradata_info, int flags)
{
if (extradata_info->allocated) {
@@ -4598,39 +4706,22 @@ bool venc_dev::venc_set_profile(OMX_U32 eProfile)
if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
- if (eProfile == OMX_VIDEO_AVCProfileBaseline) {
- control.value = V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE;
- } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedBaseline) {
- control.value = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE;
- } else if(eProfile == QOMX_VIDEO_AVCProfileConstrainedHigh) {
- control.value = V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH;
- } else if (eProfile == OMX_VIDEO_AVCProfileMain) {
- control.value = V4L2_MPEG_VIDEO_H264_PROFILE_MAIN;
- } else if (eProfile == OMX_VIDEO_AVCProfileHigh) {
- control.value = V4L2_MPEG_VIDEO_H264_PROFILE_HIGH;
- } else {
- DEBUG_PRINT_LOW("ERROR: Unsupported H.264 profile = %d", eProfile);
- return false;
- }
} else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
//In driver VP8 profile is hardcoded. No need to set anything from here
return true;
} else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
- if (eProfile == OMX_VIDEO_HEVCProfileMain) {
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
- } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
- } else {
- DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %d",
- eProfile);
- return false;
- }
} else {
DEBUG_PRINT_ERROR("Wrong CODEC");
return false;
}
+ if (!profile_level_converter::convert_omx_profile_to_v4l2(m_sVenc_cfg.codectype, eProfile, &control.value)) {
+ DEBUG_PRINT_ERROR("Cannot find v4l2 profile for OMX profile : %d Codec : %lu ",
+ eProfile, m_sVenc_cfg.codectype);
+ return false;
+ }
+
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);
@@ -4638,11 +4729,9 @@ bool venc_dev::venc_set_profile(OMX_U32 eProfile)
DEBUG_PRINT_ERROR("Failed to set control, id %#x, value %d", control.id, control.value);
return false;
}
-
DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
codec_profile.profile = control.value;
-
return true;
}
@@ -4656,64 +4745,7 @@ bool venc_dev::venc_set_level(OMX_U32 eLevel)
if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
- switch(eLevel) {
- case OMX_VIDEO_AVCLevel1:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_1_0;
- break;
- case OMX_VIDEO_AVCLevel1b:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_1B;
- break;
- case OMX_VIDEO_AVCLevel11:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_1_1;
- break;
- case OMX_VIDEO_AVCLevel12:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_1_2;
- break;
- case OMX_VIDEO_AVCLevel13:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_1_3;
- break;
- case OMX_VIDEO_AVCLevel2:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_2_0;
- break;
- case OMX_VIDEO_AVCLevel21:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_2_1;
- break;
- case OMX_VIDEO_AVCLevel22:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_2_2;
- break;
- case OMX_VIDEO_AVCLevel3:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_3_0;
- break;
- case OMX_VIDEO_AVCLevel31:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_3_1;
- break;
- case OMX_VIDEO_AVCLevel32:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_3_2;
- break;
- case OMX_VIDEO_AVCLevel4:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_4_0;
- break;
- case OMX_VIDEO_AVCLevel41:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_4_1;
- break;
- case OMX_VIDEO_AVCLevel42:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_4_2;
- break;
- case OMX_VIDEO_AVCLevel5:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_5_0;
- break;
- case OMX_VIDEO_AVCLevel51:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_5_1;
- break;
- case OMX_VIDEO_AVCLevel52:
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_5_2;
- break;
- case OMX_VIDEO_AVCLevelMax:
- case OMX_VIDEO_LEVEL_UNKNOWN:
- default: //Set max level possible as default so that invalid levels are non-fatal
- control.value = V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN;
- break;
- }
+ control.value = V4L2_MPEG_VIDEO_H264_LEVEL_UNKNOWN;
} else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
switch (eLevel) {
@@ -4737,93 +4769,23 @@ bool venc_dev::venc_set_level(OMX_U32 eLevel)
}
} else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
- switch (eLevel) {
- case OMX_VIDEO_HEVCMainTierLevel1:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
- break;
- case OMX_VIDEO_HEVCHighTierLevel1:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
- break;
- case OMX_VIDEO_HEVCMainTierLevel2:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
- break;
- case OMX_VIDEO_HEVCHighTierLevel2:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
- break;
- case OMX_VIDEO_HEVCMainTierLevel21:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
- break;
- case OMX_VIDEO_HEVCHighTierLevel21:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
- break;
- case OMX_VIDEO_HEVCMainTierLevel3:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
- break;
- case OMX_VIDEO_HEVCHighTierLevel3:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
- break;
- case OMX_VIDEO_HEVCMainTierLevel31:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
- break;
- case OMX_VIDEO_HEVCHighTierLevel31:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
- break;
- case OMX_VIDEO_HEVCMainTierLevel4:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
- break;
- case OMX_VIDEO_HEVCHighTierLevel4:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
- break;
- case OMX_VIDEO_HEVCMainTierLevel41:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
- break;
- case OMX_VIDEO_HEVCHighTierLevel41:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
- break;
- case OMX_VIDEO_HEVCMainTierLevel5:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
- break;
- case OMX_VIDEO_HEVCHighTierLevel5:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
- break;
- case OMX_VIDEO_HEVCMainTierLevel51:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
- break;
- case OMX_VIDEO_HEVCHighTierLevel51:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
- break;
- case OMX_VIDEO_HEVCMainTierLevel52:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
- break;
- case OMX_VIDEO_HEVCHighTierLevel52:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
- break;
- case OMX_VIDEO_HEVCMainTierLevel6:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
- break;
- case OMX_VIDEO_HEVCHighTierLevel6:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
- break;
- case OMX_VIDEO_HEVCMainTierLevel61:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
- break;
- case OMX_VIDEO_HEVCHighTierLevel61:
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
- break;
- case OMX_VIDEO_HEVCLevelMax:
- case OMX_VIDEO_LEVEL_UNKNOWN:
- default: //Set max level possible as default so that invalid levels are non-fatal
- control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN;
- break;
- }
+ control.value = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_UNKNOWN;
} else {
DEBUG_PRINT_ERROR("Wrong CODEC");
return false;
}
+ /* If OMX_VIDEO_LEVEL_*/
+ if (eLevel != OMX_VIDEO_LEVEL_UNKNOWN) {
+ if (!profile_level_converter::convert_omx_level_to_v4l2(m_sVenc_cfg.codectype, eLevel, &control.value)) {
+ DEBUG_PRINT_ERROR(" Cannot find v4l2 level for OMX level : %d Codec : %lu ",
+ eLevel, m_sVenc_cfg.codectype);
+ return false;
+ }
+ }
+
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, id %#x, value %d", control.id, control.value);
return false;