mirror of
https://github.com/followmsi/android_hardware_qcom_media.git
synced 2024-10-31 22:47:35 +00:00
mm-video-v4l2: vdec: Downscale to the highest connected resolution
*Downscale video to the highest resolution of the connected displays. *Don't downscale if video resolution is lower than any of connected display resolutions. *Add provision to override the downscalar width and height using the properties vidc.dec.downscalar_width and vidc.dec.downscalar_height *Enable Downsaclar only if the property vidc.dec.enable.downscalar is set to 1. Change-Id: Iac1eeaf89bd06cf86ec3b0b955f25b1c114067be
This commit is contained in:
parent
9df0885078
commit
67ab3256df
3 changed files with 101 additions and 20 deletions
|
@ -60,6 +60,8 @@ ifeq ($(call is-board-platform-in-list, $(MASTER_SIDE_CP_TARGET_LIST)),true)
|
|||
libmm-vdec-def += -DMASTER_SIDE_CP
|
||||
endif
|
||||
|
||||
libmm-vdec-def += -D_QUERY_DISP_RES_
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# Common Includes
|
||||
|
@ -111,7 +113,7 @@ 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 := liblog libutils libbinder libcutils libdl libqdutils
|
||||
|
||||
LOCAL_SHARED_LIBRARIES += libqdMetaData
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
Copyright (c) 2010 - 2016, The Linux Foundation. All rights reserved.
|
||||
Copyright (c) 2010 - 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
|
||||
|
@ -1065,6 +1065,7 @@ class omx_vdec: public qc_omx_component
|
|||
bool is_thulium_v1;
|
||||
bool m_disable_ubwc_mode;
|
||||
bool m_disable_split_mode;
|
||||
bool m_enable_downscalar;
|
||||
OMX_U32 m_downscalar_width;
|
||||
OMX_U32 m_downscalar_height;
|
||||
int decide_downscalar();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*--------------------------------------------------------------------------
|
||||
Copyright (c) 2010 - 2016, The Linux Foundation. All rights reserved.
|
||||
Copyright (c) 2010 - 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:
|
||||
|
@ -63,6 +63,10 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifdef _ANDROID_
|
||||
#include <cutils/properties.h>
|
||||
#undef USE_EGL_IMAGE_GPU
|
||||
|
||||
#ifdef _QUERY_DISP_RES_
|
||||
#include "display_config.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _USE_GLIB_
|
||||
|
@ -155,6 +159,9 @@ extern "C" {
|
|||
|
||||
#define LUMINANCE_DIV_FACTOR 10000.0
|
||||
|
||||
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
|
||||
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
static OMX_U32 maxSmoothStreamingWidth = 1920;
|
||||
static OMX_U32 maxSmoothStreamingHeight = 1088;
|
||||
|
||||
|
@ -824,6 +831,7 @@ omx_vdec::omx_vdec(): m_error_propogated(false),
|
|||
dynamic_buf_mode = false;
|
||||
out_dynamic_list = NULL;
|
||||
is_down_scalar_enabled = false;
|
||||
m_enable_downscalar = 0;
|
||||
m_downscalar_width = 0;
|
||||
m_downscalar_height = 0;
|
||||
m_force_down_scalar = 0;
|
||||
|
@ -1228,6 +1236,7 @@ int omx_vdec::decide_downscalar()
|
|||
struct v4l2_format fmt;
|
||||
enum color_fmts color_format;
|
||||
OMX_U32 width, height;
|
||||
OMX_BOOL isPortraitVideo = OMX_FALSE;
|
||||
|
||||
if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) {
|
||||
rc = disable_downscalar();
|
||||
|
@ -1238,11 +1247,77 @@ int omx_vdec::decide_downscalar()
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (!m_downscalar_width || !m_downscalar_height) {
|
||||
if (!m_enable_downscalar) {
|
||||
DEBUG_PRINT_LOW("%s: downscalar not supported", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _QUERY_DISP_RES_
|
||||
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;
|
||||
}
|
||||
isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE;
|
||||
if (!m_downscalar_width || !m_downscalar_height) {
|
||||
qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {};
|
||||
int prim_config, ext_config, virt_config;
|
||||
|
||||
prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY);
|
||||
dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY);
|
||||
DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d dpa.yres=%d dpa.xdpi = %f dpa.ydpi = %f ",
|
||||
__func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi);
|
||||
|
||||
ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL);
|
||||
dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL);
|
||||
DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d dsa.yres = %d dsa.xdpi = %f dsa.ydpi = %f ",
|
||||
__func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi);
|
||||
|
||||
virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL);
|
||||
dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL);
|
||||
DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d dva.yres = %d dva.xdpi = %f dva.ydpi = %f ",
|
||||
__func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi);
|
||||
|
||||
/* Below logic takes care of following conditions:
|
||||
* 1. Choose display resolution as maximum resolution of all the connected
|
||||
* displays (secondary, primary, virtual), so that we do not downscale
|
||||
* unnecessarily which might be supported on one of the display losing quality.
|
||||
* 2. Displays connected might be in landscape or portrait mode, so the xres might
|
||||
* be smaller or greater than the yres. So we first take the max of the two
|
||||
* in width and min of two in height and then rotate it if below point is true.
|
||||
* 3. Video might also be in portrait mode, so invert the downscalar width and
|
||||
* height for such cases.
|
||||
*/
|
||||
if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) {
|
||||
m_downscalar_width = MAX(dsa.xres, dsa.yres);
|
||||
m_downscalar_height = MIN(dsa.xres, dsa.yres);
|
||||
} else if (dva.xres * dva.yres > dpa.xres * dpa.yres) {
|
||||
m_downscalar_width = MAX(dva.xres, dva.yres);
|
||||
m_downscalar_height = MIN(dva.xres, dva.yres);
|
||||
|
||||
} else {
|
||||
m_downscalar_width = MAX(dpa.xres, dpa.yres);
|
||||
m_downscalar_height = MIN(dpa.xres, dpa.yres);
|
||||
}
|
||||
if (isPortraitVideo) {
|
||||
// Swap width and height
|
||||
m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
|
||||
m_downscalar_height = m_downscalar_width ^ m_downscalar_height;
|
||||
m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
|
||||
}
|
||||
}
|
||||
m_downscalar_width = ALIGN(m_downscalar_width, 128);
|
||||
m_downscalar_height = ALIGN(m_downscalar_height, 32);
|
||||
#endif
|
||||
|
||||
if (!m_downscalar_width || !m_downscalar_height) {
|
||||
DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_force_down_scalar) {
|
||||
DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
|
||||
return 0;
|
||||
|
@ -1263,7 +1338,7 @@ int omx_vdec::decide_downscalar()
|
|||
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) &&
|
||||
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) {
|
||||
|
@ -2617,24 +2692,27 @@ OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
|
|||
drv_ctx.idr_only_decoding = 0;
|
||||
|
||||
#ifdef _ANDROID_
|
||||
property_get("vidc.dec.downscalar_width",property_value,"0");
|
||||
property_get("vidc.dec.enable.downscalar",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);
|
||||
}
|
||||
m_enable_downscalar = atoi(property_value);
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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");
|
||||
|
|
Loading…
Reference in a new issue