diff --git a/driver/variant/iris2/inc/hfi_buffer_iris2.h b/driver/variant/iris2/inc/hfi_buffer_iris2.h index 02ca6e325e..ab617ae8ae 100644 --- a/driver/variant/iris2/inc/hfi_buffer_iris2.h +++ b/driver/variant/iris2/inc/hfi_buffer_iris2.h @@ -969,7 +969,8 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes) \ #define HFI_IRIS2_ENC_RECON_BUF_COUNT(num_recon, n_bframe, ltr_count, \ _total_hp_layers, _total_hb_layers, hybrid_hp, codec_standard) \ - do { \ + do \ + { \ HFI_U32 num_ref = 1; \ if (n_bframe) \ num_ref = 2; \ @@ -1542,24 +1543,24 @@ _yuv_bufcount_min, is_opb, num_vpp_pipes) \ HFI_BUFFER_DPB_ENC(_size, frame_width, frame_height, is_ten_bit); \ } while (0) -#define HFI_BUFFER_VPSS_ENC(vpss_size, bitstream_framewidth, bitstream_frameheight, ds_enable, \ - rotation, is_ten_bit) \ +#define HFI_BUFFER_VPSS_ENC(vpss_size, dswidth, dsheight, ds_enable, is_ten_bit) \ do \ { \ vpss_size = 0; \ if (ds_enable) \ { \ - if (rotation == HFI_ROTATION_90 || rotation == HFI_ROTATION_270 ) \ - { \ - HFI_BUFFER_DPB_ENC(vpss_size, bitstream_frameheight, \ - bitstream_framewidth, is_ten_bit); \ - } \ - else \ - { \ - HFI_BUFFER_DPB_ENC(vpss_size, bitstream_framewidth, \ - bitstream_frameheight, is_ten_bit); \ - } \ + HFI_BUFFER_DPB_ENC(vpss_size, dswidth, dsheight, is_ten_bit); \ } \ } while (0) +#define HFI_IRIS2_ENC_MIN_INPUT_BUF_COUNT(numInput, TotalHBLayers) \ + do \ + { \ + numInput = 3; \ + if (TotalHBLayers >= 2) \ + { \ + numInput = (1 << (TotalHBLayers - 1)) + 2; \ + } \ + } while (0) + #endif /* __HFI_BUFFER_IRIS2__ */ diff --git a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c index 073ba69aab..faff09f519 100644 --- a/driver/variant/iris2/src/msm_vidc_buffer_iris2.c +++ b/driver/variant/iris2/src/msm_vidc_buffer_iris2.c @@ -454,16 +454,27 @@ static u32 msm_vidc_encoder_vpss_size_iris2(struct msm_vidc_inst* inst) ds_enable = is_scaling_enabled(inst); msm_vidc_v4l2_to_hfi_enum(inst, ROTATION, &rotation_val); - width = inst->compose.width; - height = inst->compose.height; + f = &inst->fmts[OUTPUT_PORT]; + if (inst->capabilities->cap[ROTATION].value == 90 || + inst->capabilities->cap[ROTATION].value == 270) { + /* + * output width and height are rotated, + * so unrotate them to use as arguments to + * HFI_BUFFER_VPSS_ENC. + */ + width = f->fmt.pix_mp.height; + height = f->fmt.pix_mp.width; + } else { + width = f->fmt.pix_mp.width; + height = f->fmt.pix_mp.height; + } f = &inst->fmts[INPUT_PORT]; driver_colorfmt = v4l2_colorformat_to_driver( f->fmt.pix_mp.pixelformat, __func__); is_tenbit = is_10bit_colorformat(driver_colorfmt); - HFI_BUFFER_VPSS_ENC(size, width, height, ds_enable, - rotation_val, is_tenbit); + HFI_BUFFER_VPSS_ENC(size, width, height, ds_enable, is_tenbit); i_vpr_l(inst, "%s: size %d\n", __func__, size); return size; } @@ -539,6 +550,39 @@ exit: return size; } +static int msm_vidc_input_min_count_iris2(struct msm_vidc_inst* inst) +{ + u32 input_min_count = 0; + u32 total_hb_layer = 0; + + if (!inst || !inst->capabilities) { + d_vpr_e("%s: invalid params\n", __func__); + return 0; + } + + if (is_decode_session(inst)) { + input_min_count = MIN_DEC_INPUT_BUFFERS; + } else if (is_encode_session(inst)) { + total_hb_layer = is_hierb_requested(inst) ? + inst->capabilities->cap[ENH_LAYER_COUNT].value + 1 : 0; + if (inst->codec == MSM_VIDC_H264 && + !inst->capabilities->cap[LAYER_ENABLE].value) { + total_hb_layer = 0; + } + HFI_IRIS2_ENC_MIN_INPUT_BUF_COUNT(input_min_count, + total_hb_layer); + } else { + i_vpr_e(inst, "%s: invalid domain\n", + __func__, inst->domain); + return 0; + } + + if (is_thumbnail_session(inst) || is_image_session(inst)) + input_min_count = 1; + + return input_min_count; +} + static int msm_buffer_dpb_count(struct msm_vidc_inst *inst) { int count = 0; @@ -575,7 +619,7 @@ int msm_buffer_min_count_iris2(struct msm_vidc_inst *inst, switch (buffer_type) { case MSM_VIDC_BUF_INPUT: case MSM_VIDC_BUF_INPUT_META: - count = msm_vidc_input_min_count(inst); + count = msm_vidc_input_min_count_iris2(inst); break; case MSM_VIDC_BUF_OUTPUT: case MSM_VIDC_BUF_OUTPUT_META: diff --git a/driver/vidc/inc/msm_vidc_driver.h b/driver/vidc/inc/msm_vidc_driver.h index 5c044c0b18..8adff2906c 100644 --- a/driver/vidc/inc/msm_vidc_driver.h +++ b/driver/vidc/inc/msm_vidc_driver.h @@ -197,6 +197,16 @@ static inline bool is_lowlatency_session(struct msm_vidc_inst *inst) return !!(inst->capabilities->cap[LOWLATENCY_MODE].value); } +static inline bool is_hierb_requested(struct msm_vidc_inst *inst) +{ + return (inst->codec == MSM_VIDC_H264 && + inst->capabilities->cap[LAYER_TYPE].value == + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B) || + (inst->codec == MSM_VIDC_HEVC && + inst->capabilities->cap[LAYER_TYPE].value == + V4L2_MPEG_VIDEO_HEVC_HIERARCHICAL_CODING_B); +} + static inline bool is_active_session(u64 prev, u64 curr) { u64 ts_delta; diff --git a/driver/vidc/src/msm_vidc_buffer.c b/driver/vidc/src/msm_vidc_buffer.c index 46cf0c8370..56546f7912 100644 --- a/driver/vidc/src/msm_vidc_buffer.c +++ b/driver/vidc/src/msm_vidc_buffer.c @@ -11,11 +11,13 @@ #include "msm_vidc_debug.h" #include "msm_vidc_internal.h" +/* Generic function for all targets. Not being used for iris2 */ u32 msm_vidc_input_min_count(struct msm_vidc_inst* inst) { u32 input_min_count = 0; + u32 hb_enh_layer = 0; - if (!inst) { + if (!inst || !inst->capabilities) { d_vpr_e("%s: invalid params\n", __func__); return 0; } @@ -24,6 +26,16 @@ u32 msm_vidc_input_min_count(struct msm_vidc_inst* inst) input_min_count = MIN_DEC_INPUT_BUFFERS; } else if (is_encode_session(inst)) { input_min_count = MIN_ENC_INPUT_BUFFERS; + if (is_hierb_requested(inst)) { + hb_enh_layer = + inst->capabilities->cap[ENH_LAYER_COUNT].value; + if (inst->codec == MSM_VIDC_H264 && + !inst->capabilities->cap[LAYER_ENABLE].value) { + hb_enh_layer = 0; + } + if (hb_enh_layer) + input_min_count = (1 << hb_enh_layer) + 2; + } } else { i_vpr_e(inst, "%s: invalid domain\n", __func__, inst->domain); diff --git a/driver/vidc/src/msm_vidc_control.c b/driver/vidc/src/msm_vidc_control.c index f757379505..eb0bc6b8cf 100644 --- a/driver/vidc/src/msm_vidc_control.c +++ b/driver/vidc/src/msm_vidc_control.c @@ -637,6 +637,49 @@ error: return rc; } +static int msm_vidc_update_buffer_count_if_needed(struct msm_vidc_inst* inst, + struct v4l2_ctrl *ctrl) +{ + int rc = 0; + bool update_input_port = false, update_output_port = false; + + if (!inst || !inst->capabilities || !ctrl) { + d_vpr_e("%s: invalid parameters\n", __func__); + return -EINVAL; + } + + switch (ctrl->id) { + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_TYPE: + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE: + case V4L2_CID_MPEG_VIDEO_HEVC_HIER_CODING_LAYER: + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING: + case V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER: + update_input_port = true; + break; + case V4L2_CID_MPEG_VIDC_THUMBNAIL_MODE: + update_input_port = true; + update_output_port = true; + break; + default: + update_input_port = false; + update_output_port = false; + break; + } + + if (update_input_port) { + rc = msm_vidc_update_buffer_count(inst, INPUT_PORT); + if (rc) + return rc; + } + if (update_output_port) { + rc = msm_vidc_update_buffer_count(inst, OUTPUT_PORT); + if (rc) + return rc; + } + + return rc; +} + int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl) { int rc = 0; @@ -709,14 +752,6 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl) if (rc) return rc; } - if (ctrl->id == V4L2_CID_MPEG_VIDC_THUMBNAIL_MODE) { - rc = msm_vidc_update_buffer_count(inst, INPUT_PORT); - if (rc) - return rc; - rc = msm_vidc_update_buffer_count(inst, OUTPUT_PORT); - if (rc) - return rc; - } if (is_meta_ctrl(ctrl->id)) { if (cap_id == META_DPB_TAG_LIST) { /* @@ -734,6 +769,10 @@ int msm_v4l2_op_s_ctrl(struct v4l2_ctrl *ctrl) if (rc) return rc; } + rc = msm_vidc_update_buffer_count_if_needed(inst, ctrl); + if (rc) + return rc; + return 0; }