aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-02-07 13:47:28 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:39 -0400
commit466df46484aced005fa41706f87e18eaa86918ad (patch)
treebebb0b9d1e8ae9396fb07f22ee7ea67f64c839c4
parent01cbc214cfa6e0dbfaea617d32d6d66e7f6608ff (diff)
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: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/cx18/cx18-driver.c54
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c31
2 files changed, 33 insertions, 52 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 842ce636e45c..3cf8ddb633b4 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -448,34 +448,38 @@ static void cx18_process_options(struct cx18 *cx)
448 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize; 448 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
449 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize; 449 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
450 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize; 450 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
451 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */ 451 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
452 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize; 452 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
453 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */ 453 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
454 454
455 /* Except for VBI ensure stream_buffers & stream_buf_size are valid */ 455 /* Ensure stream_buffers & stream_buf_size are valid */
456 for (i = 0; i < CX18_MAX_STREAMS; i++) { 456 for (i = 0; i < CX18_MAX_STREAMS; i++) {
457 /* User said to use 0 buffers */ 457 if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
458 if (cx->stream_buffers[i] == 0) { 458 cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
459 cx->options.megabytes[i] = 0; 459 cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
460 cx->stream_buf_size[i] = 0;
461 continue;
462 }
463 /* User said to use 0 MB total */
464 if (cx->options.megabytes[i] <= 0) {
465 cx->options.megabytes[i] = 0; 460 cx->options.megabytes[i] = 0;
466 cx->stream_buffers[i] = 0; 461 cx->stream_buffers[i] = 0;
467 cx->stream_buf_size[i] = 0; 462 cx->stream_buf_size[i] = 0;
468 continue; 463 continue;
469 } 464 }
470 /* VBI is computed later or user said buffer has size 0 */ 465 /*
471 if (cx->stream_buf_size[i] <= 0) { 466 * VBI is a special case where the stream_buf_size is fixed
472 if (i != CX18_ENC_STREAM_TYPE_VBI) { 467 * and already in bytes
473 cx->options.megabytes[i] = 0; 468 */
474 cx->stream_buffers[i] = 0; 469 if (i == CX18_ENC_STREAM_TYPE_VBI) {
475 cx->stream_buf_size[i] = 0; 470 if (cx->stream_buffers[i] < 0) {
471 cx->stream_buffers[i] =
472 cx->options.megabytes[i] * 1024 * 1024
473 / cx->stream_buf_size[i];
474 } else {
475 /* N.B. This might round down to 0 */
476 cx->options.megabytes[i] =
477 cx->stream_buffers[i]
478 * cx->stream_buf_size[i]/(1024 * 1024);
476 } 479 }
477 continue; 480 continue;
478 } 481 }
482 /* All other streams have stream_buf_size in kB at this point */
479 if (cx->stream_buffers[i] < 0) { 483 if (cx->stream_buffers[i] < 0) {
480 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 484 cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
481 / cx->stream_buf_size[i]; 485 / cx->stream_buf_size[i];
@@ -732,7 +736,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
732{ 736{
733 int retval = 0; 737 int retval = 0;
734 int i; 738 int i;
735 int vbi_buf_size;
736 u32 devtype; 739 u32 devtype;
737 struct cx18 *cx; 740 struct cx18 *cx;
738 741
@@ -888,23 +891,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
888 } 891 }
889 cx->params.video_gop_size = cx->is_60hz ? 15 : 12; 892 cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
890 893
891 /*
892 * FIXME: setting the buffer size based on the tuner standard is
893 * suboptimal, as the CVBS and SVideo inputs could use a different std
894 * and the buffer could end up being too small in that case.
895 */
896 vbi_buf_size = vbi_active_samples * (cx->is_60hz ? 24 : 36) / 2;
897 cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
898
899 if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
900 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
901 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
902 / vbi_buf_size;
903 else
904 cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
905 cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
906 / (1024 * 1024);
907
908 if (cx->options.radio > 0) 894 if (cx->options.radio > 0)
909 cx->v4l2_cap |= V4L2_CAP_RADIO; 895 cx->v4l2_cap |= V4L2_CAP_RADIO;
910 896
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index d8e7d371c8e2..52082d4a179e 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -103,12 +103,11 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
103} 103}
104 104
105/* Compress raw VBI format, removes leading SAV codes and surplus space 105/* Compress raw VBI format, removes leading SAV codes and surplus space
106 after the field. 106 after the frame. Returns new compressed size. */
107 Returns new compressed size. */
108static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) 107static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
109{ 108{
110 u32 line_size = vbi_active_samples; 109 u32 line_size = vbi_active_samples;
111 u32 lines = cx->vbi.count; 110 u32 lines = cx->vbi.count * 2;
112 u8 sav1 = raw_vbi_sav_rp[0]; 111 u8 sav1 = raw_vbi_sav_rp[0];
113 u8 sav2 = raw_vbi_sav_rp[1]; 112 u8 sav2 = raw_vbi_sav_rp[1];
114 u8 *q = buf; 113 u8 *q = buf;
@@ -195,30 +194,26 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
195 u8 type; 194 u8 type;
196 195
197 /* 196 /*
198 * We've set up to get a field's worth of VBI data at a time. 197 * We've set up to get a frame's worth of VBI data at a time.
199 * Skip 12 bytes of header prefixing the first field or the 198 * Skip 12 bytes of header prefixing the first field.
200 * last 12 bytes in the last VBI line from the first field that
201 * prefixes the second field.
202 */ 199 */
203 size -= 12; 200 size -= 12;
204 memcpy(p, &buf->buf[12], size); 201 memcpy(p, &buf->buf[12], size);
205 type = p[3]; 202 type = p[3];
206 203
207 /* Extrapolate the last 12 bytes of the field's last line */ 204 /* Extrapolate the last 12 bytes of the frame's last line */
208 memset(&p[size], (int) p[size - 1], 12); 205 memset(&p[size], (int) p[size - 1], 12);
206 size += 12;
209 207
210 size = buf->bytesused = compress_raw_buf(cx, p, size); 208 size = buf->bytesused = compress_raw_buf(cx, p, size);
211 209
212 if (type == raw_vbi_sav_rp[1]) { 210 /*
213 /* 211 * Hack needed for compatibility with old VBI software.
214 * Hack needed for compatibility with old VBI software. 212 * Write the frame # at the last 4 bytes of the frame
215 * Write the frame # at the end of the last line of the 213 */
216 * second field 214 p += size - 4;
217 */ 215 memcpy(p, &cx->vbi.frame, 4);
218 p += size - 4; 216 cx->vbi.frame++;
219 memcpy(p, &cx->vbi.frame, 4);
220 cx->vbi.frame++;
221 }
222 return; 217 return;
223 } 218 }
224 219