diff options
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.c | 49 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 7 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-dvb.c | 5 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-queue.c | 6 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 26 |
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); } |