V4L/DVB (8648): ivtv: improve CC support
- change the work-queue to a single threaded high prio workqueue - use DMA instead of PIO for the sliced VBI data. - remove some incorrect tests - increase the internal VBI capture queue size for sliced VBI packets - ignore duplicate VBI lines With these changes it should finally be possible to get reliable closed captions. Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
This commit is contained in:
parent
c58dc0beaf
commit
d526afe06b
|
@ -688,7 +688,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
|
|||
spin_lock_init(&itv->lock);
|
||||
spin_lock_init(&itv->dma_reg_lock);
|
||||
|
||||
itv->irq_work_queues = create_workqueue(itv->name);
|
||||
itv->irq_work_queues = create_singlethread_workqueue(itv->name);
|
||||
if (itv->irq_work_queues == NULL) {
|
||||
IVTV_ERR("Could not create ivtv workqueue\n");
|
||||
return -1;
|
||||
|
|
|
@ -251,6 +251,7 @@ struct ivtv_mailbox_data {
|
|||
#define IVTV_F_I_DEC_PAUSED 20 /* the decoder is paused */
|
||||
#define IVTV_F_I_INITED 21 /* set after first open */
|
||||
#define IVTV_F_I_FAILED 22 /* set if first open failed */
|
||||
#define IVTV_F_I_WORK_INITED 23 /* worker thread was initialized */
|
||||
|
||||
/* Event notifications */
|
||||
#define IVTV_F_I_EV_DEC_STOPPED 28 /* decoder stopped event */
|
||||
|
|
|
@ -76,6 +76,13 @@ void ivtv_irq_work_handler(struct work_struct *work)
|
|||
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
if (test_and_clear_bit(IVTV_F_I_WORK_INITED, &itv->i_flags)) {
|
||||
struct sched_param param = { .sched_priority = 99 };
|
||||
|
||||
/* This thread must use the FIFO scheduler as it
|
||||
is realtime sensitive. */
|
||||
sched_setscheduler(current, SCHED_FIFO, ¶m);
|
||||
}
|
||||
if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
|
||||
ivtv_pio_work_handler(itv);
|
||||
|
||||
|
@ -678,34 +685,14 @@ static void ivtv_irq_enc_start_cap(struct ivtv *itv)
|
|||
|
||||
static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
|
||||
{
|
||||
struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
|
||||
u32 data[CX2341X_MBOX_MAX_DATA];
|
||||
struct ivtv_stream *s;
|
||||
|
||||
IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n");
|
||||
s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
|
||||
|
||||
/* If more than two VBI buffers are pending, then
|
||||
clear the old ones and start with this new one.
|
||||
This can happen during transition stages when MPEG capturing is
|
||||
started, but the first interrupts haven't arrived yet. During
|
||||
that period VBI requests can accumulate without being able to
|
||||
DMA the data. Since at most four VBI DMA buffers are available,
|
||||
we just drop the old requests when there are already three
|
||||
requests queued. */
|
||||
if (s->sg_pending_size > 2) {
|
||||
struct ivtv_buffer *buf;
|
||||
list_for_each_entry(buf, &s->q_predma.list, list)
|
||||
ivtv_buf_sync_for_cpu(s, buf);
|
||||
ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0);
|
||||
s->sg_pending_size = 0;
|
||||
}
|
||||
/* if we can append the data, and the MPEG stream isn't capturing,
|
||||
then start a DMA request for just the VBI data. */
|
||||
if (!stream_enc_dma_append(s, data) &&
|
||||
!test_bit(IVTV_F_S_STREAMING, &s_mpg->s_flags)) {
|
||||
if (!stream_enc_dma_append(s, data))
|
||||
set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
|
||||
}
|
||||
}
|
||||
|
||||
static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#define IVTV_QUEUE_H
|
||||
|
||||
#define IVTV_DMA_UNMAPPED ((u32) -1)
|
||||
#define SLICED_VBI_PIO 1
|
||||
#define SLICED_VBI_PIO 0
|
||||
|
||||
/* ivtv_buffer utility functions */
|
||||
|
||||
|
|
|
@ -363,7 +363,7 @@ static void ivtv_vbi_setup(struct ivtv *itv)
|
|||
/* Every X number of frames a VBI interrupt arrives (frames as in 25 or 30 fps) */
|
||||
data[1] = 1;
|
||||
/* The VBI frames are stored in a ringbuffer with this size (with a VBI frame as unit) */
|
||||
data[2] = raw ? 4 : 8;
|
||||
data[2] = raw ? 4 : 4 * (itv->vbi.raw_size / itv->vbi.enc_size);
|
||||
/* The start/stop codes determine which VBI lines end up in the raw VBI data area.
|
||||
The codes are from table 24 in the saa7115 datasheet. Each raw/sliced/video line
|
||||
is framed with codes FF0000XX where XX is the SAV/EAV (Start/End of Active Video)
|
||||
|
|
|
@ -293,6 +293,7 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8
|
|||
u32 line_size = itv->vbi.sliced_decoder_line_size;
|
||||
struct v4l2_decode_vbi_line vbi;
|
||||
int i;
|
||||
unsigned lines = 0;
|
||||
|
||||
/* find the first valid line */
|
||||
for (i = 0; i < size; i++, buf++) {
|
||||
|
@ -313,7 +314,8 @@ static u32 compress_sliced_buf(struct ivtv *itv, u32 line, u8 *buf, u32 size, u8
|
|||
}
|
||||
vbi.p = p + 4;
|
||||
itv->video_dec_func(itv, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
|
||||
if (vbi.type) {
|
||||
if (vbi.type && !(lines & (1 << vbi.line))) {
|
||||
lines |= 1 << vbi.line;
|
||||
itv->vbi.sliced_data[line].id = vbi.type;
|
||||
itv->vbi.sliced_data[line].field = vbi.is_second_field;
|
||||
itv->vbi.sliced_data[line].line = vbi.line;
|
||||
|
|
Loading…
Reference in New Issue