1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 4 * Copyright (C) 2017 Linaro Ltd. 5 */ 6 #include <linux/types.h> 7 #include <media/v4l2-ctrls.h> 8 9 #include "core.h" 10 #include "helpers.h" 11 #include "vdec.h" 12 13 static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) 14 { 15 struct venus_inst *inst = ctrl_to_inst(ctrl); 16 struct vdec_controls *ctr = &inst->controls.dec; 17 18 switch (ctrl->id) { 19 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: 20 ctr->post_loop_deb_mode = ctrl->val; 21 break; 22 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 23 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 24 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: 25 case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: 26 ctr->profile = ctrl->val; 27 break; 28 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 29 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 30 case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: 31 ctr->level = ctrl->val; 32 break; 33 case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY: 34 ctr->display_delay = ctrl->val; 35 break; 36 case V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE: 37 ctr->display_delay_enable = ctrl->val; 38 break; 39 default: 40 return -EINVAL; 41 } 42 43 return 0; 44 } 45 46 static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 47 { 48 struct venus_inst *inst = ctrl_to_inst(ctrl); 49 struct vdec_controls *ctr = &inst->controls.dec; 50 struct hfi_buffer_requirements bufreq; 51 enum hfi_version ver = inst->core->res->hfi_version; 52 u32 profile, level; 53 int ret; 54 55 switch (ctrl->id) { 56 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 57 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 58 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: 59 case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: 60 ret = venus_helper_get_profile_level(inst, &profile, &level); 61 if (!ret) 62 ctr->profile = profile; 63 ctrl->val = ctr->profile; 64 break; 65 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 66 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 67 case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: 68 ret = venus_helper_get_profile_level(inst, &profile, &level); 69 if (!ret) 70 ctr->level = level; 71 ctrl->val = ctr->level; 72 break; 73 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: 74 ctrl->val = ctr->post_loop_deb_mode; 75 break; 76 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: 77 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 78 if (!ret) 79 ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); 80 break; 81 default: 82 return -EINVAL; 83 } 84 85 return 0; 86 } 87 88 static const struct v4l2_ctrl_ops vdec_ctrl_ops = { 89 .s_ctrl = vdec_op_s_ctrl, 90 .g_volatile_ctrl = vdec_op_g_volatile_ctrl, 91 }; 92 93 int vdec_ctrl_init(struct venus_inst *inst) 94 { 95 struct v4l2_ctrl *ctrl; 96 int ret; 97 98 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 11); 99 if (ret) 100 return ret; 101 102 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 103 V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, 104 V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY, 105 ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) | 106 (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)), 107 V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE); 108 if (ctrl) 109 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 110 111 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 112 V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, 113 V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, 114 0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0); 115 if (ctrl) 116 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 117 118 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 119 V4L2_CID_MPEG_VIDEO_H264_PROFILE, 120 V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, 121 ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | 122 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | 123 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | 124 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | 125 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) | 126 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)), 127 V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); 128 if (ctrl) 129 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 130 131 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 132 V4L2_CID_MPEG_VIDEO_H264_LEVEL, 133 V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 134 0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0); 135 if (ctrl) 136 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 137 138 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 139 V4L2_CID_MPEG_VIDEO_VP8_PROFILE, 140 V4L2_MPEG_VIDEO_VP8_PROFILE_3, 141 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0); 142 if (ctrl) 143 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 144 145 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 146 V4L2_CID_MPEG_VIDEO_VP9_PROFILE, 147 V4L2_MPEG_VIDEO_VP9_PROFILE_3, 148 0, V4L2_MPEG_VIDEO_VP9_PROFILE_0); 149 if (ctrl) 150 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 151 152 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 153 V4L2_CID_MPEG_VIDEO_VP9_LEVEL, 154 V4L2_MPEG_VIDEO_VP9_LEVEL_6_2, 155 0, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0); 156 if (ctrl) 157 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 158 159 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 160 V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 0, 1, 1, 0); 161 162 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 163 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 1); 164 if (ctrl) 165 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 166 167 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 168 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY, 169 0, 16383, 1, 0); 170 171 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 172 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE, 173 0, 1, 1, 0); 174 175 ret = inst->ctrl_handler.error; 176 if (ret) { 177 v4l2_ctrl_handler_free(&inst->ctrl_handler); 178 return ret; 179 } 180 181 return 0; 182 } 183 184 void vdec_ctrl_deinit(struct venus_inst *inst) 185 { 186 v4l2_ctrl_handler_free(&inst->ctrl_handler); 187 } 188