video: driver: Add support to handle GOP and its dependencies
Add support to below mentioned properties: - HFI_PROP_LAYER_ENCODING_TYPE - HFI_PROP_LAYER_COUNT - HFI_PROP_MAX_GOP_FRAMES - HFI_PROP_MAX_B_FRAMES. Change-Id: I3be975a48dc668d0ec83f6ff13837488fc570b78 Signed-off-by: Akshata Sahukar <asahukar@codeaurora.org>
This commit is contained in:
@@ -60,6 +60,7 @@ static struct msm_platform_core_capability core_data_waipio[] = {
|
||||
{MAX_MBPS_HQ, 489600}, /* ((1920x1088)/256)@60fps */
|
||||
{MAX_MBPF_B_FRAME, 32640}, /* 3840x2176/256 */
|
||||
{MAX_MBPS_B_FRAME, 1958400}, /* 3840x2176/256 MBs@60fps */
|
||||
{MAX_ENH_LAYER_COUNT, 5},
|
||||
{NUM_VPP_PIPE, 4},
|
||||
{SW_PC, 1},
|
||||
{SW_PC_DELAY, 20000}, /* 20000 ms (>HW_RESPONSE_TIMEOUT)*/
|
||||
@@ -193,12 +194,6 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
{SCALE_X, DEC, H264|HEVC|VP9, 65536, 65536, 1, 65536},
|
||||
{SCALE_Y, ENC, H264|HEVC, 8192, 65536, 1, 8192},
|
||||
{SCALE_Y, DEC, H264|HEVC|VP9, 65536, 65536, 1, 65536},
|
||||
{B_FRAME, ENC, H264|HEVC,
|
||||
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||
V4L2_CID_MPEG_VIDEO_B_FRAMES,
|
||||
HFI_PROP_MAX_B_FRAMES,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
|
||||
|
||||
{MB_CYCLES_VSP, ENC, CODECS_ALL, 25, 25, 1, 25},
|
||||
{MB_CYCLES_VSP, DEC, CODECS_ALL, 25, 25, 1, 25},
|
||||
@@ -328,7 +323,8 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
HFI_PROP_RATE_CONTROL,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
|
||||
{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},
|
||||
msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
|
||||
|
||||
{BITRATE_MODE, ENC, HEVC,
|
||||
@@ -343,7 +339,7 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
|
||||
{0},
|
||||
{LTR_COUNT, IR_RANDOM, TIME_DELTA_BASED_RC,
|
||||
I_FRAME_QP, CONSTANT_QUALITY},
|
||||
I_FRAME_QP, CONSTANT_QUALITY, ENH_LAYER_COUNT},
|
||||
msm_vidc_adjust_bitrate_mode, msm_vidc_set_u32_enum},
|
||||
|
||||
{LOSSLESS, ENC, HEVC|HEIC,
|
||||
@@ -375,14 +371,14 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
{BITRATE_MODE}, {0},
|
||||
NULL, msm_vidc_set_constant_quality},
|
||||
|
||||
// TODO: GOP dependencies
|
||||
{GOP_SIZE, ENC, CODECS_ALL,
|
||||
0, INT_MAX, 1, 2 * DEFAULT_FPS - 1,
|
||||
V4L2_CID_MPEG_VIDEO_GOP_SIZE,
|
||||
HFI_PROP_MAX_GOP_FRAMES,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
|
||||
{0}, {0},
|
||||
NULL, msm_vidc_set_u32},
|
||||
CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
|
||||
{ENH_LAYER_COUNT},
|
||||
{0},
|
||||
msm_vidc_adjust_gop_size, msm_vidc_set_gop_size},
|
||||
|
||||
{GOP_CLOSURE, ENC, H264|HEVC,
|
||||
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||
@@ -390,6 +386,15 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
|
||||
0},
|
||||
|
||||
{B_FRAME, ENC, H264|HEVC,
|
||||
0, 7, 1, 0,
|
||||
V4L2_CID_MPEG_VIDEO_B_FRAMES,
|
||||
HFI_PROP_MAX_B_FRAMES,
|
||||
CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
|
||||
{ENH_LAYER_COUNT},
|
||||
{0},
|
||||
msm_vidc_adjust_b_frame, msm_vidc_set_u32},
|
||||
|
||||
{BLUR_TYPES, ENC, CODECS_ALL,
|
||||
VIDC_BLUR_NONE, VIDC_BLUR_ADAPTIVE, 1, VIDC_BLUR_NONE,
|
||||
V4L2_CID_MPEG_VIDC_VIDEO_BLUR_TYPES,
|
||||
@@ -662,8 +667,7 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
HFI_PROP_QP_PACKED,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
|
||||
|
||||
// TODO: Enable while reveiwing support for layer encoding
|
||||
{HIER_CODING_TYPE, ENC, HEVC,
|
||||
{LAYER_TYPE, ENC, HEVC,
|
||||
V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B,
|
||||
V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
|
||||
BIT(V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) |
|
||||
@@ -671,12 +675,9 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_P,
|
||||
V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE,
|
||||
HFI_PROP_LAYER_ENCODING_TYPE,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU,
|
||||
{0}, {0},
|
||||
NULL, NULL},
|
||||
CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
|
||||
|
||||
/* TODO(AS) - ctrl init failing. Need to fix
|
||||
{HIER_CODING_TYPE, ENC, H264,
|
||||
{LAYER_TYPE, ENC, H264,
|
||||
V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B,
|
||||
V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
|
||||
BIT(V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) |
|
||||
@@ -684,29 +685,32 @@ static struct msm_platform_inst_capability instance_data_waipio[] = {
|
||||
V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P,
|
||||
V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE,
|
||||
HFI_PROP_LAYER_ENCODING_TYPE,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
|
||||
*/
|
||||
CAP_FLAG_OUTPUT_PORT | CAP_FLAG_MENU},
|
||||
|
||||
//TODO (AS)
|
||||
{HIER_CODING, ENC, H264,
|
||||
{LAYER_ENABLE, ENC, H264,
|
||||
V4L2_MPEG_MSM_VIDC_DISABLE, V4L2_MPEG_MSM_VIDC_ENABLE,
|
||||
1, V4L2_MPEG_MSM_VIDC_DISABLE,
|
||||
V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING,
|
||||
HFI_PROP_LAYER_ENCODING_TYPE,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
|
||||
CAP_FLAG_OUTPUT_PORT},
|
||||
|
||||
// TODO: add relationship with GOP_SIZE in caps
|
||||
{HIER_CODING_LAYER, ENC, HEVC,
|
||||
{ENH_LAYER_COUNT, ENC, HEVC,
|
||||
0, 5, 1, 0,
|
||||
V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER,
|
||||
HFI_PROP_LAYER_COUNT,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
|
||||
CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
|
||||
{BITRATE_MODE},
|
||||
{GOP_SIZE, B_FRAME},
|
||||
msm_vidc_adjust_layer_count, msm_vidc_set_layer_count_and_type},
|
||||
|
||||
{HIER_CODING_LAYER, ENC, H264,
|
||||
0, 6, 1, 0,
|
||||
{ENH_LAYER_COUNT, ENC, H264,
|
||||
0, 5, 1, 0,
|
||||
V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER,
|
||||
HFI_PROP_LAYER_COUNT,
|
||||
CAP_FLAG_ROOT | CAP_FLAG_OUTPUT_PORT},
|
||||
CAP_FLAG_OUTPUT_PORT | CAP_FLAG_DYNAMIC_ALLOWED,
|
||||
{BITRATE_MODE},
|
||||
{GOP_SIZE, B_FRAME},
|
||||
msm_vidc_adjust_layer_count, msm_vidc_set_layer_count_and_type},
|
||||
|
||||
{L0_BR, ENC, HEVC,
|
||||
1, 220000000, 1, 20000000,
|
||||
|
@@ -277,13 +277,42 @@ static u32 msm_vidc_encoder_bin_size_iris2(struct msm_vidc_inst *inst)
|
||||
return size;
|
||||
}
|
||||
|
||||
static u32 msm_vidc_get_recon_buf_count(struct msm_vidc_inst *inst)
|
||||
{
|
||||
u32 num_buf_recon = 0;
|
||||
s32 n_bframe, ltr_count, hp_layers = 0, hb_layers = 0;
|
||||
bool is_hybrid_hp = false;
|
||||
u32 hfi_codec = 0;
|
||||
|
||||
n_bframe = inst->capabilities->cap[B_FRAME].value;
|
||||
ltr_count = inst->capabilities->cap[LTR_COUNT].value;
|
||||
|
||||
if (inst->hfi_layer_type == HFI_HIER_B) {
|
||||
hb_layers = inst->capabilities->cap[ENH_LAYER_COUNT].value + 1;
|
||||
} else {
|
||||
hp_layers = inst->capabilities->cap[ENH_LAYER_COUNT].value + 1;
|
||||
if (inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR)
|
||||
is_hybrid_hp = true;
|
||||
}
|
||||
|
||||
if (inst->codec == MSM_VIDC_H264)
|
||||
hfi_codec = HFI_CODEC_ENCODE_AVC;
|
||||
else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC)
|
||||
hfi_codec = HFI_CODEC_ENCODE_HEVC;
|
||||
|
||||
HFI_IRIS2_ENC_RECON_BUF_COUNT(num_buf_recon, n_bframe, ltr_count,
|
||||
hp_layers, hb_layers, is_hybrid_hp, hfi_codec);
|
||||
|
||||
return num_buf_recon;
|
||||
}
|
||||
|
||||
static u32 msm_vidc_encoder_comv_size_iris2(struct msm_vidc_inst* inst)
|
||||
{
|
||||
u32 size = 0;
|
||||
u32 width, height, num_recon = 0;
|
||||
struct v4l2_format* f;
|
||||
|
||||
if (!inst || !inst->core) {
|
||||
if (!inst || !inst->core || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return size;
|
||||
}
|
||||
@@ -292,17 +321,11 @@ static u32 msm_vidc_encoder_comv_size_iris2(struct msm_vidc_inst* inst)
|
||||
width = f->fmt.pix_mp.width;
|
||||
height = f->fmt.pix_mp.height;
|
||||
|
||||
if (inst->codec == MSM_VIDC_H264) {
|
||||
// TODO: replace zeros with appropriate variables
|
||||
HFI_IRIS2_ENC_RECON_BUF_COUNT(num_recon, 0, 0, 0, 0, 0,
|
||||
HFI_CODEC_ENCODE_AVC);
|
||||
num_recon = msm_vidc_get_recon_buf_count(inst);
|
||||
if (inst->codec == MSM_VIDC_H264)
|
||||
HFI_BUFFER_COMV_H264E(size, width, height, num_recon);
|
||||
} else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC) {
|
||||
// TODO: replace zeros with appropriate variables
|
||||
HFI_IRIS2_ENC_RECON_BUF_COUNT(num_recon, 0, 0, 0, 0, 0,
|
||||
HFI_CODEC_ENCODE_HEVC);
|
||||
else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC)
|
||||
HFI_BUFFER_COMV_H265E(size, width, height, num_recon);
|
||||
}
|
||||
|
||||
i_vpr_l(inst, "%s: size %d\n", __func__, size);
|
||||
return size;
|
||||
@@ -521,23 +544,12 @@ int msm_buffer_size_iris2(struct msm_vidc_inst *inst,
|
||||
|
||||
static int msm_buffer_encoder_dpb_count(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (!inst) {
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (inst->codec == MSM_VIDC_H264) {
|
||||
// TODO: replace zeros with appropriate variables
|
||||
HFI_IRIS2_ENC_RECON_BUF_COUNT(count, 0, 0, 0, 0, 0,
|
||||
HFI_CODEC_ENCODE_AVC);
|
||||
} else if (inst->codec == MSM_VIDC_HEVC || inst->codec == MSM_VIDC_HEIC) {
|
||||
// TODO: replace zeros with appropriate variables
|
||||
HFI_IRIS2_ENC_RECON_BUF_COUNT(count, 0, 0, 0, 0, 0,
|
||||
HFI_CODEC_ENCODE_HEVC);
|
||||
}
|
||||
return count;
|
||||
return msm_vidc_get_recon_buf_count(inst);
|
||||
}
|
||||
|
||||
static int msm_buffer_decoder_dpb_count(struct msm_vidc_inst *inst)
|
||||
|
@@ -28,6 +28,9 @@ 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_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_layer_count(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_hevc_min_qp(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_hevc_max_qp(void *instance, struct v4l2_ctrl *ctrl);
|
||||
int msm_vidc_adjust_hevc_frame_qp(void *instance, struct v4l2_ctrl *ctrl);
|
||||
@@ -49,6 +52,10 @@ int msm_vidc_set_chroma_qp_index_offset(void *instance,
|
||||
enum msm_vidc_inst_capability_type cap_id);
|
||||
int msm_vidc_set_slice_count(void* instance,
|
||||
enum msm_vidc_inst_capability_type cap_id);
|
||||
int msm_vidc_set_layer_count_and_type(void *instance,
|
||||
enum msm_vidc_inst_capability_type cap_id);
|
||||
int msm_vidc_set_gop_size(void *instance,
|
||||
enum msm_vidc_inst_capability_type cap_id);
|
||||
int msm_vidc_set_u32(void *instance,
|
||||
enum msm_vidc_inst_capability_type cap_id);
|
||||
int msm_vidc_set_u32_enum(void *instance,
|
||||
|
@@ -103,6 +103,7 @@ struct msm_vidc_inst {
|
||||
struct msm_vidc_inst_cap_entry children;
|
||||
struct msm_vidc_inst_cap_entry firmware;
|
||||
enum hfi_rate_control hfi_rc_type;
|
||||
enum hfi_layer_encoding_type hfi_layer_type;
|
||||
bool request;
|
||||
struct vb2_queue vb2q[MAX_PORT];
|
||||
struct msm_vidc_rectangle crop;
|
||||
|
@@ -50,6 +50,11 @@
|
||||
#define BIT_DEPTH_10 (10 << 16 | 10)
|
||||
#define CODED_FRAMES_PROGRESSIVE 0x0
|
||||
#define CODED_FRAMES_INTERLACE 0x1
|
||||
/* TODO: move below macros to waipio.c */
|
||||
#define MAX_ENH_LAYER_HB 3
|
||||
#define MAX_HEVC_ENH_LAYER_SLIDING_WINDOW 5
|
||||
#define MAX_AVC_ENH_LAYER_SLIDING_WINDOW 3
|
||||
#define MAX_AVC_ENH_LAYER_HYBRID_HP 5
|
||||
|
||||
/* TODO
|
||||
* #define MAX_SUPERFRAME_COUNT 32
|
||||
@@ -269,6 +274,7 @@ enum msm_vidc_core_capability_type {
|
||||
MAX_MBPS_HQ,
|
||||
MAX_MBPF_B_FRAME,
|
||||
MAX_MBPS_B_FRAME,
|
||||
MAX_ENH_LAYER_COUNT,
|
||||
NUM_VPP_PIPE,
|
||||
SW_PC,
|
||||
SW_PC_DELAY,
|
||||
@@ -313,7 +319,6 @@ enum msm_vidc_inst_capability_type {
|
||||
OPERATING_RATE,
|
||||
SCALE_X,
|
||||
SCALE_Y,
|
||||
B_FRAME,
|
||||
MB_CYCLES_VSP,
|
||||
MB_CYCLES_VPP,
|
||||
MB_CYCLES_LP,
|
||||
@@ -339,6 +344,7 @@ enum msm_vidc_inst_capability_type {
|
||||
CONSTANT_QUALITY,
|
||||
GOP_SIZE,
|
||||
GOP_CLOSURE,
|
||||
B_FRAME,
|
||||
BLUR_TYPES,
|
||||
BLUR_RESOLUTION,
|
||||
CSC,
|
||||
@@ -374,9 +380,9 @@ enum msm_vidc_inst_capability_type {
|
||||
L4_QP,
|
||||
L5_QP,
|
||||
HIER_LAYER_QP,
|
||||
HIER_CODING_TYPE,
|
||||
HIER_CODING,
|
||||
HIER_CODING_LAYER,
|
||||
LAYER_TYPE,
|
||||
LAYER_ENABLE,
|
||||
ENH_LAYER_COUNT,
|
||||
L0_BR,
|
||||
L1_BR,
|
||||
L2_BR,
|
||||
|
@@ -986,12 +986,23 @@ int msm_venc_process_cmd(struct msm_vidc_inst *inst, u32 cmd)
|
||||
int msm_venc_streamoff_output(struct msm_vidc_inst *inst)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_core *core;
|
||||
|
||||
if (!inst || !inst->core || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
core = inst->core;
|
||||
if (!core->capabilities) {
|
||||
i_vpr_e(inst, "%s: core capabilities is NULL\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* restore LAYER_COUNT max allowed value */
|
||||
inst->capabilities->cap[ENH_LAYER_COUNT].max =
|
||||
core->capabilities[MAX_ENH_LAYER_COUNT].value;
|
||||
|
||||
rc = msm_vidc_session_streamoff(inst, OUTPUT_PORT);
|
||||
if (rc)
|
||||
return rc;
|
||||
@@ -1774,6 +1785,7 @@ int msm_venc_inst_init(struct msm_vidc_inst *inst)
|
||||
inst->buffers.input_meta.size = 0;
|
||||
|
||||
inst->hfi_rc_type = HFI_RC_VBR_CFR;
|
||||
inst->hfi_layer_type = HFI_HIER_P_SLIDING_WINDOW;
|
||||
|
||||
rc = msm_venc_codec_change(inst,
|
||||
inst->fmts[OUTPUT_PORT].fmt.pix_mp.pixelformat);
|
||||
|
@@ -18,6 +18,8 @@
|
||||
|
||||
static bool is_priv_ctrl(u32 id)
|
||||
{
|
||||
bool private = false;
|
||||
|
||||
if (IS_PRIV_CTRL(id))
|
||||
return true;
|
||||
|
||||
@@ -25,8 +27,21 @@ static bool is_priv_ctrl(u32 id)
|
||||
* Treat below standard controls as private because
|
||||
* we have added custom values to the controls
|
||||
*/
|
||||
switch (id) {
|
||||
/*
|
||||
* TODO: V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE is
|
||||
* std ctrl. But needs some fixes in v4l2-ctrls.c. Hence,
|
||||
* make this as private ctrl for time being
|
||||
*/
|
||||
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
|
||||
private = true;
|
||||
break;
|
||||
default:
|
||||
private = false;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
return private;
|
||||
}
|
||||
|
||||
static bool is_meta_ctrl(u32 id)
|
||||
@@ -75,6 +90,12 @@ static const char *const mpeg_video_blur_types[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *const mpeg_video_avc_coding_layer[] = {
|
||||
"B",
|
||||
"P",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static const char *const roi_map_type[] = {
|
||||
"None",
|
||||
"2-bit",
|
||||
@@ -112,6 +133,8 @@ static const char * const * msm_vidc_get_qmenu_type(
|
||||
return mpeg_video_stream_format;
|
||||
case V4L2_CID_MPEG_VIDC_VIDEO_BLUR_TYPES:
|
||||
return mpeg_video_blur_types;
|
||||
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE:
|
||||
return mpeg_video_avc_coding_layer;
|
||||
default:
|
||||
i_vpr_e(inst, "%s: No available qmenu for ctrl %#x\n",
|
||||
__func__, control_id);
|
||||
@@ -257,10 +280,17 @@ static int msm_vidc_get_parent_value(struct msm_vidc_inst* inst,
|
||||
int rc = 0;
|
||||
|
||||
if (is_parent_available(inst, cap, parent)) {
|
||||
if (parent == BITRATE_MODE)
|
||||
switch (parent) {
|
||||
case BITRATE_MODE:
|
||||
*value = inst->hfi_rc_type;
|
||||
else
|
||||
break;
|
||||
case LAYER_TYPE:
|
||||
*value = inst->hfi_layer_type;
|
||||
break;
|
||||
default:
|
||||
*value = inst->capabilities->cap[parent].value;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i_vpr_e(inst,
|
||||
"%s: missing parent %d for cap %d, please correct database\n",
|
||||
@@ -994,6 +1024,219 @@ int msm_vidc_adjust_transform_8x8(void *instance, struct v4l2_ctrl *ctrl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int msm_vidc_adjust_static_layer_count_and_type(struct msm_vidc_inst *inst,
|
||||
s32 layer_count)
|
||||
{
|
||||
bool hb_requested = false;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!layer_count) {
|
||||
i_vpr_h(inst, "client not enabled layer encoding\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (inst->hfi_rc_type == HFI_RC_CQ) {
|
||||
i_vpr_h(inst, "rc type is CQ, disabling layer encoding\n");
|
||||
layer_count = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (inst->codec == MSM_VIDC_H264) {
|
||||
if (!inst->capabilities->cap[LAYER_ENABLE].value) {
|
||||
layer_count = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hb_requested = (inst->capabilities->cap[LAYER_TYPE].value ==
|
||||
V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) ?
|
||||
true : false;
|
||||
} else if (inst->codec == MSM_VIDC_HEVC) {
|
||||
hb_requested = (inst->capabilities->cap[LAYER_TYPE].value ==
|
||||
V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B) ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
if (hb_requested && inst->hfi_rc_type != HFI_RC_VBR_CFR) {
|
||||
i_vpr_h(inst,
|
||||
"%s: HB layer encoding is supported for VBR rc only\n",
|
||||
__func__);
|
||||
layer_count = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* decide hfi layer type */
|
||||
if (hb_requested) {
|
||||
inst->hfi_layer_type = HFI_HIER_B;
|
||||
} else {
|
||||
/* HP requested */
|
||||
inst->hfi_layer_type = HFI_HIER_P_SLIDING_WINDOW;
|
||||
if (inst->codec == MSM_VIDC_H264 &&
|
||||
inst->hfi_rc_type == HFI_RC_VBR_CFR)
|
||||
inst->hfi_layer_type = HFI_HIER_P_HYBRID_LTR;
|
||||
}
|
||||
|
||||
/* sanitize layer count based on layer type and codec */
|
||||
if (inst->hfi_layer_type == HFI_HIER_B) {
|
||||
if (layer_count > MAX_ENH_LAYER_HB)
|
||||
layer_count = MAX_ENH_LAYER_HB;
|
||||
} else if (inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR) {
|
||||
if (layer_count > MAX_AVC_ENH_LAYER_HYBRID_HP)
|
||||
layer_count = MAX_AVC_ENH_LAYER_HYBRID_HP;
|
||||
} else if (inst->hfi_layer_type == HFI_HIER_P_SLIDING_WINDOW) {
|
||||
if (inst->codec == MSM_VIDC_H264) {
|
||||
if (layer_count > MAX_AVC_ENH_LAYER_SLIDING_WINDOW)
|
||||
layer_count = MAX_AVC_ENH_LAYER_SLIDING_WINDOW;
|
||||
} else {
|
||||
if (layer_count > MAX_HEVC_ENH_LAYER_SLIDING_WINDOW)
|
||||
layer_count = MAX_HEVC_ENH_LAYER_SLIDING_WINDOW;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
msm_vidc_update_cap_value(inst, ENH_LAYER_COUNT,
|
||||
layer_count, __func__);
|
||||
inst->capabilities->cap[ENH_LAYER_COUNT].max = layer_count;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_adjust_layer_count(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_inst_capability *capability;
|
||||
s32 client_layer_count;
|
||||
struct msm_vidc_inst *inst = (struct msm_vidc_inst *) instance;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
capability = inst->capabilities;
|
||||
|
||||
client_layer_count = ctrl ? ctrl->val :
|
||||
capability->cap[ENH_LAYER_COUNT].value;
|
||||
|
||||
if (!is_parent_available(inst, ENH_LAYER_COUNT, BITRATE_MODE)) {
|
||||
i_vpr_e(inst, "%s: missing parent %d in database",
|
||||
__func__, BITRATE_MODE);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!inst->vb2q[OUTPUT_PORT].streaming) {
|
||||
rc = msm_vidc_adjust_static_layer_count_and_type(inst,
|
||||
client_layer_count);
|
||||
if (rc)
|
||||
goto exit;
|
||||
} else {
|
||||
if (inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR ||
|
||||
inst->hfi_layer_type == HFI_HIER_P_SLIDING_WINDOW) {
|
||||
/* dynamic layer count change is only supported for HP */
|
||||
if (client_layer_count >
|
||||
inst->capabilities->cap[ENH_LAYER_COUNT].max)
|
||||
client_layer_count =
|
||||
inst->capabilities->cap[ENH_LAYER_COUNT].max;
|
||||
|
||||
msm_vidc_update_cap_value(inst, ENH_LAYER_COUNT,
|
||||
client_layer_count, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. GOP calibration is only done for HP layer encoding type.
|
||||
* 2. Dynamic GOP size should not exceed static GOP size
|
||||
* 3. For HB case, or when layer encoding is not enabled,
|
||||
* client set GOP size is directly set to FW.
|
||||
*/
|
||||
int msm_vidc_adjust_gop_size(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct msm_vidc_inst_capability *capability;
|
||||
struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
|
||||
s32 adjusted_value, enh_layer_count = -1;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
capability = inst->capabilities;
|
||||
|
||||
adjusted_value = ctrl ? ctrl->val : capability->cap[GOP_SIZE].value;
|
||||
|
||||
if (msm_vidc_get_parent_value(inst, GOP_SIZE,
|
||||
ENH_LAYER_COUNT, &enh_layer_count, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
if (!enh_layer_count)
|
||||
goto exit;
|
||||
|
||||
/* calibrate GOP size */
|
||||
if (inst->hfi_layer_type == HFI_HIER_P_SLIDING_WINDOW ||
|
||||
inst->hfi_layer_type == HFI_HIER_P_HYBRID_LTR) {
|
||||
/*
|
||||
* Layer encoding needs GOP size to be multiple of subgop size
|
||||
* And subgop size is 2 ^ number of enhancement layers.
|
||||
*/
|
||||
u32 min_gop_size;
|
||||
u32 num_subgops;
|
||||
|
||||
/* v4l2 layer count is the number of enhancement layers */
|
||||
min_gop_size = 1 << enh_layer_count;
|
||||
num_subgops = (adjusted_value + (min_gop_size >> 1)) /
|
||||
min_gop_size;
|
||||
if (num_subgops)
|
||||
adjusted_value = num_subgops * min_gop_size;
|
||||
else
|
||||
adjusted_value = min_gop_size;
|
||||
}
|
||||
|
||||
exit:
|
||||
msm_vidc_update_cap_value(inst, GOP_SIZE, adjusted_value, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_adjust_b_frame(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
struct msm_vidc_inst_capability *capability;
|
||||
struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
|
||||
s32 adjusted_value, enh_layer_count = -1;
|
||||
const u32 max_bframe_size = 7;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
capability = inst->capabilities;
|
||||
|
||||
if (inst->vb2q[OUTPUT_PORT].streaming)
|
||||
return 0;
|
||||
|
||||
adjusted_value = ctrl ? ctrl->val : capability->cap[B_FRAME].value;
|
||||
|
||||
if (msm_vidc_get_parent_value(inst, B_FRAME,
|
||||
ENH_LAYER_COUNT, &enh_layer_count, __func__))
|
||||
return -EINVAL;
|
||||
|
||||
if (!enh_layer_count || inst->hfi_layer_type != HFI_HIER_B) {
|
||||
adjusted_value = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
adjusted_value = (2 << enh_layer_count) - 1;
|
||||
/* Allowed Bframe values are 0, 1, 3, 7 */
|
||||
if (adjusted_value > max_bframe_size)
|
||||
adjusted_value = max_bframe_size;
|
||||
|
||||
exit:
|
||||
msm_vidc_update_cap_value(inst, B_FRAME, adjusted_value, __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_vidc_adjust_hevc_min_qp(void *instance, struct v4l2_ctrl *ctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
@@ -1493,6 +1736,79 @@ int msm_vidc_set_nal_length(void* instance,
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_set_layer_count_and_type(void *instance,
|
||||
enum msm_vidc_inst_capability_type cap_id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
|
||||
u32 hfi_layer_count, hfi_layer_type = 0;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!inst->vb2q[OUTPUT_PORT].streaming) {
|
||||
/* set layer type */
|
||||
hfi_layer_type = inst->hfi_layer_type;
|
||||
cap_id = LAYER_TYPE;
|
||||
|
||||
rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32_ENUM,
|
||||
&hfi_layer_type, sizeof(u32), __func__);
|
||||
if (rc)
|
||||
goto exit;
|
||||
} else {
|
||||
if (inst->hfi_layer_type == HFI_HIER_B) {
|
||||
i_vpr_l(inst,
|
||||
"%s: HB dyn layers change is not supported\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* set layer count */
|
||||
cap_id = ENH_LAYER_COUNT;
|
||||
/* hfi baselayer starts from 1 */
|
||||
hfi_layer_count = inst->capabilities->cap[ENH_LAYER_COUNT].value + 1;
|
||||
|
||||
rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32,
|
||||
&hfi_layer_count, sizeof(u32), __func__);
|
||||
if (rc)
|
||||
goto exit;
|
||||
|
||||
exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int msm_vidc_set_gop_size(void *instance,
|
||||
enum msm_vidc_inst_capability_type cap_id)
|
||||
{
|
||||
int rc = 0;
|
||||
struct msm_vidc_inst *inst = (struct msm_vidc_inst *)instance;
|
||||
u32 hfi_value;
|
||||
|
||||
if (!inst || !inst->capabilities) {
|
||||
d_vpr_e("%s: invalid params\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (inst->vb2q[OUTPUT_PORT].streaming) {
|
||||
if (inst->hfi_layer_type == HFI_HIER_B) {
|
||||
i_vpr_l(inst,
|
||||
"%s: HB dyn GOP setting is not supported\n",
|
||||
__func__);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
hfi_value = inst->capabilities->cap[GOP_SIZE].value;
|
||||
|
||||
rc = msm_vidc_packetize_control(inst, cap_id, HFI_PAYLOAD_U32,
|
||||
&hfi_value, sizeof(u32), __func__);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* TODO
|
||||
int msm_vidc_set_flip(void *instance,
|
||||
enum msm_vidc_inst_capability_type cap_id)
|
||||
|
@@ -62,7 +62,6 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
|
||||
{OPERATING_RATE, "OPERATING_RATE" },
|
||||
{SCALE_X, "SCALE_X" },
|
||||
{SCALE_Y, "SCALE_Y" },
|
||||
{B_FRAME, "B_FRAME" },
|
||||
{MB_CYCLES_VSP, "MB_CYCLES_VSP" },
|
||||
{MB_CYCLES_VPP, "MB_CYCLES_VPP" },
|
||||
{MB_CYCLES_LP, "MB_CYCLES_LP" },
|
||||
@@ -88,6 +87,7 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
|
||||
{CONSTANT_QUALITY, "CONSTANT_QUALITY" },
|
||||
{GOP_SIZE, "GOP_SIZE" },
|
||||
{GOP_CLOSURE, "GOP_CLOSURE" },
|
||||
{B_FRAME, "B_FRAME" },
|
||||
{BLUR_TYPES, "BLUR_TYPES" },
|
||||
{BLUR_RESOLUTION, "BLUR_RESOLUTION" },
|
||||
{CSC, "CSC" },
|
||||
@@ -123,9 +123,9 @@ static const struct msm_vidc_cap_name cap_name_arr[] = {
|
||||
{L4_QP, "L4_QP" },
|
||||
{L5_QP, "L5_QP" },
|
||||
{HIER_LAYER_QP, "HIER_LAYER_QP" },
|
||||
{HIER_CODING_TYPE, "HIER_CODING_TYPE" },
|
||||
{HIER_CODING, "HIER_CODING" },
|
||||
{HIER_CODING_LAYER, "HIER_CODING_LAYER" },
|
||||
{LAYER_TYPE, "LAYER_TYPE" },
|
||||
{LAYER_ENABLE, "LAYER_ENABLE" },
|
||||
{ENH_LAYER_COUNT, "ENH_LAYER_COUNT" },
|
||||
{L0_BR, "L0_BR" },
|
||||
{L1_BR, "L1_BR" },
|
||||
{L2_BR, "L2_BR" },
|
||||
@@ -1063,6 +1063,7 @@ bool msm_vidc_allow_s_ctrl(struct msm_vidc_inst *inst, u32 id)
|
||||
case V4L2_CID_VFLIP:
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_I_FRAME_QP:
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER:
|
||||
case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER:
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L0_BR:
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L1_BR:
|
||||
case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_L2_BR:
|
||||
|
Reference in New Issue
Block a user