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