1 /* 2 * Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 3 * Copyright (C) 2017 Linaro Ltd. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 and 7 * only version 2 as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 */ 15 #include <linux/types.h> 16 #include <media/v4l2-ctrls.h> 17 18 #include "core.h" 19 #include "vdec.h" 20 21 static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl) 22 { 23 struct venus_inst *inst = ctrl_to_inst(ctrl); 24 struct vdec_controls *ctr = &inst->controls.dec; 25 26 switch (ctrl->id) { 27 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: 28 ctr->post_loop_deb_mode = ctrl->val; 29 break; 30 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 31 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 32 case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: 33 ctr->profile = ctrl->val; 34 break; 35 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 36 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 37 ctr->level = 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 union hfi_get_property hprop; 51 u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT; 52 int ret; 53 54 switch (ctrl->id) { 55 case V4L2_CID_MPEG_VIDEO_H264_PROFILE: 56 case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE: 57 case V4L2_CID_MPEG_VIDEO_VPX_PROFILE: 58 ret = hfi_session_get_property(inst, ptype, &hprop); 59 if (!ret) 60 ctr->profile = hprop.profile_level.profile; 61 ctrl->val = ctr->profile; 62 break; 63 case V4L2_CID_MPEG_VIDEO_H264_LEVEL: 64 case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL: 65 ret = hfi_session_get_property(inst, ptype, &hprop); 66 if (!ret) 67 ctr->level = hprop.profile_level.level; 68 ctrl->val = ctr->level; 69 break; 70 case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER: 71 ctrl->val = ctr->post_loop_deb_mode; 72 break; 73 case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE: 74 ctrl->val = inst->num_output_bufs; 75 break; 76 default: 77 return -EINVAL; 78 }; 79 80 return 0; 81 } 82 83 static const struct v4l2_ctrl_ops vdec_ctrl_ops = { 84 .s_ctrl = vdec_op_s_ctrl, 85 .g_volatile_ctrl = vdec_op_g_volatile_ctrl, 86 }; 87 88 int vdec_ctrl_init(struct venus_inst *inst) 89 { 90 struct v4l2_ctrl *ctrl; 91 int ret; 92 93 ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 7); 94 if (ret) 95 return ret; 96 97 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 98 V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE, 99 V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY, 100 ~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) | 101 (1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)), 102 V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE); 103 if (ctrl) 104 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 105 106 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 107 V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL, 108 V4L2_MPEG_VIDEO_MPEG4_LEVEL_5, 109 0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0); 110 if (ctrl) 111 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 112 113 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 114 V4L2_CID_MPEG_VIDEO_H264_PROFILE, 115 V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH, 116 ~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) | 117 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) | 118 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) | 119 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) | 120 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) | 121 (1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)), 122 V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE); 123 if (ctrl) 124 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 125 126 ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops, 127 V4L2_CID_MPEG_VIDEO_H264_LEVEL, 128 V4L2_MPEG_VIDEO_H264_LEVEL_5_1, 129 0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0); 130 if (ctrl) 131 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 132 133 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 134 V4L2_CID_MPEG_VIDEO_VPX_PROFILE, 0, 3, 1, 0); 135 if (ctrl) 136 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 137 138 v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 139 V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 0, 1, 1, 0); 140 141 ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops, 142 V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 1); 143 if (ctrl) 144 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE; 145 146 ret = inst->ctrl_handler.error; 147 if (ret) { 148 v4l2_ctrl_handler_free(&inst->ctrl_handler); 149 return ret; 150 } 151 152 return 0; 153 } 154 155 void vdec_ctrl_deinit(struct venus_inst *inst) 156 { 157 v4l2_ctrl_handler_free(&inst->ctrl_handler); 158 } 159