diff options
author | Andy Walls <awalls@radix.net> | 2009-02-07 13:47:28 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:42:39 -0400 |
commit | 466df46484aced005fa41706f87e18eaa86918ad (patch) | |
tree | bebb0b9d1e8ae9396fb07f22ee7ea67f64c839c4 | |
parent | 01cbc214cfa6e0dbfaea617d32d6d66e7f6608ff (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.c | 54 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-vbi.c | 31 |
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. */ | ||
108 | static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) | 107 | static 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 | ||