aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-streams.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-11-09 21:55:30 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:41:52 -0500
commit22dce188ef3e1e058ceabe3b3072640d7568f764 (patch)
tree6a5ee29e5b7cdf9125bea7456c8de75ab0861b92 /drivers/media/video/cx18/cx18-streams.c
parent52fcb3ecc6707f52dfe4297f96b7609d4ba517fb (diff)
V4L/DVB (13430): cx18: Fix YUV capture so that encoder passes a single frame per transfer
Fix YUV capture such that the encoder will pass one frame per transfer. This will allow the application to maintain frame alignment when a transfer from the encoder is missed due to high system latency in service the CX23418 IRQ. Also force YUV buffer sizes to be specified in multiples of 33.75 kB, the smalled amount of buffer sizes need to store a complete set of HM12 4:2:0 macroblocks specifying 32 lines of the frame. A full 60Hz/525 line screen requires 15 * 33.75 kB per frame and a full 50Hz/625 line screen requires 18 * 33.75 kB per frame so the default buffer size is 3 * 33.75 kB, requiring exactly 5 or 6 buffers per MDL respectively. The bytes needed per frame and hence MDL need not be the bytes in an integer number of buffers. However, if frame artifacts are seen with scaled screen sizes, the YUV buffer size can be set 34 kB (33.75 kB) to get rid of the artifacts at the cost of more copies between the kernel and userspace. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-streams.c')
-rw-r--r--drivers/media/video/cx18/cx18-streams.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 9f8adda6f261..7755937fc521 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -262,9 +262,11 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
262 262
263 switch (vfl_type) { 263 switch (vfl_type) {
264 case VFL_TYPE_GRABBER: 264 case VFL_TYPE_GRABBER:
265 CX18_INFO("Registered device video%d for %s (%d x %d kB)\n", 265 CX18_INFO("Registered device video%d for %s "
266 "(%d x %d.%02d kB)\n",
266 num, s->name, cx->stream_buffers[type], 267 num, s->name, cx->stream_buffers[type],
267 cx->stream_buf_size[type]/1024); 268 cx->stream_buf_size[type] / 1024,
269 (cx->stream_buf_size[type] * 100 / 1024) % 100);
268 break; 270 break;
269 271
270 case VFL_TYPE_RADIO: 272 case VFL_TYPE_RADIO:
@@ -501,9 +503,23 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s)
501{ 503{
502 cx18_unload_queues(s); 504 cx18_unload_queues(s);
503 505
504 /* For now */ 506 switch (s->type) {
505 s->bufs_per_mdl = 1; 507 case CX18_ENC_STREAM_TYPE_YUV:
506 s->mdl_size = s->buf_size * s->bufs_per_mdl; 508 /*
509 * Height should be a multiple of 32 lines.
510 * Set the MDL size to the exact size needed for one frame.
511 * Use enough buffers per MDL to cover the MDL size
512 */
513 s->mdl_size = 720 * s->cx->params.height * 3 / 2;
514 s->bufs_per_mdl = s->mdl_size / s->buf_size;
515 if (s->mdl_size % s->buf_size)
516 s->bufs_per_mdl++;
517 break;
518 default:
519 s->bufs_per_mdl = 1;
520 s->mdl_size = s->buf_size * s->bufs_per_mdl;
521 break;
522 }
507 523
508 cx18_load_queues(s); 524 cx18_load_queues(s);
509} 525}