diff options
author | Srinu Gorle <sgorle@codeaurora.org> | 2015-05-21 00:08:24 +0530 |
---|---|---|
committer | Srinu Gorle <sgorle@codeaurora.org> | 2015-11-18 09:00:25 +0530 |
commit | 8be933c724ad0a94e906ef6084c3f098d47b1709 (patch) | |
tree | 4fe3f29bb6b42d366394b7cc101fc72068f72ce8 | |
parent | 4c87b6599b942d86d9c757e391f39bc8d66811e6 (diff) | |
download | android_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.h | 8 | ||||
-rw-r--r-- | mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp | 237 |
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; } |