summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSrinu Gorle <sgorle@codeaurora.org>2015-05-21 00:08:24 +0530
committerSrinu Gorle <sgorle@codeaurora.org>2015-11-18 09:00:25 +0530
commit8be933c724ad0a94e906ef6084c3f098d47b1709 (patch)
tree4fe3f29bb6b42d366394b7cc101fc72068f72ce8
parent4c87b6599b942d86d9c757e391f39bc8d66811e6 (diff)
downloadandroid_hardware_qcom_media-8be933c724ad0a94e906ef6084c3f098d47b1709.tar.gz
android_hardware_qcom_media-8be933c724ad0a94e906ef6084c3f098d47b1709.tar.bz2
android_hardware_qcom_media-8be933c724ad0a94e906ef6084c3f098d47b1709.zip
mm-video-v4l2: vidc: vdec: Add support for downscalar in component
Downscalar is now supported in component. It will be enabled as well as disabled accordingly depending upon the clip resolution and max resolution supported by target. Change-Id: I1a90911600d3a100d7f905bea320d1c465df3178
-rw-r--r--mm-video-v4l2/vidc/vdec/inc/omx_vdec.h8
-rw-r--r--mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp237
2 files changed, 217 insertions, 28 deletions
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index a17624bb..a9145ee1 100644
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -455,7 +455,7 @@ class omx_vdec: public qc_omx_component
void buf_ref_add(int nPortIndex);
void buf_ref_remove();
OMX_ERRORTYPE set_dpb(bool is_split_mode, int dpb_color_format);
- OMX_ERRORTYPE decide_dpb_buffer_mode();
+ OMX_ERRORTYPE decide_dpb_buffer_mode(bool force_split_mode);
void request_perf_level(enum vidc_perf_level perf_level);
int dpb_bit_depth;
@@ -951,6 +951,7 @@ class omx_vdec: public qc_omx_component
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;
@@ -980,6 +981,11 @@ class omx_vdec: public qc_omx_component
OMX_ERRORTYPE enable_adaptive_playback(unsigned long width, unsigned long height);
bool is_thulium_v1;
static bool m_disable_ubwc_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;
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 5b79be67..3528f0ce 100644
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -752,6 +752,9 @@ omx_vdec::omx_vdec(): m_error_propogated(false),
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;
@@ -929,7 +932,7 @@ OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format)
}
-OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode()
+OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool force_split_mode)
{
OMX_ERRORTYPE eRet = OMX_ErrorNone;
@@ -942,14 +945,18 @@ OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode()
if (cpu_access) {
if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
- if (m_force_compressed_for_dpb || is_res_above_1080p) {
+ if ((m_force_compressed_for_dpb || is_res_above_1080p) &&
+ !force_split_mode) {
//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);
- }
+ //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
@@ -957,8 +964,14 @@ OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode()
}
} else { //no cpu access
if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
- //DPB-OPB combined UBWC
- eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
+ 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
@@ -971,6 +984,155 @@ OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode()
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;
+
+ 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;
+ }
+
+ DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d", __func__,
+ fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height);
+
+ if (fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) {
+ rc = enable_downscalar();
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
+ return rc;
+ }
+
+ OMX_U32 width = m_downscalar_width > fmt.fmt.pix_mp.width ?
+ fmt.fmt.pix_mp.width : m_downscalar_width;
+ OMX_U32 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;
+ }
+
+ rc = update_resolution(width, height,
+ VENUS_Y_STRIDE(color_format, width), VENUS_Y_SCANLINES(color_format, height));
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed \n", __func__, width, height);
+ return rc;
+ }
+ } else {
+
+ rc = disable_downscalar();
+ if (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
+ return rc;
+ }
+
+ rc = 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 (rc < 0) {
+ DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed\n", __func__, fmt.fmt.pix_mp.width,
+ fmt.fmt.pix_mp.height);
+ return rc;
+ }
+ }
+
+ 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;
+ 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
@@ -2238,6 +2400,25 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
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);
+#endif
m_state = OMX_StateLoaded;
#ifdef DEFAULT_EXTRADATA
if ((strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
@@ -2778,6 +2959,11 @@ OMX_ERRORTYPE omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
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) {
@@ -3218,7 +3404,7 @@ OMX_ERRORTYPE omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
(OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
- decide_dpb_buffer_mode();
+ decide_dpb_buffer_mode(is_down_scalar_enabled);
eRet = update_portdef(portDefn);
if (eRet == OMX_ErrorNone)
m_port_def = *portDefn;
@@ -3657,7 +3843,7 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
/* update output port resolution with client supplied dimensions
in case scaling is enabled, else it follows input resolution set
*/
- decide_dpb_buffer_mode();
+ 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,
@@ -4385,25 +4571,22 @@ OMX_ERRORTYPE omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
struct v4l2_control control;
int rc;
- if (pParam) {
- is_down_scalar_enabled = pParam->bEnable;
- if (is_down_scalar_enabled) {
- control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
- control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
- DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar value = %d", pParam->bEnable);
- rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
- if (rc < 0) {
- DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
- eRet = OMX_ErrorUnsupportedSetting;
- }
- 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 < 0) {
- DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
- eRet = OMX_ErrorUnsupportedSetting;
- }
+ 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;
}