Loading drivers/media/platform/msm/vidc/msm_vdec.c +13 −0 Original line number Diff line number Diff line Loading @@ -1196,6 +1196,19 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) hdev = inst->core->device; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE); if (ctrl->val) { if (!(inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_VP9 || inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2)) { dprintk(VIDC_ERR, "%s: Secure allowed for HEVC/H264/VP9/MPEG2\n", __func__); return -EINVAL; } } dprintk(VIDC_DBG, "%s: %#x\n", __func__, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &ctrl->val, sizeof(u32)); Loading drivers/media/platform/msm/vidc/msm_venc.c +169 −27 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ #define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8) #define MAX_LTR_FRAME_COUNT 10 #define MAX_NUM_B_FRAMES 1 #define MIN_CBRPLUS_W 1280 #define MIN_CBRPLUS_H 720 #define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 Loading Loading @@ -1918,6 +1920,16 @@ int msm_venc_set_secure_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE); enable.enable = !!ctrl->val; if (enable.enable) { if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) { dprintk(VIDC_ERR, "%s: Secure mode only allowed for HEVC/H264\n", __func__); return -EINVAL; } } dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &enable, sizeof(enable)); Loading Loading @@ -2252,13 +2264,55 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; u32 hfi_rc; u32 hfi_rc, codec; u32 height, width, mbpf; struct hfi_vbv_hrd_buf_size hrd_buf_size; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; inst->clk_data.is_cbr_plus = false; codec = inst->fmts[CAPTURE_PORT].fourcc; height = inst->prop.height[OUTPUT_PORT]; width = inst->prop.width[OUTPUT_PORT]; mbpf = NUM_MBS_PER_FRAME(height, width); if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR) inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR; else if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && inst->clk_data.low_latency_mode) inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; if ((inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) && (codec != V4L2_PIX_FMT_VP8)) { hrd_buf_size.vbv_hrd_buf_size = 500; inst->clk_data.low_latency_mode = true; if ((width > MIN_CBRPLUS_W && height > MIN_CBRPLUS_H) || (width > MIN_CBRPLUS_H && height > MIN_CBRPLUS_W) || mbpf > NUM_MBS_PER_FRAME(720, 1280)) { hrd_buf_size.vbv_hrd_buf_size = 1000; inst->clk_data.is_cbr_plus = true; } dprintk(VIDC_DBG, "Set hrd_buf_size %d", hrd_buf_size.vbv_hrd_buf_size); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size, sizeof(hrd_buf_size)); if (rc) { dprintk(VIDC_ERR, "%s: set HRD_BUF_SIZE %u failed\n", __func__, hrd_buf_size.vbv_hrd_buf_size); inst->clk_data.is_cbr_plus = false; } } switch (inst->rc_type) { case RATE_CONTROL_OFF: Loading @@ -2276,9 +2330,6 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR: hfi_rc = HFI_RATE_CONTROL_CBR_VFR; break; case V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR: hfi_rc = HFI_RATE_CONTROL_MBR_VFR; break; case V4L2_MPEG_VIDEO_BITRATE_MODE_CQ: hfi_rc = HFI_RATE_CONTROL_CQ; break; Loading Loading @@ -2694,35 +2745,88 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) struct v4l2_ctrl *ctrl_t; struct hfi_multi_slice_control multi_slice_control; int temp = 0; u32 mb_per_frame, fps, mbps, bitrate; u32 slice_val, slice_mode, max_avg_slicesize; u32 rc_mode, output_width, output_height; struct v4l2_ctrl *rc_enable; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC && inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) return 0; slice_mode = HFI_MULTI_SLICE_OFF; slice_val = 0; bitrate = inst->clk_data.bitrate; fps = inst->clk_data.frame_rate; rc_mode = inst->rc_type; rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); if (fps > 60 || (rc_enable->val && rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) { goto set_and_exit; } output_width = inst->prop.width[OUTPUT_PORT]; output_height = inst->prop.height[OUTPUT_PORT]; if (output_height < 128 || (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC && output_width < 384) || (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264 && output_width < 192)) { goto set_and_exit; } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); multi_slice_control.multi_slice = HFI_MULTI_SLICE_OFF; temp = 0; if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; multi_slice_control.multi_slice = HFI_MULTI_SLICE_BY_MB_COUNT; slice_mode = HFI_MULTI_SLICE_BY_MB_COUNT; } else if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; multi_slice_control.multi_slice = HFI_MULTI_SLICE_BY_BYTE_COUNT; slice_mode = HFI_MULTI_SLICE_BY_BYTE_COUNT; } else { goto set_and_exit; } multi_slice_control.slice_size = 0; if (temp) { ctrl_t = get_ctrl(inst, temp); multi_slice_control.slice_size = ctrl_t->val; slice_val = ctrl_t->val; /* Update Slice Config */ mb_per_frame = NUM_MBS_PER_FRAME(output_height, output_width); mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); if (slice_mode == HFI_MULTI_SLICE_BY_MB_COUNT) { if (output_width <= 4096 || output_height <= 4096 || mb_per_frame <= NUM_MBS_PER_FRAME(4096, 2160) || mbps <= NUM_MBS_PER_SEC(4096, 2160, 60)) { slice_val = max(slice_val, mb_per_frame / 10); } } else { if (output_width <= 1920 || output_height <= 1920 || mb_per_frame <= NUM_MBS_PER_FRAME(1088, 1920) || mbps <= NUM_MBS_PER_SEC(1088, 1920, 60)) { max_avg_slicesize = ((bitrate / fps) / 8) / 10; slice_val = max(slice_val, max_avg_slicesize); } } if (slice_mode == HFI_MULTI_SLICE_OFF) { ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; ctrl_t->val = 0; } set_and_exit: multi_slice_control.multi_slice = slice_mode; multi_slice_control.slice_size = slice_val; hdev = inst->core->device; dprintk(VIDC_DBG, "%s: %d %d\n", __func__, multi_slice_control.multi_slice, multi_slice_control.slice_size); Loading @@ -2739,7 +2843,8 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct v4l2_ctrl *ctrl = NULL; struct v4l2_ctrl *rc_mode = NULL; struct hfi_intra_refresh intra_refresh; if (!inst || !inst->core) { Loading @@ -2748,6 +2853,11 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); if (!(rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR || rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM); intra_refresh.mbs = 0; if (ctrl->val) { Loading Loading @@ -2791,6 +2901,9 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE); ctrl_a = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA); ctrl_b = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA); Loading Loading @@ -2825,6 +2938,10 @@ int msm_venc_set_sequence_header_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR); if (ctrl->val) enable.enable = true; Loading Loading @@ -2854,6 +2971,10 @@ int msm_venc_set_au_delimiter_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER); enable.enable = !!ctrl->val; Loading Loading @@ -3096,7 +3217,8 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl_cs = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); Loading Loading @@ -3166,8 +3288,8 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct v4l2_ctrl *profile; struct v4l2_ctrl *ctrl = NULL; struct v4l2_ctrl *profile = NULL; struct hfi_enable enable; if (!inst || !inst->core) { Loading @@ -3176,17 +3298,13 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264 && inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) return 0; if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264) { profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE); if (profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE || profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) if (!(profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH || profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH)) return 0; } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM); enable.enable = !!ctrl->val; Loading Loading @@ -3310,6 +3428,10 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); if (!ctrl->val) return 0; Loading Loading @@ -3344,6 +3466,10 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME); use_ltr.ref_ltr = ctrl->val; use_ltr.use_constrnt = false; Loading Loading @@ -3371,6 +3497,10 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME); mark_ltr.mark_frame = ctrl->val; Loading Loading @@ -3435,6 +3565,10 @@ int msm_venc_set_aspect_ratio(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH); if (!ctrl->val) return 0; Loading Loading @@ -3485,6 +3619,7 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) { int rc = 0; struct v4l2_ctrl *profile = NULL; struct hfi_device *hdev; if (!inst || !inst->core) { Loading @@ -3493,6 +3628,13 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) return 0; profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE); if (profile->val != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) return 0; /* No conversion to HFI needed as both structures are same */ dprintk(VIDC_DBG, "%s: setting hdr info\n", __func__); rc = call_hfi_op(hdev, session_set_property, inst->session, Loading drivers/media/platform/msm/vidc/msm_vidc.c +0 −66 Original line number Diff line number Diff line Loading @@ -797,64 +797,6 @@ static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst) return rc; } int msm_vidc_set_internal_config(struct msm_vidc_inst *inst) { int rc = 0; u32 rc_mode = RATE_CONTROL_OFF; struct hfi_vbv_hdr_buf_size hrd_buf_size; struct hfi_enable latency; struct hfi_device *hdev; u32 codec; u32 mbps, fps; u32 output_width, output_height; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__); return -EINVAL; } if (inst->session_type != MSM_VIDC_ENCODER) return rc; hdev = inst->core->device; codec = inst->fmts[CAPTURE_PORT].fourcc; latency.enable = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE); if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR) rc_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR; else if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && latency.enable == V4L2_MPEG_MSM_VIDC_ENABLE && codec != V4L2_PIX_FMT_VP8) rc_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; output_height = inst->prop.height[CAPTURE_PORT]; output_width = inst->prop.width[CAPTURE_PORT]; fps = inst->clk_data.frame_rate >> 16; mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); if ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) && (codec != V4L2_PIX_FMT_VP8)) { if ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && mbps <= CBR_MB_LIMIT) || (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps <= CBR_VFR_MB_LIMIT)) hrd_buf_size.vbv_hdr_buf_size = 500; else hrd_buf_size.vbv_hdr_buf_size = 1000; dprintk(VIDC_DBG, "Enable hdr_buf_size %d :\n", hrd_buf_size.vbv_hdr_buf_size); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size, sizeof(hrd_buf_size)); inst->clk_data.low_latency_mode = true; } return rc; } static int msm_vidc_set_rotation(struct msm_vidc_inst *inst) { int rc = 0; Loading Loading @@ -997,14 +939,6 @@ static inline int start_streaming(struct msm_vidc_inst *inst) goto fail_start; } rc = msm_vidc_set_internal_config(inst); if (rc) { dprintk(VIDC_ERR, "Set internal config failed %pK\n", inst); goto fail_start; } /* Decide work mode for current session */ rc = call_core_op(inst->core, decide_work_mode, inst); if (rc) { Loading drivers/media/platform/msm/vidc/msm_vidc_clocks.c +54 −43 Original line number Diff line number Diff line Loading @@ -1272,6 +1272,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) int rc = 0; struct hfi_device *hdev; struct hfi_video_work_route pdata; bool cbr_plus; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, Loading @@ -1281,45 +1282,39 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) } hdev = inst->core->device; cbr_plus = inst->clk_data.is_cbr_plus; pdata.video_work_route = 4; if (inst->session_type == MSM_VIDC_DECODER) { if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) pdata.video_work_route = 1; } else if (inst->session_type == MSM_VIDC_ENCODER) { u32 slice_mode, rc_mode; u32 output_width, output_height, fps, mbps; bool cbr_plus; u32 slice_mode, output_width, output_height, num_mbs; bool is_1080p_above; if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { pdata.video_work_route = 1; goto decision_done; } rc_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); slice_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); output_height = inst->prop.height[CAPTURE_PORT]; output_width = inst->prop.width[CAPTURE_PORT]; fps = inst->clk_data.frame_rate >> 16; mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); cbr_plus = ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && mbps > CBR_MB_LIMIT) || (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps > CBR_VFR_MB_LIMIT)); output_height = inst->prop.height[OUTPUT_PORT]; output_width = inst->prop.width[OUTPUT_PORT]; num_mbs = NUM_MBS_PER_FRAME(output_height, output_width); is_1080p_above = ((output_height > 1088 && output_width > 1920) || (output_height > 1920 && output_width > 1088) || num_mbs > NUM_MBS_PER_FRAME(1088, 1920)); if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || ((mbps <= NUM_MBS_PER_SEC(1920, 1088, 60)) && !cbr_plus) ) { inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 || (!is_1080p_above && !cbr_plus)) { pdata.video_work_route = 1; dprintk(VIDC_DBG, "Configured work route = 1"); } } else { return -EINVAL; } decision_done: dprintk(VIDC_DBG, "Configurng work route = %u", pdata.video_work_route); inst->clk_data.work_route = pdata.video_work_route; rc = call_hfi_op(hdev, session_set_property, Loading Loading @@ -1486,6 +1481,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) struct hfi_video_work_mode pdata; struct hfi_enable latency; u32 num_mbs = 0; u32 width, height; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, Loading @@ -1496,28 +1492,52 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) hdev = inst->core->device; pdata.video_work_mode = HFI_WORKMODE_2; latency.enable = inst->clk_data.low_latency_mode; if (inst->clk_data.low_latency_mode) { pdata.video_work_mode = HFI_WORKMODE_1; dprintk(VIDC_DBG, "Configured work mode = 1"); } else if (inst->session_type == MSM_VIDC_DECODER) { num_mbs = NUM_MBS_PER_FRAME( inst->prop.height[OUTPUT_PORT], inst->prop.width[OUTPUT_PORT]); if (inst->session_type == MSM_VIDC_DECODER) { height = inst->prop.height[CAPTURE_PORT]; width = inst->prop.width[CAPTURE_PORT]; num_mbs = NUM_MBS_PER_FRAME(height, width); if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || (inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) || (num_mbs < NUM_MBS_PER_FRAME(720, 1280))) inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE || inst->clk_data.low_latency_mode || (width < 1280 && height < 720) || (width < 720 && height < 1280) || num_mbs < NUM_MBS_PER_FRAME(720, 1280)) { pdata.video_work_mode = HFI_WORKMODE_1; } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { height = inst->prop.height[OUTPUT_PORT]; width = inst->prop.width[OUTPUT_PORT]; num_mbs = NUM_MBS_PER_FRAME(height, width); if ((num_mbs >= NUM_MBS_PER_FRAME(2160, 4096) || (width < 4096 && height < 2160) || (width < 2160 && height < 4096)) && (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 || inst->clk_data.low_latency_mode)) { pdata.video_work_mode = HFI_WORKMODE_1; /* For WORK_MODE_1, set Low Latency mode by default */ inst->clk_data.low_latency_mode = true; latency.enable = true; } } else { return -EINVAL; } dprintk(VIDC_DBG, "Configuring work mode = %u low latency = %u", inst->clk_data.work_mode, latency.enable); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, (void *)&latency, sizeof(latency)); if (rc) dprintk(VIDC_WARN, " Failed to configure low latency %pK\n", inst); else inst->clk_data.low_latency_mode = latency.enable; inst->clk_data.work_mode = pdata.video_work_mode; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, Loading @@ -1526,15 +1546,6 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) dprintk(VIDC_WARN, " Failed to configure Work Mode %pK\n", inst); if (inst->clk_data.low_latency_mode && inst->session_type == MSM_VIDC_ENCODER){ latency.enable = true; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, (void *)&latency, sizeof(latency)); } return rc; } Loading drivers/media/platform/msm/vidc/msm_vidc_internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -362,6 +362,7 @@ struct clock_data { u32 opb_fourcc; u32 work_mode; bool low_latency_mode; bool is_cbr_plus; bool turbo_mode; u32 work_route; u32 dcvs_flags; Loading Loading
drivers/media/platform/msm/vidc/msm_vdec.c +13 −0 Original line number Diff line number Diff line Loading @@ -1196,6 +1196,19 @@ int msm_vdec_set_secure_mode(struct msm_vidc_inst *inst) hdev = inst->core->device; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE); if (ctrl->val) { if (!(inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_VP9 || inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2)) { dprintk(VIDC_ERR, "%s: Secure allowed for HEVC/H264/VP9/MPEG2\n", __func__); return -EINVAL; } } dprintk(VIDC_DBG, "%s: %#x\n", __func__, ctrl->val); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &ctrl->val, sizeof(u32)); Loading
drivers/media/platform/msm/vidc/msm_venc.c +169 −27 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ #define MAX_INTRA_REFRESH_MBS ((7680 * 4320) >> 8) #define MAX_LTR_FRAME_COUNT 10 #define MAX_NUM_B_FRAMES 1 #define MIN_CBRPLUS_W 1280 #define MIN_CBRPLUS_H 720 #define L_MODE V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY #define MIN_NUM_ENC_OUTPUT_BUFFERS 4 Loading Loading @@ -1918,6 +1920,16 @@ int msm_venc_set_secure_mode(struct msm_vidc_inst *inst) ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_SECURE); enable.enable = !!ctrl->val; if (enable.enable) { if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) { dprintk(VIDC_ERR, "%s: Secure mode only allowed for HEVC/H264\n", __func__); return -EINVAL; } } dprintk(VIDC_DBG, "%s: %d\n", __func__, enable.enable); rc = call_hfi_op(hdev, session_set_property, inst->session, HFI_PROPERTY_PARAM_SECURE_SESSION, &enable, sizeof(enable)); Loading Loading @@ -2252,13 +2264,55 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; u32 hfi_rc; u32 hfi_rc, codec; u32 height, width, mbpf; struct hfi_vbv_hrd_buf_size hrd_buf_size; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; inst->clk_data.is_cbr_plus = false; codec = inst->fmts[CAPTURE_PORT].fourcc; height = inst->prop.height[OUTPUT_PORT]; width = inst->prop.width[OUTPUT_PORT]; mbpf = NUM_MBS_PER_FRAME(height, width); if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR) inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR; else if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && inst->clk_data.low_latency_mode) inst->rc_type = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; if ((inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) && (codec != V4L2_PIX_FMT_VP8)) { hrd_buf_size.vbv_hrd_buf_size = 500; inst->clk_data.low_latency_mode = true; if ((width > MIN_CBRPLUS_W && height > MIN_CBRPLUS_H) || (width > MIN_CBRPLUS_H && height > MIN_CBRPLUS_W) || mbpf > NUM_MBS_PER_FRAME(720, 1280)) { hrd_buf_size.vbv_hrd_buf_size = 1000; inst->clk_data.is_cbr_plus = true; } dprintk(VIDC_DBG, "Set hrd_buf_size %d", hrd_buf_size.vbv_hrd_buf_size); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size, sizeof(hrd_buf_size)); if (rc) { dprintk(VIDC_ERR, "%s: set HRD_BUF_SIZE %u failed\n", __func__, hrd_buf_size.vbv_hrd_buf_size); inst->clk_data.is_cbr_plus = false; } } switch (inst->rc_type) { case RATE_CONTROL_OFF: Loading @@ -2276,9 +2330,6 @@ int msm_venc_set_rate_control(struct msm_vidc_inst *inst) case V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR: hfi_rc = HFI_RATE_CONTROL_CBR_VFR; break; case V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR: hfi_rc = HFI_RATE_CONTROL_MBR_VFR; break; case V4L2_MPEG_VIDEO_BITRATE_MODE_CQ: hfi_rc = HFI_RATE_CONTROL_CQ; break; Loading Loading @@ -2694,35 +2745,88 @@ int msm_venc_set_slice_control_mode(struct msm_vidc_inst *inst) struct v4l2_ctrl *ctrl_t; struct hfi_multi_slice_control multi_slice_control; int temp = 0; u32 mb_per_frame, fps, mbps, bitrate; u32 slice_val, slice_mode, max_avg_slicesize; u32 rc_mode, output_width, output_height; struct v4l2_ctrl *rc_enable; if (!inst || !inst->core) { dprintk(VIDC_ERR, "%s: invalid params\n", __func__); return -EINVAL; } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC && inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) return 0; slice_mode = HFI_MULTI_SLICE_OFF; slice_val = 0; bitrate = inst->clk_data.bitrate; fps = inst->clk_data.frame_rate; rc_mode = inst->rc_type; rc_enable = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE); if (fps > 60 || (rc_enable->val && rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && rc_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) { goto set_and_exit; } output_width = inst->prop.width[OUTPUT_PORT]; output_height = inst->prop.height[OUTPUT_PORT]; if (output_height < 128 || (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC && output_width < 384) || (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264 && output_width < 192)) { goto set_and_exit; } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); multi_slice_control.multi_slice = HFI_MULTI_SLICE_OFF; temp = 0; if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_MB) { temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_MB; multi_slice_control.multi_slice = HFI_MULTI_SLICE_BY_MB_COUNT; slice_mode = HFI_MULTI_SLICE_BY_MB_COUNT; } else if (ctrl->val == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES) { temp = V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MAX_BYTES; multi_slice_control.multi_slice = HFI_MULTI_SLICE_BY_BYTE_COUNT; slice_mode = HFI_MULTI_SLICE_BY_BYTE_COUNT; } else { goto set_and_exit; } multi_slice_control.slice_size = 0; if (temp) { ctrl_t = get_ctrl(inst, temp); multi_slice_control.slice_size = ctrl_t->val; slice_val = ctrl_t->val; /* Update Slice Config */ mb_per_frame = NUM_MBS_PER_FRAME(output_height, output_width); mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); if (slice_mode == HFI_MULTI_SLICE_BY_MB_COUNT) { if (output_width <= 4096 || output_height <= 4096 || mb_per_frame <= NUM_MBS_PER_FRAME(4096, 2160) || mbps <= NUM_MBS_PER_SEC(4096, 2160, 60)) { slice_val = max(slice_val, mb_per_frame / 10); } } else { if (output_width <= 1920 || output_height <= 1920 || mb_per_frame <= NUM_MBS_PER_FRAME(1088, 1920) || mbps <= NUM_MBS_PER_SEC(1088, 1920, 60)) { max_avg_slicesize = ((bitrate / fps) / 8) / 10; slice_val = max(slice_val, max_avg_slicesize); } } if (slice_mode == HFI_MULTI_SLICE_OFF) { ctrl->val = V4L2_MPEG_VIDEO_MULTI_SLICE_MODE_SINGLE; ctrl_t->val = 0; } set_and_exit: multi_slice_control.multi_slice = slice_mode; multi_slice_control.slice_size = slice_val; hdev = inst->core->device; dprintk(VIDC_DBG, "%s: %d %d\n", __func__, multi_slice_control.multi_slice, multi_slice_control.slice_size); Loading @@ -2739,7 +2843,8 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct v4l2_ctrl *ctrl = NULL; struct v4l2_ctrl *rc_mode = NULL; struct hfi_intra_refresh intra_refresh; if (!inst || !inst->core) { Loading @@ -2748,6 +2853,11 @@ int msm_venc_set_intra_refresh_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; rc_mode = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); if (!(rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR || rc_mode->val == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM); intra_refresh.mbs = 0; if (ctrl->val) { Loading Loading @@ -2791,6 +2901,9 @@ int msm_venc_set_loop_filter_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_MODE); ctrl_a = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_ALPHA); ctrl_b = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_LOOP_FILTER_BETA); Loading Loading @@ -2825,6 +2938,10 @@ int msm_venc_set_sequence_header_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_PREPEND_SPSPPS_TO_IDR); if (ctrl->val) enable.enable = true; Loading Loading @@ -2854,6 +2971,10 @@ int msm_venc_set_au_delimiter_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_AU_DELIMITER); enable.enable = !!ctrl->val; Loading Loading @@ -3096,7 +3217,8 @@ int msm_venc_set_video_signal_info(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl_cs = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_COLOR_SPACE); Loading Loading @@ -3166,8 +3288,8 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) { int rc = 0; struct hfi_device *hdev; struct v4l2_ctrl *ctrl; struct v4l2_ctrl *profile; struct v4l2_ctrl *ctrl = NULL; struct v4l2_ctrl *profile = NULL; struct hfi_enable enable; if (!inst || !inst->core) { Loading @@ -3176,17 +3298,13 @@ int msm_venc_set_8x8_transform(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264 && inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_H264) return 0; if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264) { profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_PROFILE); if (profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE || profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) if (!(profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_HIGH || profile->val == V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH)) return 0; } ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_8X8_TRANSFORM); enable.enable = !!ctrl->val; Loading Loading @@ -3310,6 +3428,10 @@ int msm_venc_set_ltr_mode(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT); if (!ctrl->val) return 0; Loading Loading @@ -3344,6 +3466,10 @@ int msm_venc_set_ltr_useframe(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME); use_ltr.ref_ltr = ctrl->val; use_ltr.use_constrnt = false; Loading Loading @@ -3371,6 +3497,10 @@ int msm_venc_set_ltr_markframe(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME); mark_ltr.mark_frame = ctrl->val; Loading Loading @@ -3435,6 +3565,10 @@ int msm_venc_set_aspect_ratio(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (!(inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_H264 || inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_HEVC)) return 0; ctrl = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_H264_VUI_EXT_SAR_WIDTH); if (!ctrl->val) return 0; Loading Loading @@ -3485,6 +3619,7 @@ int msm_venc_set_blur_resolution(struct msm_vidc_inst *inst) int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) { int rc = 0; struct v4l2_ctrl *profile = NULL; struct hfi_device *hdev; if (!inst || !inst->core) { Loading @@ -3493,6 +3628,13 @@ int msm_venc_set_hdr_info(struct msm_vidc_inst *inst) } hdev = inst->core->device; if (inst->fmts[CAPTURE_PORT].fourcc != V4L2_PIX_FMT_HEVC) return 0; profile = get_ctrl(inst, V4L2_CID_MPEG_VIDEO_HEVC_PROFILE); if (profile->val != V4L2_MPEG_VIDEO_HEVC_PROFILE_MAIN_10) return 0; /* No conversion to HFI needed as both structures are same */ dprintk(VIDC_DBG, "%s: setting hdr info\n", __func__); rc = call_hfi_op(hdev, session_set_property, inst->session, Loading
drivers/media/platform/msm/vidc/msm_vidc.c +0 −66 Original line number Diff line number Diff line Loading @@ -797,64 +797,6 @@ static inline int msm_vidc_verify_buffer_counts(struct msm_vidc_inst *inst) return rc; } int msm_vidc_set_internal_config(struct msm_vidc_inst *inst) { int rc = 0; u32 rc_mode = RATE_CONTROL_OFF; struct hfi_vbv_hdr_buf_size hrd_buf_size; struct hfi_enable latency; struct hfi_device *hdev; u32 codec; u32 mbps, fps; u32 output_width, output_height; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_WARN, "%s: Invalid parameter\n", __func__); return -EINVAL; } if (inst->session_type != MSM_VIDC_ENCODER) return rc; hdev = inst->core->device; codec = inst->fmts[CAPTURE_PORT].fourcc; latency.enable = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDC_VIDEO_LOWLATENCY_MODE); if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_MBR_VFR) rc_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_MBR; else if (inst->rc_type == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR && latency.enable == V4L2_MPEG_MSM_VIDC_ENABLE && codec != V4L2_PIX_FMT_VP8) rc_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR; output_height = inst->prop.height[CAPTURE_PORT]; output_width = inst->prop.width[CAPTURE_PORT]; fps = inst->clk_data.frame_rate >> 16; mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); if ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR || rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR) && (codec != V4L2_PIX_FMT_VP8)) { if ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && mbps <= CBR_MB_LIMIT) || (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps <= CBR_VFR_MB_LIMIT)) hrd_buf_size.vbv_hdr_buf_size = 500; else hrd_buf_size.vbv_hdr_buf_size = 1000; dprintk(VIDC_DBG, "Enable hdr_buf_size %d :\n", hrd_buf_size.vbv_hdr_buf_size); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_CONFIG_VENC_VBV_HRD_BUF_SIZE, (void *)&hrd_buf_size, sizeof(hrd_buf_size)); inst->clk_data.low_latency_mode = true; } return rc; } static int msm_vidc_set_rotation(struct msm_vidc_inst *inst) { int rc = 0; Loading Loading @@ -997,14 +939,6 @@ static inline int start_streaming(struct msm_vidc_inst *inst) goto fail_start; } rc = msm_vidc_set_internal_config(inst); if (rc) { dprintk(VIDC_ERR, "Set internal config failed %pK\n", inst); goto fail_start; } /* Decide work mode for current session */ rc = call_core_op(inst->core, decide_work_mode, inst); if (rc) { Loading
drivers/media/platform/msm/vidc/msm_vidc_clocks.c +54 −43 Original line number Diff line number Diff line Loading @@ -1272,6 +1272,7 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) int rc = 0; struct hfi_device *hdev; struct hfi_video_work_route pdata; bool cbr_plus; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, Loading @@ -1281,45 +1282,39 @@ int msm_vidc_decide_work_route_iris2(struct msm_vidc_inst *inst) } hdev = inst->core->device; cbr_plus = inst->clk_data.is_cbr_plus; pdata.video_work_route = 4; if (inst->session_type == MSM_VIDC_DECODER) { if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) pdata.video_work_route = 1; } else if (inst->session_type == MSM_VIDC_ENCODER) { u32 slice_mode, rc_mode; u32 output_width, output_height, fps, mbps; bool cbr_plus; u32 slice_mode, output_width, output_height, num_mbs; bool is_1080p_above; if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { pdata.video_work_route = 1; goto decision_done; } rc_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_BITRATE_MODE); slice_mode = msm_comm_g_ctrl_for_id(inst, V4L2_CID_MPEG_VIDEO_MULTI_SLICE_MODE); output_height = inst->prop.height[CAPTURE_PORT]; output_width = inst->prop.width[CAPTURE_PORT]; fps = inst->clk_data.frame_rate >> 16; mbps = NUM_MBS_PER_SEC(output_height, output_width, fps); cbr_plus = ((rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR && mbps > CBR_MB_LIMIT) || (rc_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR_VFR && mbps > CBR_VFR_MB_LIMIT)); output_height = inst->prop.height[OUTPUT_PORT]; output_width = inst->prop.width[OUTPUT_PORT]; num_mbs = NUM_MBS_PER_FRAME(output_height, output_width); is_1080p_above = ((output_height > 1088 && output_width > 1920) || (output_height > 1920 && output_width > 1088) || num_mbs > NUM_MBS_PER_FRAME(1088, 1920)); if (slice_mode == V4L2_MPEG_VIDEO_MULTI_SICE_MODE_MAX_BYTES || ((mbps <= NUM_MBS_PER_SEC(1920, 1088, 60)) && !cbr_plus) ) { inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 || (!is_1080p_above && !cbr_plus)) { pdata.video_work_route = 1; dprintk(VIDC_DBG, "Configured work route = 1"); } } else { return -EINVAL; } decision_done: dprintk(VIDC_DBG, "Configurng work route = %u", pdata.video_work_route); inst->clk_data.work_route = pdata.video_work_route; rc = call_hfi_op(hdev, session_set_property, Loading Loading @@ -1486,6 +1481,7 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) struct hfi_video_work_mode pdata; struct hfi_enable latency; u32 num_mbs = 0; u32 width, height; if (!inst || !inst->core || !inst->core->device) { dprintk(VIDC_ERR, Loading @@ -1496,28 +1492,52 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) hdev = inst->core->device; pdata.video_work_mode = HFI_WORKMODE_2; latency.enable = inst->clk_data.low_latency_mode; if (inst->clk_data.low_latency_mode) { pdata.video_work_mode = HFI_WORKMODE_1; dprintk(VIDC_DBG, "Configured work mode = 1"); } else if (inst->session_type == MSM_VIDC_DECODER) { num_mbs = NUM_MBS_PER_FRAME( inst->prop.height[OUTPUT_PORT], inst->prop.width[OUTPUT_PORT]); if (inst->session_type == MSM_VIDC_DECODER) { height = inst->prop.height[CAPTURE_PORT]; width = inst->prop.width[CAPTURE_PORT]; num_mbs = NUM_MBS_PER_FRAME(height, width); if (inst->fmts[OUTPUT_PORT].fourcc == V4L2_PIX_FMT_MPEG2 || (inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE) || (num_mbs < NUM_MBS_PER_FRAME(720, 1280))) inst->pic_struct != MSM_VIDC_PIC_STRUCT_PROGRESSIVE || inst->clk_data.low_latency_mode || (width < 1280 && height < 720) || (width < 720 && height < 1280) || num_mbs < NUM_MBS_PER_FRAME(720, 1280)) { pdata.video_work_mode = HFI_WORKMODE_1; } } else if (inst->session_type == MSM_VIDC_ENCODER) { if (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8) { height = inst->prop.height[OUTPUT_PORT]; width = inst->prop.width[OUTPUT_PORT]; num_mbs = NUM_MBS_PER_FRAME(height, width); if ((num_mbs >= NUM_MBS_PER_FRAME(2160, 4096) || (width < 4096 && height < 2160) || (width < 2160 && height < 4096)) && (inst->fmts[CAPTURE_PORT].fourcc == V4L2_PIX_FMT_VP8 || inst->clk_data.low_latency_mode)) { pdata.video_work_mode = HFI_WORKMODE_1; /* For WORK_MODE_1, set Low Latency mode by default */ inst->clk_data.low_latency_mode = true; latency.enable = true; } } else { return -EINVAL; } dprintk(VIDC_DBG, "Configuring work mode = %u low latency = %u", inst->clk_data.work_mode, latency.enable); rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, (void *)&latency, sizeof(latency)); if (rc) dprintk(VIDC_WARN, " Failed to configure low latency %pK\n", inst); else inst->clk_data.low_latency_mode = latency.enable; inst->clk_data.work_mode = pdata.video_work_mode; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_WORK_MODE, Loading @@ -1526,15 +1546,6 @@ int msm_vidc_decide_work_mode_iris2(struct msm_vidc_inst *inst) dprintk(VIDC_WARN, " Failed to configure Work Mode %pK\n", inst); if (inst->clk_data.low_latency_mode && inst->session_type == MSM_VIDC_ENCODER){ latency.enable = true; rc = call_hfi_op(hdev, session_set_property, (void *)inst->session, HFI_PROPERTY_PARAM_VENC_LOW_LATENCY_MODE, (void *)&latency, sizeof(latency)); } return rc; } Loading
drivers/media/platform/msm/vidc/msm_vidc_internal.h +1 −0 Original line number Diff line number Diff line Loading @@ -362,6 +362,7 @@ struct clock_data { u32 opb_fourcc; u32 work_mode; bool low_latency_mode; bool is_cbr_plus; bool turbo_mode; u32 work_route; u32 dcvs_flags; Loading