Add a menu control V4L2_CID_MPEG_VIDEO_VP8_PROFILE for VP8 profile and make V4L2_CID_MPEG_VIDEO_VPX_PROFILE an alias of it. This new control is used to select the desired profile for VP8 encoder and query for supported profiles by VP8 encoder/decoder. Though we have originally a control V4L2_CID_MPEG_VIDEO_VPX_PROFILE and its name contains 'VPX', it works only for VP8 because supported profiles usually differ between VP8 and VP9. In addition, this control cannot be used for querying since it is not a menu control but an integer control, which cannot return an arbitrary set of supported profiles. The new control V4L2_CID_MPEG_VIDEO_VP8_PROFILE is a menu control as with controls for other codec profiles. (e.g. H264) In addition, this patch also fixes the use of V4L2_CID_MPEG_VIDEO_VPX_PROFILE in drivers of Qualcomm's venus and Samsung's s5p-mfc. Signed-off-by: Keiichi Watanabe <keiichiw@chromium.org> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
161 lines
4.6 KiB
C
161 lines
4.6 KiB
C
/*
|
|
* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
|
* Copyright (C) 2017 Linaro Ltd.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
*/
|
|
#include <linux/types.h>
|
|
#include <media/v4l2-ctrls.h>
|
|
|
|
#include "core.h"
|
|
#include "vdec.h"
|
|
|
|
static int vdec_op_s_ctrl(struct v4l2_ctrl *ctrl)
|
|
{
|
|
struct venus_inst *inst = ctrl_to_inst(ctrl);
|
|
struct vdec_controls *ctr = &inst->controls.dec;
|
|
|
|
switch (ctrl->id) {
|
|
case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
|
|
ctr->post_loop_deb_mode = ctrl->val;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
|
|
case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
|
|
ctr->profile = ctrl->val;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
|
|
ctr->level = ctrl->val;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int vdec_op_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
|
|
{
|
|
struct venus_inst *inst = ctrl_to_inst(ctrl);
|
|
struct vdec_controls *ctr = &inst->controls.dec;
|
|
union hfi_get_property hprop;
|
|
u32 ptype = HFI_PROPERTY_PARAM_PROFILE_LEVEL_CURRENT;
|
|
int ret;
|
|
|
|
switch (ctrl->id) {
|
|
case V4L2_CID_MPEG_VIDEO_H264_PROFILE:
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE:
|
|
case V4L2_CID_MPEG_VIDEO_VP8_PROFILE:
|
|
ret = hfi_session_get_property(inst, ptype, &hprop);
|
|
if (!ret)
|
|
ctr->profile = hprop.profile_level.profile;
|
|
ctrl->val = ctr->profile;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_H264_LEVEL:
|
|
case V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL:
|
|
ret = hfi_session_get_property(inst, ptype, &hprop);
|
|
if (!ret)
|
|
ctr->level = hprop.profile_level.level;
|
|
ctrl->val = ctr->level;
|
|
break;
|
|
case V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER:
|
|
ctrl->val = ctr->post_loop_deb_mode;
|
|
break;
|
|
case V4L2_CID_MIN_BUFFERS_FOR_CAPTURE:
|
|
ctrl->val = inst->num_output_bufs;
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
};
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const struct v4l2_ctrl_ops vdec_ctrl_ops = {
|
|
.s_ctrl = vdec_op_s_ctrl,
|
|
.g_volatile_ctrl = vdec_op_g_volatile_ctrl,
|
|
};
|
|
|
|
int vdec_ctrl_init(struct venus_inst *inst)
|
|
{
|
|
struct v4l2_ctrl *ctrl;
|
|
int ret;
|
|
|
|
ret = v4l2_ctrl_handler_init(&inst->ctrl_handler, 7);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
|
|
V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE,
|
|
V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY,
|
|
~((1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE) |
|
|
(1 << V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE)),
|
|
V4L2_MPEG_VIDEO_MPEG4_PROFILE_SIMPLE);
|
|
if (ctrl)
|
|
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
|
|
|
ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
|
|
V4L2_CID_MPEG_VIDEO_MPEG4_LEVEL,
|
|
V4L2_MPEG_VIDEO_MPEG4_LEVEL_5,
|
|
0, V4L2_MPEG_VIDEO_MPEG4_LEVEL_0);
|
|
if (ctrl)
|
|
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
|
|
|
ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
|
|
V4L2_CID_MPEG_VIDEO_H264_PROFILE,
|
|
V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH,
|
|
~((1 << V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE) |
|
|
(1 << V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE) |
|
|
(1 << V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) |
|
|
(1 << V4L2_MPEG_VIDEO_H264_PROFILE_HIGH) |
|
|
(1 << V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH) |
|
|
(1 << V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH)),
|
|
V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE);
|
|
if (ctrl)
|
|
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
|
|
|
ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
|
|
V4L2_CID_MPEG_VIDEO_H264_LEVEL,
|
|
V4L2_MPEG_VIDEO_H264_LEVEL_5_1,
|
|
0, V4L2_MPEG_VIDEO_H264_LEVEL_1_0);
|
|
if (ctrl)
|
|
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
|
|
|
ctrl = v4l2_ctrl_new_std_menu(&inst->ctrl_handler, &vdec_ctrl_ops,
|
|
V4L2_CID_MPEG_VIDEO_VP8_PROFILE,
|
|
V4L2_MPEG_VIDEO_VP8_PROFILE_3,
|
|
0, V4L2_MPEG_VIDEO_VP8_PROFILE_0);
|
|
if (ctrl)
|
|
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
|
|
|
v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
|
|
V4L2_CID_MPEG_VIDEO_DECODER_MPEG4_DEBLOCK_FILTER, 0, 1, 1, 0);
|
|
|
|
ctrl = v4l2_ctrl_new_std(&inst->ctrl_handler, &vdec_ctrl_ops,
|
|
V4L2_CID_MIN_BUFFERS_FOR_CAPTURE, 1, 32, 1, 1);
|
|
if (ctrl)
|
|
ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
|
|
|
|
ret = inst->ctrl_handler.error;
|
|
if (ret) {
|
|
v4l2_ctrl_handler_free(&inst->ctrl_handler);
|
|
return ret;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void vdec_ctrl_deinit(struct venus_inst *inst)
|
|
{
|
|
v4l2_ctrl_handler_free(&inst->ctrl_handler);
|
|
}
|