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

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
...@@ -448,34 +448,38 @@ static void cx18_process_options(struct cx18 *cx) ...@@ -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_MPG] = enc_mpg_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_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_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_PCM] = enc_pcm_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */ 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++) { for (i = 0; i < CX18_MAX_STREAMS; i++) {
/* User said to use 0 buffers */ if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
if (cx->stream_buffers[i] == 0) { cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
cx->options.megabytes[i] = 0; cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
cx->stream_buf_size[i] = 0;
continue;
}
/* User said to use 0 MB total */
if (cx->options.megabytes[i] <= 0) {
cx->options.megabytes[i] = 0; cx->options.megabytes[i] = 0;
cx->stream_buffers[i] = 0; cx->stream_buffers[i] = 0;
cx->stream_buf_size[i] = 0; cx->stream_buf_size[i] = 0;
continue; continue;
} }
/* VBI is computed later or user said buffer has size 0 */ /*
if (cx->stream_buf_size[i] <= 0) { * VBI is a special case where the stream_buf_size is fixed
if (i != CX18_ENC_STREAM_TYPE_VBI) { * and already in bytes
cx->options.megabytes[i] = 0; */
cx->stream_buffers[i] = 0; if (i == CX18_ENC_STREAM_TYPE_VBI) {
cx->stream_buf_size[i] = 0; 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; continue;
} }
/* All other streams have stream_buf_size in kB at this point */
if (cx->stream_buffers[i] < 0) { if (cx->stream_buffers[i] < 0) {
cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
/ cx->stream_buf_size[i]; / cx->stream_buf_size[i];
...@@ -732,7 +736,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -732,7 +736,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
{ {
int retval = 0; int retval = 0;
int i; int i;
int vbi_buf_size;
u32 devtype; u32 devtype;
struct cx18 *cx; struct cx18 *cx;
...@@ -888,23 +891,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -888,23 +891,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
} }
cx->params.video_gop_size = cx->is_60hz ? 15 : 12; 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) if (cx->options.radio > 0)
cx->v4l2_cap |= V4L2_CAP_RADIO; cx->v4l2_cap |= V4L2_CAP_RADIO;
......
...@@ -103,12 +103,11 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) ...@@ -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 /* Compress raw VBI format, removes leading SAV codes and surplus space
after the field. after the frame. Returns new compressed size. */
Returns new compressed size. */
static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
{ {
u32 line_size = vbi_active_samples; 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 sav1 = raw_vbi_sav_rp[0];
u8 sav2 = raw_vbi_sav_rp[1]; u8 sav2 = raw_vbi_sav_rp[1];
u8 *q = buf; u8 *q = buf;
...@@ -195,30 +194,26 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, ...@@ -195,30 +194,26 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
u8 type; u8 type;
/* /*
* We've set up to get a field's worth of VBI data at a time. * 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 or the * Skip 12 bytes of header prefixing the first field.
* last 12 bytes in the last VBI line from the first field that
* prefixes the second field.
*/ */
size -= 12; size -= 12;
memcpy(p, &buf->buf[12], size); memcpy(p, &buf->buf[12], size);
type = p[3]; 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); memset(&p[size], (int) p[size - 1], 12);
size += 12;
size = buf->bytesused = compress_raw_buf(cx, p, size); size = buf->bytesused = compress_raw_buf(cx, p, size);
if (type == raw_vbi_sav_rp[1]) {
/* /*
* Hack needed for compatibility with old VBI software. * Hack needed for compatibility with old VBI software.
* Write the frame # at the end of the last line of the * Write the frame # at the last 4 bytes of the frame
* second field
*/ */
p += size - 4; p += size - 4;
memcpy(p, &cx->vbi.frame, 4); memcpy(p, &cx->vbi.frame, 4);
cx->vbi.frame++; cx->vbi.frame++;
}
return; return;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment