Re: [PATCH 07/30] [media] coda: add selection API support for h.264 decoder

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 06/13/2014 06:08 PM, Philipp Zabel wrote:
> The h.264 decoder produces capture frames that are a multiple of the macroblock
> size (16 pixels). To inform userspace about invalid pixel data at the edges,
> use the active and padded composing rectangles on the capture queue.
> The cropping information is obtained from the h.264 sequence parameter set.
> 
> Signed-off-by: Philipp Zabel <p.zabel@xxxxxxxxxxxxxx>
> ---
>  drivers/media/platform/coda.c | 87 +++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 87 insertions(+)
> 
> diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c
> index 10cc031..7e4df82 100644
> --- a/drivers/media/platform/coda.c
> +++ b/drivers/media/platform/coda.c
> @@ -119,6 +119,7 @@ struct coda_q_data {
>  	unsigned int		height;
>  	unsigned int		sizeimage;
>  	unsigned int		fourcc;
> +	struct v4l2_rect	rect;
>  };
>  
>  struct coda_aux_buf {
> @@ -737,6 +738,10 @@ static int coda_s_fmt(struct coda_ctx *ctx, struct v4l2_format *f)
>  	q_data->width = f->fmt.pix.width;
>  	q_data->height = f->fmt.pix.height;
>  	q_data->sizeimage = f->fmt.pix.sizeimage;
> +	q_data->rect.left = 0;
> +	q_data->rect.top = 0;
> +	q_data->rect.width = f->fmt.pix.width;
> +	q_data->rect.height = f->fmt.pix.height;
>  
>  	v4l2_dbg(1, coda_debug, &ctx->dev->v4l2_dev,
>  		"Setting format for type %d, wxh: %dx%d, fmt: %d\n",
> @@ -873,6 +878,43 @@ static int coda_streamoff(struct file *file, void *priv,
>  	return ret;
>  }
>  
> +static int coda_g_selection(struct file *file, void *fh,
> +			    struct v4l2_selection *s)
> +{
> +	struct coda_ctx *ctx = fh_to_ctx(fh);
> +	struct coda_q_data *q_data;
> +
> +	switch (s->target) {
> +	case V4L2_SEL_TGT_CROP:
> +		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);

There is no check against s->type: CROP is only supported for output
buffers and should return -EINVAL for capture buffers and the reverse
for COMPOSE.

> +		s->r = q_data->rect;
> +		break;
> +	case V4L2_SEL_TGT_CROP_DEFAULT:
> +	case V4L2_SEL_TGT_CROP_BOUNDS:
> +		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
> +		s->r.left = 0;
> +		s->r.top = 0;
> +		s->r.width = q_data->width;
> +		s->r.height = q_data->height;
> +		break;
> +	case V4L2_SEL_TGT_COMPOSE:
> +	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
> +		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +		s->r = q_data->rect;
> +		break;
> +	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
> +	case V4L2_SEL_TGT_COMPOSE_PADDED:
> +		q_data = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
> +		s->r.left = 0;
> +		s->r.top = 0;
> +		s->r.width = q_data->width;
> +		s->r.height = q_data->height;
> +		break;

Add:

	default:
		return -EINVAL;

Regards,

	Hans

> +	}
> +
> +	return 0;
> +}
> +
>  static int coda_try_decoder_cmd(struct file *file, void *fh,
>  				struct v4l2_decoder_cmd *dc)
>  {
> @@ -951,6 +993,8 @@ static const struct v4l2_ioctl_ops coda_ioctl_ops = {
>  	.vidioc_streamon	= coda_streamon,
>  	.vidioc_streamoff	= coda_streamoff,
>  
> +	.vidioc_g_selection	= coda_g_selection,
> +
>  	.vidioc_try_decoder_cmd	= coda_try_decoder_cmd,
>  	.vidioc_decoder_cmd	= coda_decoder_cmd,
>  
> @@ -1506,6 +1550,10 @@ static void set_default_params(struct coda_ctx *ctx)
>  	ctx->q_data[V4L2_M2M_DST].width = max_w;
>  	ctx->q_data[V4L2_M2M_DST].height = max_h;
>  	ctx->q_data[V4L2_M2M_DST].sizeimage = CODA_MAX_FRAME_SIZE;
> +	ctx->q_data[V4L2_M2M_SRC].rect.width = max_w;
> +	ctx->q_data[V4L2_M2M_SRC].rect.height = max_h;
> +	ctx->q_data[V4L2_M2M_DST].rect.width = max_w;
> +	ctx->q_data[V4L2_M2M_DST].rect.height = max_h;
>  
>  	if (ctx->dev->devtype->product == CODA_960)
>  		coda_set_tiled_map_type(ctx, GDI_LINEAR_FRAME_MAP);
> @@ -2033,6 +2081,21 @@ static int coda_start_decoding(struct coda_ctx *ctx)
>  		return -EINVAL;
>  	}
>  
> +	if (src_fourcc == V4L2_PIX_FMT_H264) {
> +		u32 left_right;
> +		u32 top_bottom;
> +
> +		left_right = coda_read(dev, CODA_RET_DEC_SEQ_CROP_LEFT_RIGHT);
> +		top_bottom = coda_read(dev, CODA_RET_DEC_SEQ_CROP_TOP_BOTTOM);
> +
> +		q_data_dst->rect.left = (left_right >> 10) & 0x3ff;
> +		q_data_dst->rect.top = (top_bottom >> 10) & 0x3ff;
> +		q_data_dst->rect.width = width - q_data_dst->rect.left -
> +					 (left_right & 0x3ff);
> +		q_data_dst->rect.height = height - q_data_dst->rect.top -
> +					  (top_bottom & 0x3ff);
> +	}
> +
>  	ret = coda_alloc_framebuffers(ctx, q_data_dst, src_fourcc);
>  	if (ret < 0)
>  		return ret;
> @@ -2939,6 +3002,30 @@ static void coda_finish_decode(struct coda_ctx *ctx)
>  
>  	q_data_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
>  
> +	/* frame crop information */
> +	if (src_fourcc == V4L2_PIX_FMT_H264) {
> +		u32 left_right;
> +		u32 top_bottom;
> +
> +		left_right = coda_read(dev, CODA_RET_DEC_PIC_CROP_LEFT_RIGHT);
> +		top_bottom = coda_read(dev, CODA_RET_DEC_PIC_CROP_TOP_BOTTOM);
> +
> +		if (left_right == 0xffffffff && top_bottom == 0xffffffff) {
> +			/* Keep current crop information */
> +		} else {
> +			struct v4l2_rect *rect = &q_data_dst->rect;
> +
> +			rect->left = left_right >> 16 & 0xffff;
> +			rect->top = top_bottom >> 16 & 0xffff;
> +			rect->width = width - rect->left -
> +				      (left_right & 0xffff);
> +			rect->height = height - rect->top -
> +				       (top_bottom & 0xffff);
> +		}
> +	} else {
> +		/* no cropping */
> +	}
> +
>  	val = coda_read(dev, CODA_RET_DEC_PIC_ERR_MB);
>  	if (val > 0)
>  		v4l2_err(&dev->v4l2_dev,
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux