summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/media/video/cx18/cx18-driver.c49
-rw-r--r--drivers/media/video/cx18/cx18-driver.h7
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c5
-rw-r--r--drivers/media/video/cx18/cx18-queue.c6
-rw-r--r--drivers/media/video/cx18/cx18-streams.c26
5 files changed, 71 insertions, 22 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index ba4c3ceffbb3..87a735f1ee9e 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -211,7 +211,9 @@ MODULE_PARM_DESC(enc_yuv_buffers,
"\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS));
MODULE_PARM_DESC(enc_yuv_bufsize,
"Size of an encoder YUV buffer (kB)\n"
- "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE));
+ "\t\t\tAllowed values are multiples of 33.75 kB rounded up\n"
+ "\t\t\t(multiples of size required for 32 screen lines)\n"
+ "\t\t\tDefault: 102");
MODULE_PARM_DESC(enc_yuv_bufs,
"Number of encoder YUV buffers\n"
"\t\t\tDefault is computed from other enc_yuv_* parameters");
@@ -499,10 +501,27 @@ static void cx18_process_options(struct cx18 *cx)
continue;
}
/*
+ * YUV is a special case where the stream_buf_size needs to be
+ * an integral multiple of 33.75 kB (storage for 32 screens
+ * lines to maintain alignment in case of lost buffers
+ */
+ if (i == CX18_ENC_STREAM_TYPE_YUV) {
+ cx->stream_buf_size[i] *= 1024;
+ cx->stream_buf_size[i] -=
+ (cx->stream_buf_size[i] % CX18_UNIT_ENC_YUV_BUFSIZE);
+
+ if (cx->stream_buf_size[i] < CX18_UNIT_ENC_YUV_BUFSIZE)
+ cx->stream_buf_size[i] =
+ CX18_UNIT_ENC_YUV_BUFSIZE;
+ }
+ /*
+ * YUV is a special case where the stream_buf_size is
+ * now in bytes.
* VBI is a special case where the stream_buf_size is fixed
* and already in bytes
*/
- if (i == CX18_ENC_STREAM_TYPE_VBI) {
+ if (i == CX18_ENC_STREAM_TYPE_VBI ||
+ i == CX18_ENC_STREAM_TYPE_YUV) {
if (cx->stream_buffers[i] < 0) {
cx->stream_buffers[i] =
cx->options.megabytes[i] * 1024 * 1024
@@ -513,18 +532,24 @@ static void cx18_process_options(struct cx18 *cx)
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];
} else {
- /* N.B. This might round down to 0 */
- cx->options.megabytes[i] =
- cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024;
+ /* All other streams have stream_buf_size in kB here */
+ if (cx->stream_buffers[i] < 0) {
+ cx->stream_buffers[i] =
+ cx->options.megabytes[i] * 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;
+ }
+ /* convert from kB to bytes */
+ cx->stream_buf_size[i] *= 1024;
}
- cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
+ CX18_DEBUG_INFO("Stream type %d options: %d MB, %d buffers, "
+ "%d bytes\n", i, cx->options.megabytes[i],
+ cx->stream_buffers[i], cx->stream_buf_size[i]);
}
cx->options.cardtype = cardtype[cx->instance];
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index bed8bcc65411..5c78b014dbc0 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -120,11 +120,16 @@
/* Maximum firmware DMA buffers per stream */
#define CX18_MAX_FW_MDLS_PER_STREAM 63
+/* YUV buffer sizes in bytes to ensure integer # of frames per buffer */
+#define CX18_UNIT_ENC_YUV_BUFSIZE (720 * 32 * 3 / 2) /* bytes */
+#define CX18_625_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 576/32)
+#define CX18_525_LINE_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 480/32)
+
/* DMA buffer, default size in kB allocated */
#define CX18_DEFAULT_ENC_TS_BUFSIZE 32
#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32
#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32
-#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128
+#define CX18_DEFAULT_ENC_YUV_BUFSIZE (CX18_UNIT_ENC_YUV_BUFSIZE * 3 / 1024 + 1)
/* Default VBI bufsize based on standards supported by card tuner for now */
#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index 54a6fd3f7af5..71ad2d1b4c2c 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -362,9 +362,10 @@ int cx18_dvb_register(struct cx18_stream *stream)
dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx);
CX18_INFO("DVB Frontend registered\n");
- CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n",
+ CX18_INFO("Registered DVB adapter%d for %s (%d x %d.%02d kB)\n",
stream->dvb.dvb_adapter.num, stream->name,
- stream->buffers, stream->buf_size/1024);
+ stream->buffers, stream->buf_size/1024,
+ (stream->buf_size * 100 / 1024) % 100);
mutex_init(&dvb->feedlock);
dvb->enabled = 1;
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index c1a49ecf9d98..98cbf001f8da 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -348,9 +348,11 @@ int cx18_stream_alloc(struct cx18_stream *s)
if (s->buffers == 0)
return 0;
- CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n",
+ CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers "
+ "(%d.%02d kB total)\n",
s->name, s->buffers, s->buf_size,
- s->buffers * s->buf_size / 1024);
+ s->buffers * s->buf_size / 1024,
+ (s->buffers * s->buf_size * 100 / 1024) % 100);
if (((char __iomem *)&cx->scb->cpu_mdl[cx->free_mdl_idx + s->buffers] -
(char __iomem *)cx->scb) > SCB_RESERVED_SIZE) {
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)
switch (vfl_type) {
case VFL_TYPE_GRABBER:
- CX18_INFO("Registered device video%d for %s (%d x %d kB)\n",
+ CX18_INFO("Registered device video%d for %s "
+ "(%d x %d.%02d kB)\n",
num, s->name, cx->stream_buffers[type],
- cx->stream_buf_size[type]/1024);
+ cx->stream_buf_size[type] / 1024,
+ (cx->stream_buf_size[type] * 100 / 1024) % 100);
break;
case VFL_TYPE_RADIO:
@@ -501,9 +503,23 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s)
{
cx18_unload_queues(s);
- /* For now */
- s->bufs_per_mdl = 1;
- s->mdl_size = s->buf_size * s->bufs_per_mdl;
+ switch (s->type) {
+ case CX18_ENC_STREAM_TYPE_YUV:
+ /*
+ * Height should be a multiple of 32 lines.
+ * Set the MDL size to the exact size needed for one frame.
+ * Use enough buffers per MDL to cover the MDL size
+ */
+ s->mdl_size = 720 * s->cx->params.height * 3 / 2;
+ s->bufs_per_mdl = s->mdl_size / s->buf_size;
+ if (s->mdl_size % s->buf_size)
+ s->bufs_per_mdl++;
+ break;
+ default:
+ s->bufs_per_mdl = 1;
+ s->mdl_size = s->buf_size * s->bufs_per_mdl;
+ break;
+ }
cx18_load_queues(s);
}