Skip to content

Commit

Permalink
media: venus: hfi_parser: add common capability parser
Browse files Browse the repository at this point in the history
This adds common capability parser for all supported Venus
versions. Having it will help to enumerate better the supported
raw formats and codecs and also the capabilities for every
codec like max/min width/height, framerate, bitrate and so on.

Signed-off-by: Stanimir Varbanov <stanimir.varbanov@linaro.org>
Reviewed-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
  • Loading branch information
Stanimir Varbanov authored and Mauro Carvalho Chehab committed Jul 25, 2018
1 parent aa3a841 commit 1a73374
Show file tree
Hide file tree
Showing 10 changed files with 590 additions and 444 deletions.
3 changes: 2 additions & 1 deletion drivers/media/platform/qcom/venus/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# Makefile for Qualcomm Venus driver

venus-core-objs += core.o helpers.o firmware.o \
hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o
hfi_venus.o hfi_msgs.o hfi_cmds.o hfi.o \
hfi_parser.o

venus-dec-objs += vdec.o vdec_ctrls.o
venus-enc-objs += venc.o venc_ctrls.o
Expand Down
85 changes: 85 additions & 0 deletions drivers/media/platform/qcom/venus/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,83 @@ static void venus_clks_disable(struct venus_core *core)
clk_disable_unprepare(core->clks[i]);
}

static u32 to_v4l2_codec_type(u32 codec)
{
switch (codec) {
case HFI_VIDEO_CODEC_H264:
return V4L2_PIX_FMT_H264;
case HFI_VIDEO_CODEC_H263:
return V4L2_PIX_FMT_H263;
case HFI_VIDEO_CODEC_MPEG1:
return V4L2_PIX_FMT_MPEG1;
case HFI_VIDEO_CODEC_MPEG2:
return V4L2_PIX_FMT_MPEG2;
case HFI_VIDEO_CODEC_MPEG4:
return V4L2_PIX_FMT_MPEG4;
case HFI_VIDEO_CODEC_VC1:
return V4L2_PIX_FMT_VC1_ANNEX_G;
case HFI_VIDEO_CODEC_VP8:
return V4L2_PIX_FMT_VP8;
case HFI_VIDEO_CODEC_VP9:
return V4L2_PIX_FMT_VP9;
case HFI_VIDEO_CODEC_DIVX:
case HFI_VIDEO_CODEC_DIVX_311:
return V4L2_PIX_FMT_XVID;
default:
return 0;
}
}

static int venus_enumerate_codecs(struct venus_core *core, u32 type)
{
const struct hfi_inst_ops dummy_ops = {};
struct venus_inst *inst;
u32 codec, codecs;
unsigned int i;
int ret;

if (core->res->hfi_version != HFI_VERSION_1XX)
return 0;

inst = kzalloc(sizeof(*inst), GFP_KERNEL);
if (!inst)
return -ENOMEM;

mutex_init(&inst->lock);
inst->core = core;
inst->session_type = type;
if (type == VIDC_SESSION_TYPE_DEC)
codecs = core->dec_codecs;
else
codecs = core->enc_codecs;

ret = hfi_session_create(inst, &dummy_ops);
if (ret)
goto err;

for (i = 0; i < MAX_CODEC_NUM; i++) {
codec = (1 << i) & codecs;
if (!codec)
continue;

ret = hfi_session_init(inst, to_v4l2_codec_type(codec));
if (ret)
goto done;

ret = hfi_session_deinit(inst);
if (ret)
goto done;
}

done:
hfi_session_destroy(inst);
err:
mutex_destroy(&inst->lock);
kfree(inst);

return ret;
}

static int venus_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
Expand Down Expand Up @@ -219,6 +296,14 @@ static int venus_probe(struct platform_device *pdev)
if (ret)
goto err_venus_shutdown;

ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_DEC);
if (ret)
goto err_venus_shutdown;

ret = venus_enumerate_codecs(core, VIDC_SESSION_TYPE_ENC);
if (ret)
goto err_venus_shutdown;

ret = v4l2_device_register(dev, &core->v4l2_dev);
if (ret)
goto err_core_deinit;
Expand Down
74 changes: 44 additions & 30 deletions drivers/media/platform/qcom/venus/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,30 @@ struct venus_format {
u32 type;
};

#define MAX_PLANES 4
#define MAX_FMT_ENTRIES 32
#define MAX_CAP_ENTRIES 32
#define MAX_ALLOC_MODE_ENTRIES 16
#define MAX_CODEC_NUM 32

struct raw_formats {
u32 buftype;
u32 fmt;
};

struct venus_caps {
u32 codec;
u32 domain;
bool cap_bufs_mode_dynamic;
unsigned int num_caps;
struct hfi_capability caps[MAX_CAP_ENTRIES];
unsigned int num_pl;
struct hfi_profile_level pl[HFI_MAX_PROFILE_COUNT];
unsigned int num_fmts;
struct raw_formats fmts[MAX_FMT_ENTRIES];
bool valid; /* used only for Venus v1xx */
};

/**
* struct venus_core - holds core parameters valid for all instances
*
Expand Down Expand Up @@ -113,8 +137,8 @@ struct venus_core {
unsigned int error;
bool sys_error;
const struct hfi_core_ops *core_ops;
u32 enc_codecs;
u32 dec_codecs;
unsigned long enc_codecs;
unsigned long dec_codecs;
unsigned int max_sessions_supported;
#define ENC_ROTATION_CAPABILITY 0x1
#define ENC_SCALING_CAPABILITY 0x2
Expand All @@ -124,6 +148,8 @@ struct venus_core {
void *priv;
const struct hfi_ops *ops;
struct delayed_work work;
struct venus_caps caps[MAX_CODEC_NUM];
unsigned int codecs_count;
};

struct vdec_controls {
Expand Down Expand Up @@ -216,6 +242,7 @@ struct venus_buffer {
* @reconfig: a flag raised by decoder when the stream resolution changed
* @reconfig_width: holds the new width
* @reconfig_height: holds the new height
* @hfi_codec: current codec for this instance in HFI space
* @sequence_cap: a sequence counter for capture queue
* @sequence_out: a sequence counter for output queue
* @m2m_dev: a reference to m2m device structure
Expand All @@ -228,22 +255,8 @@ struct venus_buffer {
* @priv: a private for HFI operations callbacks
* @session_type: the type of the session (decoder or encoder)
* @hprop: a union used as a holder by get property
* @cap_width: width capability
* @cap_height: height capability
* @cap_mbs_per_frame: macroblocks per frame capability
* @cap_mbs_per_sec: macroblocks per second capability
* @cap_framerate: framerate capability
* @cap_scale_x: horizontal scaling capability
* @cap_scale_y: vertical scaling capability
* @cap_bitrate: bitrate capability
* @cap_hier_p: hier capability
* @cap_ltr_count: LTR count capability
* @cap_secure_output2_threshold: secure OUTPUT2 threshold capability
* @cap_bufs_mode_static: buffers allocation mode capability
* @cap_bufs_mode_dynamic: buffers allocation mode capability
* @pl_count: count of supported profiles/levels
* @pl: supported profiles/levels
* @bufreq: holds buffer requirements
*/
struct venus_inst {
struct list_head list;
Expand Down Expand Up @@ -280,6 +293,7 @@ struct venus_inst {
bool reconfig;
u32 reconfig_width;
u32 reconfig_height;
u32 hfi_codec;
u32 sequence_cap;
u32 sequence_out;
struct v4l2_m2m_dev *m2m_dev;
Expand All @@ -291,22 +305,8 @@ struct venus_inst {
const struct hfi_inst_ops *ops;
u32 session_type;
union hfi_get_property hprop;
struct hfi_capability cap_width;
struct hfi_capability cap_height;
struct hfi_capability cap_mbs_per_frame;
struct hfi_capability cap_mbs_per_sec;
struct hfi_capability cap_framerate;
struct hfi_capability cap_scale_x;
struct hfi_capability cap_scale_y;
struct hfi_capability cap_bitrate;
struct hfi_capability cap_hier_p;
struct hfi_capability cap_ltr_count;
struct hfi_capability cap_secure_output2_threshold;
bool cap_bufs_mode_static;
bool cap_bufs_mode_dynamic;
unsigned int pl_count;
struct hfi_profile_level pl[HFI_MAX_PROFILE_COUNT];
struct hfi_buffer_requirements bufreq[HFI_BUFFER_TYPE_MAX];
};

#define IS_V1(core) ((core)->res->hfi_version == HFI_VERSION_1XX)
Expand All @@ -326,4 +326,18 @@ static inline void *to_hfi_priv(struct venus_core *core)
return core->priv;
}

static inline struct venus_caps *
venus_caps_by_codec(struct venus_core *core, u32 codec, u32 domain)
{
unsigned int c;

for (c = 0; c < core->codecs_count; c++) {
if (core->caps[c].codec == codec &&
core->caps[c].domain == domain)
return &core->caps[c];
}

return NULL;
}

#endif
5 changes: 2 additions & 3 deletions drivers/media/platform/qcom/venus/hfi.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,12 @@ int hfi_session_init(struct venus_inst *inst, u32 pixfmt)
{
struct venus_core *core = inst->core;
const struct hfi_ops *ops = core->ops;
u32 codec;
int ret;

codec = to_codec_type(pixfmt);
inst->hfi_codec = to_codec_type(pixfmt);
reinit_completion(&inst->done);

ret = ops->session_init(inst, inst->session_type, codec);
ret = ops->session_init(inst, inst->session_type, inst->hfi_codec);
if (ret)
return ret;

Expand Down
28 changes: 14 additions & 14 deletions drivers/media/platform/qcom/venus/hfi_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -858,10 +858,23 @@ struct hfi_uncompressed_format_select {
u32 format;
};

struct hfi_uncompressed_plane_constraints {
u32 stride_multiples;
u32 max_stride;
u32 min_plane_buffer_height_multiple;
u32 buffer_alignment;
};

struct hfi_uncompressed_plane_info {
u32 format;
u32 num_planes;
struct hfi_uncompressed_plane_constraints plane_constraints[1];
};

struct hfi_uncompressed_format_supported {
u32 buffer_type;
u32 format_entries;
u32 format_info[1];
struct hfi_uncompressed_plane_info plane_info[1];
};

struct hfi_uncompressed_plane_actual {
Expand All @@ -875,19 +888,6 @@ struct hfi_uncompressed_plane_actual_info {
struct hfi_uncompressed_plane_actual plane_format[1];
};

struct hfi_uncompressed_plane_constraints {
u32 stride_multiples;
u32 max_stride;
u32 min_plane_buffer_height_multiple;
u32 buffer_alignment;
};

struct hfi_uncompressed_plane_info {
u32 format;
u32 num_planes;
struct hfi_uncompressed_plane_constraints plane_format[1];
};

struct hfi_uncompressed_plane_actual_constraints_info {
u32 buffer_type;
u32 num_planes;
Expand Down
Loading

0 comments on commit 1a73374

Please sign in to comment.