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:
Akshata Sahukar
2021-04-12 13:09:40 -07:00
parent 140af50ab5
commit 5a2b2ee399
5 changed files with 152 additions and 10 deletions

View File

@@ -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},

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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:

View File

@@ -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;