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

Commit 466df464 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB (10445): cx18: Process Raw VBI on a whole frame basis; fix VBI buffer size



The cx23418 appears to send Raw VBI buffers with a PTS on a per frame
basis, not per field, so process Raw VBI on a whole frame basis and reduce
some complexity.  Fix VBI buffer size computation to handle a whole
frame of Raw VBI for a 625 line system, which is the worst case and will
work for 525 lines systems as well.

Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 01cbc214
Loading
Loading
Loading
Loading
+20 −34
Original line number Diff line number Diff line
@@ -448,34 +448,38 @@ static void cx18_process_options(struct cx18 *cx)
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */

	/* Except for VBI ensure stream_buffers & stream_buf_size are valid */
	/* Ensure stream_buffers & stream_buf_size are valid */
	for (i = 0; i < CX18_MAX_STREAMS; i++) {
		/* User said to use 0 buffers */
		if (cx->stream_buffers[i] == 0) {
			cx->options.megabytes[i] = 0;
			cx->stream_buf_size[i] = 0;
			continue;
		}
		/* User said to use 0 MB total */
		if (cx->options.megabytes[i] <= 0) {
		if (cx->stream_buffers[i] == 0 ||     /* User said 0 buffers */
		    cx->options.megabytes[i] <= 0 ||  /* User said 0 MB total */
		    cx->stream_buf_size[i] <= 0) {    /* User said buf size 0 */
			cx->options.megabytes[i] = 0;
			cx->stream_buffers[i] = 0;
			cx->stream_buf_size[i] = 0;
			continue;
		}
		/* VBI is computed later or user said buffer has size 0 */
		if (cx->stream_buf_size[i] <= 0) {
			if (i != CX18_ENC_STREAM_TYPE_VBI) {
				cx->options.megabytes[i] = 0;
				cx->stream_buffers[i] = 0;
				cx->stream_buf_size[i] = 0;
		/*
		 * VBI is a special case where the stream_buf_size is fixed
		 * and already in bytes
		 */
		if (i == CX18_ENC_STREAM_TYPE_VBI) {
			if (cx->stream_buffers[i] < 0) {
				cx->stream_buffers[i] =
					cx->options.megabytes[i] * 1024 * 1024
					/ cx->stream_buf_size[i];
			} else {
				/* N.B. This might round down to 0 */
				cx->options.megabytes[i] =
					cx->stream_buffers[i]
					* cx->stream_buf_size[i]/(1024 * 1024);
			}
			continue;
		}
		/* All other streams have stream_buf_size in kB at this point */
		if (cx->stream_buffers[i] < 0) {
			cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
						/ cx->stream_buf_size[i];
@@ -732,7 +736,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
{
	int retval = 0;
	int i;
	int vbi_buf_size;
	u32 devtype;
	struct cx18 *cx;

@@ -888,23 +891,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
	}
	cx->params.video_gop_size = cx->is_60hz ? 15 : 12;

	/*
	 * FIXME: setting the buffer size based on the tuner standard is
	 * suboptimal, as the CVBS and SVideo inputs could use a different std
	 * and the buffer could end up being too small in that case.
	 */
	vbi_buf_size = vbi_active_samples * (cx->is_60hz ? 24 : 36) / 2;
	cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;

	if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
		cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
		   cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
		   / vbi_buf_size;
	else
		cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
		     cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
		     / (1024 * 1024);

	if (cx->options.radio > 0)
		cx->v4l2_cap |= V4L2_CAP_RADIO;

+13 −18
Original line number Diff line number Diff line
@@ -103,12 +103,11 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
}

/* Compress raw VBI format, removes leading SAV codes and surplus space
   after the field.
   Returns new compressed size. */
   after the frame.  Returns new compressed size. */
static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
{
	u32 line_size = vbi_active_samples;
	u32 lines = cx->vbi.count;
	u32 lines = cx->vbi.count * 2;
	u8 sav1 = raw_vbi_sav_rp[0];
	u8 sav2 = raw_vbi_sav_rp[1];
	u8 *q = buf;
@@ -195,30 +194,26 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
		u8 type;

		/*
		 * We've set up to get a field's worth of VBI data at a time.
		 * Skip 12 bytes of header prefixing the first field or the
		 * last 12 bytes in the last VBI line from the first field that
		 * prefixes the second field.
		 * We've set up to get a frame's worth of VBI data at a time.
		 * Skip 12 bytes of header prefixing the first field.
		 */
		size -= 12;
		memcpy(p, &buf->buf[12], size);
		type = p[3];

		/* Extrapolate the last 12 bytes of the field's last line */
		/* Extrapolate the last 12 bytes of the frame's last line */
		memset(&p[size], (int) p[size - 1], 12);
		size += 12;

		size = buf->bytesused = compress_raw_buf(cx, p, size);

		if (type == raw_vbi_sav_rp[1]) {
		/*
		 * Hack needed for compatibility with old VBI software.
			 * Write the frame # at the end of the last line of the
			 * second field
		 * Write the frame # at the last 4 bytes of the frame
		 */
		p += size - 4;
		memcpy(p, &cx->vbi.frame, 4);
		cx->vbi.frame++;
		}
		return;
	}