Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d35167a1 authored by Philipp Zabel's avatar Philipp Zabel Committed by Mauro Carvalho Chehab
Browse files

[media] coda: add coda_encode_header helper function



In preparation for CODA7541 and CODA960 multi-stream support and for
replacement of the completion with a mutex lock, consolidate the
header encoding in a helper function.

Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: default avatarKamil Debski <k.debski@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent b96904e5
Loading
Loading
Loading
Loading
+53 −59
Original line number Diff line number Diff line
@@ -1022,6 +1022,28 @@ static int coda_h264_padding(int size, char *p)
	return nal_size;
}

static int coda_encode_header(struct coda_ctx *ctx, struct vb2_buffer *buf,
			      int header_code, u8 *header, int *size)
{
	struct coda_dev *dev = ctx->dev;
	int ret;

	coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0),
		   CODA_CMD_ENC_HEADER_BB_START);
	coda_write(dev, vb2_plane_size(buf, 0), CODA_CMD_ENC_HEADER_BB_SIZE);
	coda_write(dev, header_code, CODA_CMD_ENC_HEADER_CODE);
	ret = coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER);
	if (ret < 0) {
		v4l2_err(&dev->v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
		return ret;
	}
	*size = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
		coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
	memcpy(header, vb2_plane_vaddr(buf, 0), *size);

	return 0;
}

static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct coda_ctx *ctx = vb2_get_drv_priv(q);
@@ -1032,7 +1054,7 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
	struct vb2_buffer *buf;
	u32 dst_fourcc;
	u32 value;
	int ret;
	int ret = 0;

	if (count < 1)
		return -EINVAL;
@@ -1219,33 +1241,22 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
		 * Get SPS in the first frame and copy it to an
		 * intermediate buffer.
		 */
		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
		coda_write(dev, CODA_HEADER_H264_SPS, CODA_CMD_ENC_HEADER_CODE);
		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
			return -ETIMEDOUT;
		}
		ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
		memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
		       ctx->vpu_header_size[0]);
		ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_SPS,
					 &ctx->vpu_header[0][0],
					 &ctx->vpu_header_size[0]);
		if (ret < 0)
			goto out;

		/*
		 * Get PPS in the first frame and copy it to an
		 * intermediate buffer.
		 */
		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
		coda_write(dev, CODA_HEADER_H264_PPS, CODA_CMD_ENC_HEADER_CODE);
		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
			return -ETIMEDOUT;
		}
		ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
				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]);
		ret = coda_encode_header(ctx, buf, CODA_HEADER_H264_PPS,
					 &ctx->vpu_header[1][0],
					 &ctx->vpu_header_size[1]);
		if (ret < 0)
			goto out;

		/*
		 * 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
@@ -1261,48 +1272,31 @@ static int coda_start_streaming(struct vb2_queue *q, unsigned int count)
		 * Get VOS in the first frame and copy it to an
		 * intermediate buffer
		 */
		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
		coda_write(dev, CODA_HEADER_MP4V_VOS, CODA_CMD_ENC_HEADER_CODE);
		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER timeout\n");
			return -ETIMEDOUT;
		}
		ctx->vpu_header_size[0] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
		memcpy(&ctx->vpu_header[0][0], vb2_plane_vaddr(buf, 0),
		       ctx->vpu_header_size[0]);

		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
		coda_write(dev, CODA_HEADER_MP4V_VIS, CODA_CMD_ENC_HEADER_CODE);
		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
			return -ETIMEDOUT;
		}
		ctx->vpu_header_size[1] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
				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]);

		coda_write(dev, vb2_dma_contig_plane_dma_addr(buf, 0), CODA_CMD_ENC_HEADER_BB_START);
		coda_write(dev, bitstream_size, CODA_CMD_ENC_HEADER_BB_SIZE);
		coda_write(dev, CODA_HEADER_MP4V_VOL, CODA_CMD_ENC_HEADER_CODE);
		if (coda_command_sync(ctx, CODA_COMMAND_ENCODE_HEADER)) {
			v4l2_err(v4l2_dev, "CODA_COMMAND_ENCODE_HEADER failed\n");
			return -ETIMEDOUT;
		}
		ctx->vpu_header_size[2] = coda_read(dev, CODA_REG_BIT_WR_PTR(ctx->idx)) -
				coda_read(dev, CODA_CMD_ENC_HEADER_BB_START);
		memcpy(&ctx->vpu_header[2][0], vb2_plane_vaddr(buf, 0),
		       ctx->vpu_header_size[2]);
		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOS,
					 &ctx->vpu_header[0][0],
					 &ctx->vpu_header_size[0]);
		if (ret < 0)
			goto out;

		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VIS,
					 &ctx->vpu_header[1][0],
					 &ctx->vpu_header_size[1]);
		if (ret < 0)
			goto out;

		ret = coda_encode_header(ctx, buf, CODA_HEADER_MP4V_VOL,
					 &ctx->vpu_header[2][0],
					 &ctx->vpu_header_size[2]);
		if (ret < 0)
			goto out;
		break;
	default:
		/* No more formats need to save headers at the moment */
		break;
	}

	return 0;
out:
	return ret;
}

static int coda_stop_streaming(struct vb2_queue *q)