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