Commit ddc1b085 authored by Dafna Hirschfeld's avatar Dafna Hirschfeld Committed by Mauro Carvalho Chehab
Browse files

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: default avatarDafna Hirschfeld <dafna3@gmail.com>
Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 5fbd0729
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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;
};

+65 −45
Original line number Diff line number Diff line
@@ -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;