diff options
Diffstat (limited to 'drivers/media/platform/coda.c')
| -rw-r--r-- | drivers/media/platform/coda.c | 32 | 
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/media/platform/coda.c b/drivers/media/platform/coda.c index 4a980e029ca..20827ba168f 100644 --- a/drivers/media/platform/coda.c +++ b/drivers/media/platform/coda.c @@ -178,6 +178,10 @@ struct coda_ctx {  	int				idx;  }; +static const u8 coda_filler_nal[14] = { 0x00, 0x00, 0x00, 0x01, 0x0c, 0xff, +			0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x80 }; +static const u8 coda_filler_size[8] = { 0, 7, 14, 13, 12, 11, 10, 9 }; +  static inline void coda_write(struct coda_dev *dev, u32 data, u32 reg)  {  	v4l2_dbg(1, coda_debug, &dev->v4l2_dev, @@ -944,6 +948,24 @@ static int coda_alloc_framebuffers(struct coda_ctx *ctx, struct coda_q_data *q_d  	return 0;  } +static int coda_h264_padding(int size, char *p) +{ +	int nal_size; +	int diff; + +	diff = size - (size & ~0x7); +	if (diff == 0) +		return 0; + +	nal_size = coda_filler_size[diff]; +	memcpy(p, coda_filler_nal, nal_size); + +	/* Add rbsp stop bit and trailing at the end */ +	*(p + nal_size - 1) = 0x80; + +	return nal_size; +} +  static int coda_start_streaming(struct vb2_queue *q, unsigned int count)  {  	struct coda_ctx *ctx = vb2_get_drv_priv(q); @@ -1171,7 +1193,15 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)  				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);  		memcpy(&ctx->vpu_header[1][0], vb2_plane_vaddr(buf, 0),  		       ctx->vpu_header_size[1]); -		ctx->vpu_header_size[2] = 0; +		/* +		 * Length of H.264 headers is variable and thus it might not be +		 * aligned for the coda to append the encoded frame. In that is +		 * the case a filler NAL must be added to header 2. +		 */ +		ctx->vpu_header_size[2] = coda_h264_padding( +					(ctx->vpu_header_size[0] + +					 ctx->vpu_header_size[1]), +					 ctx->vpu_header[2]);  		break;  	case V4L2_PIX_FMT_MPEG4:  		/*  |