Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d526afe0 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab
Browse files

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: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent c58dc0be
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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 */
+8 −21
Original line number Diff line number Diff line
@@ -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, &param);
	}
	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
		ivtv_pio_work_handler(itv);

@@ -678,35 +685,15 @@ 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)
{
+1 −1
Original line number Diff line number Diff line
@@ -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 */

+1 −1
Original line number Diff line number Diff line
@@ -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)
Loading