video: driver: Add support to adjust slice mode
Add support to adjust slice mode. Change-Id: Id09e951b3085c55cc5bc6b15a2ce002645923435 Signed-off-by: Akshata Sahukar <asahukar@codeaurora.org>
This commit is contained in:
@@ -25,6 +25,11 @@
|
|||||||
#define MAX_QP 51
|
#define MAX_QP 51
|
||||||
#define DEFAULT_QP 20
|
#define DEFAULT_QP 20
|
||||||
#define MAX_CONSTANT_QUALITY 100
|
#define MAX_CONSTANT_QUALITY 100
|
||||||
|
#define MIN_SLICE_BYTE_SIZE 512
|
||||||
|
#define MAX_SLICE_BYTE_SIZE \
|
||||||
|
((MAX_BITRATE) >> 3)
|
||||||
|
#define MAX_SLICE_MB_SIZE \
|
||||||
|
(((4096 + 15) >> 4) * ((2304 + 15) >> 4))
|
||||||
|
|
||||||
#define UBWC_CONFIG(mc, ml, hbb, bs1, bs2, bs3, bsp) \
|
#define UBWC_CONFIG(mc, ml, hbb, bs1, bs2, bs3, bsp) \
|
||||||
{ \
|
{ \
|
||||||
@@ -329,7 +334,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
|||||||
{0},
|
{0},
|
||||||
{LTR_COUNT, IR_RANDOM, TIME_DELTA_BASED_RC, I_FRAME_QP,
|
{LTR_COUNT, IR_RANDOM, TIME_DELTA_BASED_RC, I_FRAME_QP,
|
||||||
ENH_LAYER_COUNT, BIT_RATE, CONTENT_ADAPTIVE_CODING,
|
ENH_LAYER_COUNT, BIT_RATE, CONTENT_ADAPTIVE_CODING,
|
||||||
BITRATE_BOOST, MIN_QUALITY, VBV_DELAY, PEAK_BITRATE},
|
BITRATE_BOOST, MIN_QUALITY, VBV_DELAY, PEAK_BITRATE,
|
||||||
|
SLICE_MODE},
|
||||||
msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
|
msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
|
||||||
|
|
||||||
{BITRATE_MODE, ENC, HEVC,
|
{BITRATE_MODE, ENC, HEVC,
|
||||||
@@ -347,7 +353,7 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
|||||||
CONSTANT_QUALITY, ENH_LAYER_COUNT,
|
CONSTANT_QUALITY, ENH_LAYER_COUNT,
|
||||||
CONTENT_ADAPTIVE_CODING, BIT_RATE,
|
CONTENT_ADAPTIVE_CODING, BIT_RATE,
|
||||||
BITRATE_BOOST, MIN_QUALITY, VBV_DELAY,
|
BITRATE_BOOST, MIN_QUALITY, VBV_DELAY,
|
||||||
PEAK_BITRATE},
|
PEAK_BITRATE, SLICE_MODE},
|
||||||
msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
|
msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
|
||||||
|
|
||||||
{LOSSLESS, ENC, HEVC|HEIC,
|
{LOSSLESS, ENC, HEVC|HEIC,
|
||||||
@@ -1027,18 +1033,19 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
|||||||
V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
|
V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE,
|
||||||
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
|
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE,
|
||||||
0,
|
0,
|
||||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
|
CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
|
||||||
{0}, {0},
|
{BITRATE_MODE}, {0},
|
||||||
NULL, msm_vidc_set_slice_count},
|
msm_vidc_adjust_slice_count, msm_vidc_set_slice_count},
|
||||||
|
|
||||||
{SLICE_MAX_BYTES, ENC, H264|HEVC|HEIC,
|
{SLICE_MAX_BYTES, ENC, H264|HEVC|HEIC,
|
||||||
1, INT_MAX, 1, INT_MAX,
|
MIN_SLICE_BYTE_SIZE, MAX_SLICE_BYTE_SIZE,
|
||||||
|
1, MIN_SLICE_BYTE_SIZE,
|
||||||
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
|
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES,
|
||||||
HFI_PROP_MULTI_SLICE_BYTES_COUNT,
|
HFI_PROP_MULTI_SLICE_BYTES_COUNT,
|
||||||
CAP_FLAG_OUTPUT_PORT},
|
CAP_FLAG_OUTPUT_PORT},
|
||||||
|
|
||||||
{SLICE_MAX_MB, ENC, H264|HEVC|HEIC,
|
{SLICE_MAX_MB, ENC, H264|HEVC|HEIC,
|
||||||
1, INT_MAX, 1, INT_MAX,
|
1, MAX_SLICE_MB_SIZE, 1, 1,
|
||||||
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
|
V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB,
|
||||||
HFI_PROP_MULTI_SLICE_MB_COUNT,
|
HFI_PROP_MULTI_SLICE_MB_COUNT,
|
||||||
CAP_FLAG_OUTPUT_PORT},
|
CAP_FLAG_OUTPUT_PORT},
|
||||||
|
@@ -28,6 +28,7 @@ int msm_vidc_adjust_mark_ltr(void *instance, struct v4l2_ctrl *ctrl);
|
|||||||
int msm_vidc_adjust_ir_random(void *instance, struct v4l2_ctrl *ctrl);
|
int msm_vidc_adjust_ir_random(void *instance, struct v4l2_ctrl *ctrl);
|
||||||
int msm_vidc_adjust_delta_based_rc(void *instance, struct v4l2_ctrl *ctrl);
|
int msm_vidc_adjust_delta_based_rc(void *instance, struct v4l2_ctrl *ctrl);
|
||||||
int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl);
|
int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl);
|
||||||
|
int msm_vidc_adjust_slice_count(void *instance, struct v4l2_ctrl *ctrl);
|
||||||
int msm_vidc_adjust_layer_count(void *instance, struct v4l2_ctrl *ctrl);
|
int msm_vidc_adjust_layer_count(void *instance, struct v4l2_ctrl *ctrl);
|
||||||
int msm_vidc_adjust_gop_size(void *instance, struct v4l2_ctrl *ctrl);
|
int msm_vidc_adjust_gop_size(void *instance, struct v4l2_ctrl *ctrl);
|
||||||
int msm_vidc_adjust_b_frame(void *instance, struct v4l2_ctrl *ctrl);
|
int msm_vidc_adjust_b_frame(void *instance, struct v4l2_ctrl *ctrl);
|
||||||
|
@@ -56,6 +56,15 @@
|
|||||||
#define MAX_AVC_ENH_LAYER_HYBRID_HP 5
|
#define MAX_AVC_ENH_LAYER_HYBRID_HP 5
|
||||||
#define PERCENT_PEAK_BITRATE_INCREASED 10
|
#define PERCENT_PEAK_BITRATE_INCREASED 10
|
||||||
#define INVALID_DEFAULT_MARK_OR_USE_LTR -1
|
#define INVALID_DEFAULT_MARK_OR_USE_LTR -1
|
||||||
|
#define MAX_SLICES_PER_FRAME 10
|
||||||
|
#define MAX_SLICES_FRAME_RATE 60
|
||||||
|
#define MAX_MB_SLICE_WIDTH 4096
|
||||||
|
#define MAX_MB_SLICE_HEIGHT 2160
|
||||||
|
#define MAX_BYTES_SLICE_WIDTH 1920
|
||||||
|
#define MAX_BYTES_SLICE_HEIGHT 1088
|
||||||
|
#define MIN_HEVC_SLICE_WIDTH 384
|
||||||
|
#define MIN_AVC_SLICE_WIDTH 192
|
||||||
|
#define MIN_SLICE_HEIGHT 128
|
||||||
|
|
||||||
#define DCVS_WINDOW 16
|
#define DCVS_WINDOW 16
|
||||||
/* Superframe can have maximum of 32 frames */
|
/* Superframe can have maximum of 32 frames */
|
||||||
|
@@ -1245,6 +1245,7 @@ static int msm_venc_s_fmt_input(struct msm_vidc_inst *inst, struct v4l2_format *
|
|||||||
|
|
||||||
if (fmt->fmt.pix_mp.width != crop_width ||
|
if (fmt->fmt.pix_mp.width != crop_width ||
|
||||||
fmt->fmt.pix_mp.height != crop_height) {
|
fmt->fmt.pix_mp.height != crop_height) {
|
||||||
|
struct v4l2_format *output_fmt;
|
||||||
|
|
||||||
/* reset crop dimensions with updated resolution */
|
/* reset crop dimensions with updated resolution */
|
||||||
inst->crop.top = inst->crop.left = 0;
|
inst->crop.top = inst->crop.left = 0;
|
||||||
@@ -1256,9 +1257,17 @@ static int msm_venc_s_fmt_input(struct msm_vidc_inst *inst, struct v4l2_format *
|
|||||||
inst->compose.width = f->fmt.pix_mp.width;
|
inst->compose.width = f->fmt.pix_mp.width;
|
||||||
inst->compose.height = f->fmt.pix_mp.height;
|
inst->compose.height = f->fmt.pix_mp.height;
|
||||||
|
|
||||||
rc = msm_venc_s_fmt_output(inst, &inst->fmts[OUTPUT_PORT]);
|
output_fmt = &inst->fmts[OUTPUT_PORT];
|
||||||
|
rc = msm_venc_s_fmt_output(inst, output_fmt);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
i_vpr_h(inst,
|
||||||
|
"%s: type %d: format %#x width %d height %d size %d\n",
|
||||||
|
__func__, output_fmt->type, output_fmt->fmt.pix_mp.pixelformat,
|
||||||
|
output_fmt->fmt.pix_mp.width,
|
||||||
|
output_fmt->fmt.pix_mp.height,
|
||||||
|
output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage);
|
||||||
}
|
}
|
||||||
|
|
||||||
//rc = msm_vidc_check_session_supported(inst);
|
//rc = msm_vidc_check_session_supported(inst);
|
||||||
@@ -1385,6 +1394,7 @@ int msm_venc_g_fmt(struct msm_vidc_inst *inst, struct v4l2_format *f)
|
|||||||
int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s)
|
int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
struct v4l2_format *output_fmt;
|
||||||
|
|
||||||
if (!inst || !s) {
|
if (!inst || !s) {
|
||||||
d_vpr_e("%s: invalid params\n", __func__);
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
@@ -1431,9 +1441,16 @@ int msm_venc_s_selection(struct msm_vidc_inst* inst, struct v4l2_selection* s)
|
|||||||
if (inst->compose.height > inst->crop.height)
|
if (inst->compose.height > inst->crop.height)
|
||||||
inst->compose.height = inst->crop.height;
|
inst->compose.height = inst->crop.height;
|
||||||
/* update output format based on new crop dimensions */
|
/* update output format based on new crop dimensions */
|
||||||
rc = msm_venc_s_fmt_output(inst, &inst->fmts[OUTPUT_PORT]);
|
output_fmt = &inst->fmts[OUTPUT_PORT];
|
||||||
|
rc = msm_venc_s_fmt_output(inst, output_fmt);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
i_vpr_h(inst,
|
||||||
|
"%s: type %d: format %#x width %d height %d size %d\n",
|
||||||
|
__func__, output_fmt->type, output_fmt->fmt.pix_mp.pixelformat,
|
||||||
|
output_fmt->fmt.pix_mp.width,
|
||||||
|
output_fmt->fmt.pix_mp.height,
|
||||||
|
output_fmt->fmt.pix_mp.plane_fmt[0].sizeimage);
|
||||||
break;
|
break;
|
||||||
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
|
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
|
||||||
case V4L2_SEL_TGT_COMPOSE_PADDED:
|
case V4L2_SEL_TGT_COMPOSE_PADDED:
|
||||||
|
@@ -1072,6 +1072,112 @@ int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int msm_vidc_adjust_slice_count(void *instance, struct v4l2_ctrl *ctrl)
|
||||||
|
{
|
||||||
|
struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
|
||||||
|
struct msm_vidc_inst_capability *capability;
|
||||||
|
struct v4l2_format *output_fmt;
|
||||||
|
s32 adjusted_value, rc_type = -1, slice_mode;
|
||||||
|
u32 slice_val, mbpf = 0, mbps = 0, max_mbpf = 0, max_mbps = 0;
|
||||||
|
u32 update_cap, max_avg_slicesize, output_width, output_height;
|
||||||
|
u32 min_width, min_height, max_width, max_height, fps;
|
||||||
|
|
||||||
|
if (!inst || !inst->capabilities) {
|
||||||
|
d_vpr_e("%s: invalid params\n", __func__);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
capability = inst->capabilities;
|
||||||
|
|
||||||
|
slice_mode = ctrl ? ctrl->val :
|
||||||
|
capability->cap[SLICE_MODE].value;
|
||||||
|
|
||||||
|
if (msm_vidc_get_parent_value(inst, SLICE_MODE,
|
||||||
|
BITRATE_MODE, &rc_type, __func__))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
fps = capability->cap[FRAME_RATE].value >> 16;
|
||||||
|
if (fps > MAX_SLICES_FRAME_RATE ||
|
||||||
|
(rc_type != HFI_RC_OFF &&
|
||||||
|
rc_type != HFI_RC_CBR_CFR &&
|
||||||
|
rc_type != HFI_RC_CBR_VFR)) {
|
||||||
|
adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
|
||||||
|
update_cap = SLICE_MODE;
|
||||||
|
i_vpr_h(inst,
|
||||||
|
"%s: slice unsupported, fps: %u, rc_type: %#x\n",
|
||||||
|
__func__, fps, rc_type);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
output_fmt = &inst->fmts[OUTPUT_PORT];
|
||||||
|
output_width = output_fmt->fmt.pix_mp.width;
|
||||||
|
output_height = output_fmt->fmt.pix_mp.height;
|
||||||
|
|
||||||
|
max_width = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
|
||||||
|
MAX_MB_SLICE_WIDTH : MAX_BYTES_SLICE_WIDTH;
|
||||||
|
max_height = (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) ?
|
||||||
|
MAX_MB_SLICE_HEIGHT : MAX_BYTES_SLICE_HEIGHT;
|
||||||
|
min_width = (inst->codec == MSM_VIDC_HEVC) ?
|
||||||
|
MIN_HEVC_SLICE_WIDTH : MIN_AVC_SLICE_WIDTH;
|
||||||
|
min_height = MIN_SLICE_HEIGHT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB:
|
||||||
|
* - width >= 384 and height >= 128
|
||||||
|
* - width and height <= 4096
|
||||||
|
* For V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES:
|
||||||
|
* - width >= 192 and height >= 128
|
||||||
|
* - width and height <= 1920
|
||||||
|
*/
|
||||||
|
if (output_width < min_width || output_height < min_height ||
|
||||||
|
output_width > max_width || output_height > max_width) {
|
||||||
|
adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
|
||||||
|
update_cap = SLICE_MODE;
|
||||||
|
i_vpr_h(inst,
|
||||||
|
"%s: slice unsupported, codec: %#x wxh: [%dx%d]\n",
|
||||||
|
__func__, inst->codec, output_width, output_height);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbpf = NUM_MBS_PER_FRAME(output_height, output_width);
|
||||||
|
mbps = NUM_MBS_PER_SEC(output_height, output_width, fps);
|
||||||
|
max_mbpf = NUM_MBS_PER_FRAME(max_height, max_width);
|
||||||
|
max_mbps = NUM_MBS_PER_SEC(max_height, max_width, fps);
|
||||||
|
|
||||||
|
if (mbpf > max_mbpf || mbps > max_mbps) {
|
||||||
|
adjusted_value = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE;
|
||||||
|
update_cap = SLICE_MODE;
|
||||||
|
i_vpr_h(inst,
|
||||||
|
"%s: Unsupported, mbpf[%u] > max[%u], mbps[%u] > max[%u]\n",
|
||||||
|
__func__, mbpf, max_mbpf, mbps, max_mbps);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
|
||||||
|
update_cap = SLICE_MAX_MB;
|
||||||
|
slice_val = capability->cap[SLICE_MAX_MB].value;
|
||||||
|
slice_val = max(slice_val, mbpf / MAX_SLICES_PER_FRAME);
|
||||||
|
} else {
|
||||||
|
slice_val = capability->cap[SLICE_MAX_BYTES].value;
|
||||||
|
update_cap = SLICE_MAX_BYTES;
|
||||||
|
if (rc_type != HFI_RC_OFF) {
|
||||||
|
max_avg_slicesize = ((capability->cap[BIT_RATE].value /
|
||||||
|
fps) / 8) /
|
||||||
|
MAX_SLICES_PER_FRAME;
|
||||||
|
slice_val = max(slice_val, max_avg_slicesize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adjusted_value = slice_val;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
msm_vidc_update_cap_value(inst, update_cap,
|
||||||
|
adjusted_value, __func__);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int msm_vidc_adjust_static_layer_count_and_type(struct msm_vidc_inst *inst,
|
static int msm_vidc_adjust_static_layer_count_and_type(struct msm_vidc_inst *inst,
|
||||||
s32 layer_count)
|
s32 layer_count)
|
||||||
{
|
{
|
||||||
@@ -2033,7 +2139,9 @@ int msm_vidc_set_slice_count(void* instance,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
|
if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_MB) {
|
||||||
hfi_value = inst->capabilities->cap[SLICE_MAX_MB].value;
|
hfi_value = (inst->codec == MSM_VIDC_HEVC) ?
|
||||||
|
((inst->capabilities->cap[SLICE_MAX_MB].value + 3) / 4) :
|
||||||
|
inst->capabilities->cap[SLICE_MAX_MB].value;
|
||||||
set_cap_id = SLICE_MAX_MB;
|
set_cap_id = SLICE_MAX_MB;
|
||||||
} else if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
|
} else if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_MAX_BYTES) {
|
||||||
hfi_value = inst->capabilities->cap[SLICE_MAX_BYTES].value;
|
hfi_value = inst->capabilities->cap[SLICE_MAX_BYTES].value;
|
||||||
|
Reference in New Issue
Block a user