diff options
author | Linux Build Service Account <lnxbuild@localhost> | 2015-11-20 03:40:54 -0800 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2015-11-20 03:40:54 -0800 |
commit | 670e94432151724d86b747b4ac23c424968b9f91 (patch) | |
tree | cd85cce988326b5d74feaa335335d85f14a4c1b1 | |
parent | 76f5a33fd0ec451acbc1c397c5bb2ec1b3624376 (diff) | |
parent | 8be933c724ad0a94e906ef6084c3f098d47b1709 (diff) | |
download | android_hardware_qcom_media-670e94432151724d86b747b4ac23c424968b9f91.tar.gz android_hardware_qcom_media-670e94432151724d86b747b4ac23c424968b9f91.tar.bz2 android_hardware_qcom_media-670e94432151724d86b747b4ac23c424968b9f91.zip |
Merge "mm-video-v4l2: vidc: vdec: Add support for downscalar in component"
-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 fae605a7..54230724 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; } |