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