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 case V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR: 40 ctr->conceal_color = *ctrl->p_new.p_s64; 41 break; 42 default: 43 return -EINVAL; 44 } 45 46 return 0; 47 } 48 49 static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 50 { 51 struct venus_inst *inst = ctrl_to_inst(ctrl); 52 struct vdec_controls *ctr = &inst->controls.dec; 53 struct hfi_buffer_requirements bufreq; 54 enum hfi_version ver = inst->core->res->hfi_version; 55 u32 profile, level; 56 int ret; 57 58 switch (ctrl->id) { 59 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 60 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 61 case V4L2_CID_MPEG_VIDEO_VP8_PROFILE: 62 case V4L2_CID_MPEG_VIDEO_VP9_PROFILE: 63 ret = venus_helper_get_profile_level(inst, &profile, &level); 64 if (!ret) 65 ctr->profile = profile; 66 ctrl->val = ctr->profile; 67 break; 68 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 69 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 70 case V4L2_CID_MPEG_VIDEO_VP9_LEVEL: 71 ret = venus_helper_get_profile_level(inst, &profile, &level); 72 if (!ret) 73 ctr->level = level; 74 ctrl->val = ctr->level; 75 break; 76 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: 77 ctrl->val = ctr->post_loop_deb_mode; 78 break; 79 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: 80 ret = venus_helper_get_bufreq(inst, HFI_BUFFER_OUTPUT, &bufreq); 81 if (!ret) 82 ctrl->val = HFI_BUFREQ_COUNT_MIN(&bufreq, ver); 83 break; 84 default: 85 return -EINVAL; 86 } 87 88 return 0; 89 } 90 91 static const struct v4l2_ctrl_ops vdec_ctrl_ops = { 92 .s_ctrl = vdec_op_s_ctrl, 93 .g_volatile_ctrl = vdec_op_g_volatile_ctrl, 94 }; 95 96 int vdec_ctrl_init(struct venus_inst *inst) 97 { 98 struct v4l2_ctrl *ctrl; 99 int ret; 100 101 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 12); 102 if (ret) 103 return ret; 104 105 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 106 V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, 107 V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY, 108 ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) | 109 (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)), 110 V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE); 111 if (ctrl) 112 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 113 114 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 115 V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, 116 V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, 117 0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0); 118 if (ctrl) 119 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 120 121 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 122 V4L2_CID_MPEG_VIDEO_H264_PROFILE, 123 V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, 124 ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | 125 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | 126 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | 127 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | 128 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) | 129 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)), 130 V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); 131 if (ctrl) 132 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 133 134 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 135 V4L2_CID_MPEG_VIDEO_H264_LEVEL, 136 V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 137 0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0); 138 if (ctrl) 139 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 140 141 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 142 V4L2_CID_MPEG_VIDEO_VP8_PROFILE, 143 V4L2_MPEG_VIDEO_VP8_PROFILE_3, 144 0, V4L2_MPEG_VIDEO_VP8_PROFILE_0); 145 if (ctrl) 146 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 147 148 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 149 V4L2_CID_MPEG_VIDEO_VP9_PROFILE, 150 V4L2_MPEG_VIDEO_VP9_PROFILE_3, 151 0, V4L2_MPEG_VIDEO_VP9_PROFILE_0); 152 if (ctrl) 153 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 154 155 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 156 V4L2_CID_MPEG_VIDEO_VP9_LEVEL, 157 V4L2_MPEG_VIDEO_VP9_LEVEL_6_2, 158 0, V4L2_MPEG_VIDEO_VP9_LEVEL_1_0); 159 if (ctrl) 160 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 161 162 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 163 V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 0, 1, 1, 0); 164 165 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 166 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 1); 167 if (ctrl) 168 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 169 170 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 171 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY, 172 0, 16383, 1, 0); 173 174 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 175 V4L2_CID_MPEG_VIDEO_DEC_DISPLAY_DELAY_ENABLE, 176 0, 1, 1, 0); 177 178 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 179 V4L2_CID_MPEG_VIDEO_DEC_CONCEAL_COLOR, 0, 180 0xffffffffffffLL, 1, 0x8000800010LL); 181 182 ret = inst->ctrl_handler.error; 183 if (ret) { 184 v4l2_ctrl_handler_free(&inst->ctrl_handler); 185 return ret; 186 } 187 188 return 0; 189 } 190 191 void vdec_ctrl_deinit(struct venus_inst *inst) 192 { 193 v4l2_ctrl_handler_free(&inst->ctrl_handler); 194 } 195