media: vicodec: Separate fwht header from the frame data

Keep the fwht header in separated field from the data.
Refactor job_ready to use a new function 'get_next_header'

Signed-off-by: Dafna Hirschfeld <dafna3@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
Dafna Hirschfeld 2019-01-21 09:46:17 -02:00 committed by Mauro Carvalho Chehab
parent 5fbd0729cf
commit ddc1b08527
3 changed files with 77 additions and 58 deletions

View File

@ -235,7 +235,6 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
{
unsigned int i, j, k;
u32 flags;
struct fwht_cframe_hdr *p_hdr;
struct fwht_cframe cf;
u8 *p, *ref_p;
unsigned int components_num = 3;
@ -247,25 +246,24 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
return -EINVAL;
info = state->info;
p_hdr = (struct fwht_cframe_hdr *)p_in;
version = ntohl(p_hdr->version);
version = ntohl(state->header.version);
if (!version || version > FWHT_VERSION) {
pr_err("version %d is not supported, current version is %d\n",
version, FWHT_VERSION);
return -EINVAL;
}
if (p_hdr->magic1 != FWHT_MAGIC1 ||
p_hdr->magic2 != FWHT_MAGIC2)
if (state->header.magic1 != FWHT_MAGIC1 ||
state->header.magic2 != FWHT_MAGIC2)
return -EINVAL;
/* TODO: support resolution changes */
if (ntohl(p_hdr->width) != state->visible_width ||
ntohl(p_hdr->height) != state->visible_height)
if (ntohl(state->header.width) != state->visible_width ||
ntohl(state->header.height) != state->visible_height)
return -EINVAL;
flags = ntohl(p_hdr->flags);
flags = ntohl(state->header.flags);
if (version == FWHT_VERSION) {
if ((flags & FWHT_FL_PIXENC_MSK) != info->pixenc)
@ -277,11 +275,11 @@ int v4l2_fwht_decode(struct v4l2_fwht_state *state, u8 *p_in, u8 *p_out)
if (components_num != info->components_num)
return -EINVAL;
state->colorspace = ntohl(p_hdr->colorspace);
state->xfer_func = ntohl(p_hdr->xfer_func);
state->ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
state->quantization = ntohl(p_hdr->quantization);
cf.rlc_data = (__be16 *)(p_in + sizeof(*p_hdr));
state->colorspace = ntohl(state->header.colorspace);
state->xfer_func = ntohl(state->header.xfer_func);
state->ycbcr_enc = ntohl(state->header.ycbcr_enc);
state->quantization = ntohl(state->header.quantization);
cf.rlc_data = (__be16 *)p_in;
hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;

View File

@ -41,6 +41,7 @@ struct v4l2_fwht_state {
enum v4l2_quantization quantization;
struct fwht_raw_frame ref_frame;
struct fwht_cframe_hdr header;
u8 *compressed_frame;
};

View File

@ -124,6 +124,7 @@ struct vicodec_ctx {
u32 cur_buf_offset;
u32 comp_max_size;
u32 comp_size;
u32 header_size;
u32 comp_magic_cnt;
u32 comp_frame_size;
bool comp_has_frame;
@ -201,6 +202,62 @@ static int device_process(struct vicodec_ctx *ctx,
/*
* mem2mem callbacks
*/
enum vb2_buffer_state get_next_header(struct vicodec_ctx *ctx, u8 **pp, u32 sz)
{
static const u8 magic[] = {
0x4f, 0x4f, 0x4f, 0x4f, 0xff, 0xff, 0xff, 0xff
};
u8 *p = *pp;
u32 state;
u8 *header = (u8 *)&ctx->state.header;
state = VB2_BUF_STATE_DONE;
if (!ctx->header_size) {
state = VB2_BUF_STATE_ERROR;
for (; p < *pp + sz; p++) {
u32 copy;
p = memchr(p, magic[ctx->comp_magic_cnt],
*pp + sz - p);
if (!p) {
ctx->comp_magic_cnt = 0;
p = *pp + sz;
break;
}
copy = sizeof(magic) - ctx->comp_magic_cnt;
if (*pp + sz - p < copy)
copy = *pp + sz - p;
memcpy(header + ctx->comp_magic_cnt, p, copy);
ctx->comp_magic_cnt += copy;
if (!memcmp(header, magic, ctx->comp_magic_cnt)) {
p += copy;
state = VB2_BUF_STATE_DONE;
break;
}
ctx->comp_magic_cnt = 0;
}
if (ctx->comp_magic_cnt < sizeof(magic)) {
*pp = p;
return state;
}
ctx->header_size = sizeof(magic);
}
if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->header_size;
if (*pp + sz - p < copy)
copy = *pp + sz - p;
memcpy(header + ctx->header_size, p, copy);
p += copy;
ctx->header_size += copy;
}
*pp = p;
return state;
}
/* device_run() - prepares and starts the device */
static void device_run(void *priv)
@ -241,6 +298,7 @@ static void device_run(void *priv)
}
v4l2_m2m_buf_done(dst_buf, state);
ctx->comp_size = 0;
ctx->header_size = 0;
ctx->comp_magic_cnt = 0;
ctx->comp_has_frame = false;
spin_unlock(ctx->lock);
@ -291,54 +349,15 @@ restart:
state = VB2_BUF_STATE_DONE;
if (!ctx->comp_size) {
state = VB2_BUF_STATE_ERROR;
for (; p < p_src + sz; p++) {
u32 copy;
p = memchr(p, magic[ctx->comp_magic_cnt],
p_src + sz - p);
if (!p) {
ctx->comp_magic_cnt = 0;
break;
}
copy = sizeof(magic) - ctx->comp_magic_cnt;
if (p_src + sz - p < copy)
copy = p_src + sz - p;
memcpy(ctx->state.compressed_frame + ctx->comp_magic_cnt,
p, copy);
ctx->comp_magic_cnt += copy;
if (!memcmp(ctx->state.compressed_frame, magic,
ctx->comp_magic_cnt)) {
p += copy;
state = VB2_BUF_STATE_DONE;
break;
}
ctx->comp_magic_cnt = 0;
}
if (ctx->comp_magic_cnt < sizeof(magic)) {
if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
state = get_next_header(ctx, &p, p_src + sz - p);
if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
job_remove_src_buf(ctx, state);
goto restart;
}
ctx->comp_size = sizeof(magic);
}
if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) {
struct fwht_cframe_hdr *p_hdr =
(struct fwht_cframe_hdr *)ctx->state.compressed_frame;
u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->comp_size;
if (copy > p_src + sz - p)
copy = p_src + sz - p;
memcpy(ctx->state.compressed_frame + ctx->comp_size,
p, copy);
p += copy;
ctx->comp_size += copy;
if (ctx->comp_size < sizeof(struct fwht_cframe_hdr)) {
job_remove_src_buf(ctx, state);
goto restart;
}
ctx->comp_frame_size = ntohl(p_hdr->size) + sizeof(*p_hdr);
ctx->comp_frame_size = ntohl(ctx->state.header.size);
if (ctx->comp_frame_size > ctx->comp_max_size)
ctx->comp_frame_size = ctx->comp_max_size;
}
@ -1121,7 +1140,7 @@ static int vicodec_start_streaming(struct vb2_queue *q,
state->stride = q_data->coded_width * info->bytesperline_mult;
}
state->ref_frame.luma = kvmalloc(total_planes_size, GFP_KERNEL);
ctx->comp_max_size = total_planes_size + sizeof(struct fwht_cframe_hdr);
ctx->comp_max_size = total_planes_size;
state->compressed_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
if (!state->ref_frame.luma || !state->compressed_frame) {
kvfree(state->ref_frame.luma);
@ -1148,6 +1167,7 @@ static int vicodec_start_streaming(struct vb2_queue *q,
state->gop_cnt = 0;
ctx->cur_buf_offset = 0;
ctx->comp_size = 0;
ctx->header_size = 0;
ctx->comp_magic_cnt = 0;
ctx->comp_has_frame = false;