Commit e1cb72de authored by Stanimir Varbanov's avatar Stanimir Varbanov Committed by Mauro Carvalho Chehab

media: venus: helpers: move frame size calculations on common place

This move the calculations of raw and compressed buffer sizes
on common helper and make it identical for encoder and decoder.
Signed-off-by: default avatarStanimir Varbanov <stanimir.varbanov@linaro.org>
Reviewed-by: default avatarTomasz Figa <tfiga@chromium.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Tested-by: default avatarAlexandre Courbot <acourbot@chromium.org>
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent ea8ce235
...@@ -457,6 +457,104 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, ...@@ -457,6 +457,104 @@ int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
} }
EXPORT_SYMBOL_GPL(venus_helper_get_bufreq); EXPORT_SYMBOL_GPL(venus_helper_get_bufreq);
static u32 get_framesize_raw_nv12(u32 width, u32 height)
{
u32 y_stride, uv_stride, y_plane;
u32 y_sclines, uv_sclines, uv_plane;
u32 size;
y_stride = ALIGN(width, 128);
uv_stride = ALIGN(width, 128);
y_sclines = ALIGN(height, 32);
uv_sclines = ALIGN(((height + 1) >> 1), 16);
y_plane = y_stride * y_sclines;
uv_plane = uv_stride * uv_sclines + SZ_4K;
size = y_plane + uv_plane + SZ_8K;
return ALIGN(size, SZ_4K);
}
static u32 get_framesize_raw_nv12_ubwc(u32 width, u32 height)
{
u32 y_meta_stride, y_meta_plane;
u32 y_stride, y_plane;
u32 uv_meta_stride, uv_meta_plane;
u32 uv_stride, uv_plane;
u32 extradata = SZ_16K;
y_meta_stride = ALIGN(DIV_ROUND_UP(width, 32), 64);
y_meta_plane = y_meta_stride * ALIGN(DIV_ROUND_UP(height, 8), 16);
y_meta_plane = ALIGN(y_meta_plane, SZ_4K);
y_stride = ALIGN(width, 128);
y_plane = ALIGN(y_stride * ALIGN(height, 32), SZ_4K);
uv_meta_stride = ALIGN(DIV_ROUND_UP(width / 2, 16), 64);
uv_meta_plane = uv_meta_stride * ALIGN(DIV_ROUND_UP(height / 2, 8), 16);
uv_meta_plane = ALIGN(uv_meta_plane, SZ_4K);
uv_stride = ALIGN(width, 128);
uv_plane = ALIGN(uv_stride * ALIGN(height / 2, 32), SZ_4K);
return ALIGN(y_meta_plane + y_plane + uv_meta_plane + uv_plane +
max(extradata, y_stride * 48), SZ_4K);
}
u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height)
{
switch (hfi_fmt) {
case HFI_COLOR_FORMAT_NV12:
case HFI_COLOR_FORMAT_NV21:
return get_framesize_raw_nv12(width, height);
case HFI_COLOR_FORMAT_NV12_UBWC:
return get_framesize_raw_nv12_ubwc(width, height);
default:
return 0;
}
}
EXPORT_SYMBOL_GPL(venus_helper_get_framesz_raw);
u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height)
{
u32 hfi_fmt, sz;
bool compressed;
switch (v4l2_fmt) {
case V4L2_PIX_FMT_MPEG:
case V4L2_PIX_FMT_H264:
case V4L2_PIX_FMT_H264_NO_SC:
case V4L2_PIX_FMT_H264_MVC:
case V4L2_PIX_FMT_H263:
case V4L2_PIX_FMT_MPEG1:
case V4L2_PIX_FMT_MPEG2:
case V4L2_PIX_FMT_MPEG4:
case V4L2_PIX_FMT_XVID:
case V4L2_PIX_FMT_VC1_ANNEX_G:
case V4L2_PIX_FMT_VC1_ANNEX_L:
case V4L2_PIX_FMT_VP8:
case V4L2_PIX_FMT_VP9:
case V4L2_PIX_FMT_HEVC:
compressed = true;
break;
default:
compressed = false;
break;
}
if (compressed) {
sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2;
return ALIGN(sz, SZ_4K);
}
hfi_fmt = to_hfi_raw_fmt(v4l2_fmt);
if (!hfi_fmt)
return 0;
return venus_helper_get_framesz_raw(hfi_fmt, width, height);
}
EXPORT_SYMBOL_GPL(venus_helper_get_framesz);
int venus_helper_set_input_resolution(struct venus_inst *inst, int venus_helper_set_input_resolution(struct venus_inst *inst,
unsigned int width, unsigned int height) unsigned int width, unsigned int height)
{ {
......
...@@ -33,6 +33,8 @@ void venus_helper_m2m_device_run(void *priv); ...@@ -33,6 +33,8 @@ void venus_helper_m2m_device_run(void *priv);
void venus_helper_m2m_job_abort(void *priv); void venus_helper_m2m_job_abort(void *priv);
int venus_helper_get_bufreq(struct venus_inst *inst, u32 type, int venus_helper_get_bufreq(struct venus_inst *inst, u32 type,
struct hfi_buffer_requirements *req); struct hfi_buffer_requirements *req);
u32 venus_helper_get_framesz_raw(u32 hfi_fmt, u32 width, u32 height);
u32 venus_helper_get_framesz(u32 v4l2_fmt, u32 width, u32 height);
int venus_helper_set_input_resolution(struct venus_inst *inst, int venus_helper_set_input_resolution(struct venus_inst *inst,
unsigned int width, unsigned int height); unsigned int width, unsigned int height);
int venus_helper_set_output_resolution(struct venus_inst *inst, int venus_helper_set_output_resolution(struct venus_inst *inst,
......
...@@ -29,29 +29,6 @@ ...@@ -29,29 +29,6 @@
#include "helpers.h" #include "helpers.h"
#include "vdec.h" #include "vdec.h"
static u32 get_framesize_uncompressed(unsigned int plane, u32 width, u32 height)
{
u32 y_stride, uv_stride, y_plane;
u32 y_sclines, uv_sclines, uv_plane;
u32 size;
y_stride = ALIGN(width, 128);
uv_stride = ALIGN(width, 128);
y_sclines = ALIGN(height, 32);
uv_sclines = ALIGN(((height + 1) >> 1), 16);
y_plane = y_stride * y_sclines;
uv_plane = uv_stride * uv_sclines + SZ_4K;
size = y_plane + uv_plane + SZ_8K;
return ALIGN(size, SZ_4K);
}
static u32 get_framesize_compressed(unsigned int width, unsigned int height)
{
return ((width * height * 3 / 2) / 2) + 128;
}
/* /*
* Three resons to keep MPLANE formats (despite that the number of planes * Three resons to keep MPLANE formats (despite that the number of planes
* currently is one): * currently is one):
...@@ -160,7 +137,6 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) ...@@ -160,7 +137,6 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
const struct venus_format *fmt; const struct venus_format *fmt;
unsigned int p;
memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
...@@ -189,18 +165,14 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) ...@@ -189,18 +165,14 @@ vdec_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
pixmp->num_planes = fmt->num_planes; pixmp->num_planes = fmt->num_planes;
pixmp->flags = 0; pixmp->flags = 0;
if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,
for (p = 0; p < pixmp->num_planes; p++) { pixmp->width,
pfmt[p].sizeimage = pixmp->height);
get_framesize_uncompressed(p, pixmp->width,
pixmp->height); if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
pfmt[p].bytesperline = ALIGN(pixmp->width, 128); pfmt[0].bytesperline = ALIGN(pixmp->width, 128);
} else
} else {
pfmt[0].sizeimage = get_framesize_compressed(pixmp->width,
pixmp->height);
pfmt[0].bytesperline = 0; pfmt[0].bytesperline = 0;
}
return fmt; return fmt;
} }
...@@ -645,7 +617,7 @@ static int vdec_queue_setup(struct vb2_queue *q, ...@@ -645,7 +617,7 @@ static int vdec_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_devs[]) unsigned int sizes[], struct device *alloc_devs[])
{ {
struct venus_inst *inst = vb2_get_drv_priv(q); struct venus_inst *inst = vb2_get_drv_priv(q);
unsigned int p, in_num, out_num; unsigned int in_num, out_num;
int ret = 0; int ret = 0;
if (*num_planes) { if (*num_planes) {
...@@ -675,7 +647,8 @@ static int vdec_queue_setup(struct vb2_queue *q, ...@@ -675,7 +647,8 @@ static int vdec_queue_setup(struct vb2_queue *q,
switch (q->type) { switch (q->type) {
case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
*num_planes = inst->fmt_out->num_planes; *num_planes = inst->fmt_out->num_planes;
sizes[0] = get_framesize_compressed(inst->out_width, sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt,
inst->out_width,
inst->out_height); inst->out_height);
inst->input_buf_size = sizes[0]; inst->input_buf_size = sizes[0];
*num_buffers = max(*num_buffers, in_num); *num_buffers = max(*num_buffers, in_num);
...@@ -684,10 +657,9 @@ static int vdec_queue_setup(struct vb2_queue *q, ...@@ -684,10 +657,9 @@ static int vdec_queue_setup(struct vb2_queue *q,
break; break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
*num_planes = inst->fmt_cap->num_planes; *num_planes = inst->fmt_cap->num_planes;
sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt,
for (p = 0; p < *num_planes; p++) inst->width,
sizes[p] = get_framesize_uncompressed(p, inst->width, inst->height);
inst->height);
inst->output_buf_size = sizes[0]; inst->output_buf_size = sizes[0];
*num_buffers = max(*num_buffers, out_num); *num_buffers = max(*num_buffers, out_num);
inst->num_output_bufs = *num_buffers; inst->num_output_bufs = *num_buffers;
......
...@@ -31,32 +31,6 @@ ...@@ -31,32 +31,6 @@
#define NUM_B_FRAMES_MAX 4 #define NUM_B_FRAMES_MAX 4
static u32 get_framesize_uncompressed(unsigned int plane, u32 width, u32 height)
{
u32 y_stride, uv_stride, y_plane;
u32 y_sclines, uv_sclines, uv_plane;
u32 size;
y_stride = ALIGN(width, 128);
uv_stride = ALIGN(width, 128);
y_sclines = ALIGN(height, 32);
uv_sclines = ALIGN(((height + 1) >> 1), 16);
y_plane = y_stride * y_sclines;
uv_plane = uv_stride * uv_sclines + SZ_4K;
size = y_plane + uv_plane + SZ_8K;
size = ALIGN(size, SZ_4K);
return size;
}
static u32 get_framesize_compressed(u32 width, u32 height)
{
u32 sz = ALIGN(height, 32) * ALIGN(width, 32) * 3 / 2 / 2;
return ALIGN(sz, SZ_4K);
}
/* /*
* Three resons to keep MPLANE formats (despite that the number of planes * Three resons to keep MPLANE formats (despite that the number of planes
* currently is one): * currently is one):
...@@ -284,7 +258,6 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) ...@@ -284,7 +258,6 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp; struct v4l2_pix_format_mplane *pixmp = &f->fmt.pix_mp;
struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt; struct v4l2_plane_pix_format *pfmt = pixmp->plane_fmt;
const struct venus_format *fmt; const struct venus_format *fmt;
unsigned int p;
memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved)); memset(pfmt[0].reserved, 0, sizeof(pfmt[0].reserved));
memset(pixmp->reserved, 0, sizeof(pixmp->reserved)); memset(pixmp->reserved, 0, sizeof(pixmp->reserved));
...@@ -316,19 +289,14 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f) ...@@ -316,19 +289,14 @@ venc_try_fmt_common(struct venus_inst *inst, struct v4l2_format *f)
pixmp->num_planes = fmt->num_planes; pixmp->num_planes = fmt->num_planes;
pixmp->flags = 0; pixmp->flags = 0;
if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { pfmt[0].sizeimage = venus_helper_get_framesz(pixmp->pixelformat,
for (p = 0; p < pixmp->num_planes; p++) { pixmp->width,
pfmt[p].sizeimage = pixmp->height);
get_framesize_uncompressed(p, pixmp->width,
pixmp->height);
pfmt[p].bytesperline = ALIGN(pixmp->width, 128); if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
} pfmt[0].bytesperline = ALIGN(pixmp->width, 128);
} else { else
pfmt[0].sizeimage = get_framesize_compressed(pixmp->width,
pixmp->height);
pfmt[0].bytesperline = 0; pfmt[0].bytesperline = 0;
}
return fmt; return fmt;
} }
...@@ -843,7 +811,7 @@ static int venc_queue_setup(struct vb2_queue *q, ...@@ -843,7 +811,7 @@ static int venc_queue_setup(struct vb2_queue *q,
unsigned int sizes[], struct device *alloc_devs[]) unsigned int sizes[], struct device *alloc_devs[])
{ {
struct venus_inst *inst = vb2_get_drv_priv(q); struct venus_inst *inst = vb2_get_drv_priv(q);
unsigned int p, num, min = 4; unsigned int num, min = 4;
int ret = 0; int ret = 0;
if (*num_planes) { if (*num_planes) {
...@@ -878,16 +846,18 @@ static int venc_queue_setup(struct vb2_queue *q, ...@@ -878,16 +846,18 @@ static int venc_queue_setup(struct vb2_queue *q,
*num_buffers = max(*num_buffers, num); *num_buffers = max(*num_buffers, num);
inst->num_input_bufs = *num_buffers; inst->num_input_bufs = *num_buffers;
for (p = 0; p < *num_planes; ++p) sizes[0] = venus_helper_get_framesz(inst->fmt_out->pixfmt,
sizes[p] = get_framesize_uncompressed(p, inst->width, inst->width,
inst->height); inst->height);
inst->input_buf_size = sizes[0]; inst->input_buf_size = sizes[0];
break; break;
case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
*num_planes = inst->fmt_cap->num_planes; *num_planes = inst->fmt_cap->num_planes;
*num_buffers = max(*num_buffers, min); *num_buffers = max(*num_buffers, min);
inst->num_output_bufs = *num_buffers; inst->num_output_bufs = *num_buffers;
sizes[0] = get_framesize_compressed(inst->width, inst->height); sizes[0] = venus_helper_get_framesz(inst->fmt_cap->pixfmt,
inst->width,
inst->height);
inst->output_buf_size = sizes[0]; inst->output_buf_size = sizes[0];
break; break;
default: default:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment