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:
parent
5fbd0729cf
commit
ddc1b08527
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue