[vlc-devel] [PATCH 2/3] v4l2: make VBI mode work with UserPtr and ReadStream mode
Devin Heitmueller
dheitmueller at kernellabs.com
Sun Oct 21 22:01:01 CEST 2012
The commit with the original VBI support only worked with
Mmap mode. Extend the code to work in the other two modes
as well.
---
modules/access/v4l2/demux.c | 146 +++++++++++++++++++++++++++++++++----------
1 file changed, 112 insertions(+), 34 deletions(-)
diff --git a/modules/access/v4l2/demux.c b/modules/access/v4l2/demux.c
index 21e1709..a2dbbb2 100644
--- a/modules/access/v4l2/demux.c
+++ b/modules/access/v4l2/demux.c
@@ -571,11 +571,27 @@ static void *UserPtrThread (void *data)
demux_t *demux = data;
demux_sys_t *sys = demux->p_sys;
int fd = sys->fd;
- struct pollfd ufd[1];
-
+ struct pollfd ufd[2];
+ nfds_t numfds = 1;
+
ufd[0].fd = fd;
ufd[0].events = POLLIN;
+#ifdef ZVBI_COMPILED
+ if ( sys->vbi_cap )
+ {
+ ufd[1].fd = vbi_capture_fd(sys->vbi_cap);
+ ufd[1].events = POLLIN;
+ ufd[1].revents = 0;
+ numfds++;
+
+ /* Do a single read and throw away the results so that ZVBI calls
+ the STREAMON ioctl() */
+ GrabVBI( VLC_OBJECT(demux), sys->vbi_cap, sys->vbi_sliced,
+ sys->vbi_sliced_size, sys->vbi_raw );
+ }
+#endif
+
int canc = vlc_savecancel ();
for (;;)
{
@@ -590,25 +606,48 @@ static void *UserPtrThread (void *data)
/* Wait for data */
vlc_restorecancel (canc);
block_cleanup_push (block);
- while (poll (ufd, 1, -1) == -1)
+ while (poll (ufd, numfds, -1) == -1)
if (errno != EINTR)
msg_Err (demux, "poll error: %m");
vlc_cleanup_pop ();
canc = vlc_savecancel ();
- if (v4l2_ioctl (fd, VIDIOC_DQBUF, &buf) < 0)
+ if( ufd[0].revents & POLLIN )
{
- msg_Err (demux, "cannot dequeue buffer: %m");
- block_Release (block);
- continue;
- }
+ if (v4l2_ioctl (fd, VIDIOC_DQBUF, &buf) < 0)
+ {
+ msg_Err (demux, "cannot dequeue buffer: %m");
+ block_Release (block);
+ continue;
+ }
- assert (block->p_buffer == (void *)buf.m.userptr);
- block->i_buffer = buf.length;
- block->i_pts = block->i_dts = mdate ();
- block->i_flags |= sys->block_flags;
- es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
- es_out_Send (demux->out, sys->es, block);
+ assert (block->p_buffer == (void *)buf.m.userptr);
+ block->i_buffer = buf.length;
+ block->i_pts = block->i_dts = mdate ();
+ block->i_flags |= sys->block_flags;
+ es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
+ es_out_Send (demux->out, sys->es, block);
+ }
+#ifdef ZVBI_COMPILED
+ if( sys->vbi_cap && (ufd[1].revents & POLLIN) )
+ {
+ block_t *p_block = GrabVBI( VLC_OBJECT(demux), sys->vbi_cap,
+ sys->vbi_sliced, sys->vbi_sliced_size,
+ sys->vbi_raw );
+ if( p_block )
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ if (i == 3)
+ es_out_Send( demux->out, sys->p_es_subt[i], p_block );
+ else
+ es_out_Send( demux->out, sys->p_es_subt[i],
+ block_Duplicate(p_block) );
+ }
+ }
+ }
+#endif
}
vlc_restorecancel (canc); /* <- hmm, this is purely cosmetic */
return NULL;
@@ -693,42 +732,81 @@ static void *ReadThread (void *data)
demux_t *demux = data;
demux_sys_t *sys = demux->p_sys;
int fd = sys->fd;
- struct pollfd ufd[1];
-
+ struct pollfd ufd[2];
+ nfds_t numfds = 1;
+
ufd[0].fd = fd;
ufd[0].events = POLLIN;
+#ifdef ZVBI_COMPILED
+ if ( sys->vbi_cap )
+ {
+ ufd[1].fd = vbi_capture_fd(sys->vbi_cap);
+ ufd[1].events = POLLIN;
+ ufd[1].revents = 0;
+ numfds++;
+
+ /* Do a single read and throw away the results so that ZVBI calls
+ the STREAMON ioctl() */
+ GrabVBI( VLC_OBJECT(demux), sys->vbi_cap, sys->vbi_sliced,
+ sys->vbi_sliced_size, sys->vbi_raw );
+ }
+#endif
+
for (;;)
{
/* Wait for data */
- if (poll (ufd, 1, -1) == -1)
+ if (poll (ufd, numfds, -1) == -1)
{
if (errno != EINTR)
msg_Err (demux, "poll error: %m");
continue;
}
- block_t *block = block_Alloc (sys->blocksize);
- if (unlikely(block == NULL))
+ if( ufd[0].revents & POLLIN )
{
- msg_Err (demux, "read error: %m");
- v4l2_read (fd, NULL, 0); /* discard frame */
- continue;
- }
- block->i_pts = block->i_dts = mdate ();
- block->i_flags |= sys->block_flags;
+ block_t *block = block_Alloc (sys->blocksize);
+ if (unlikely(block == NULL))
+ {
+ msg_Err (demux, "read error: %m");
+ v4l2_read (fd, NULL, 0); /* discard frame */
+ continue;
+ }
+ block->i_pts = block->i_dts = mdate ();
+ block->i_flags |= sys->block_flags;
- int canc = vlc_savecancel ();
- ssize_t val = v4l2_read (fd, block->p_buffer, block->i_buffer);
- if (val != -1)
+ int canc = vlc_savecancel ();
+ ssize_t val = v4l2_read (fd, block->p_buffer, block->i_buffer);
+ if (val != -1)
+ {
+ block->i_buffer = val;
+ es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
+ es_out_Send (demux->out, sys->es, block);
+ }
+ else
+ block_Release (block);
+ vlc_restorecancel (canc);
+ }
+#ifdef ZVBI_COMPILED
+ if( sys->vbi_cap && (ufd[1].revents & POLLIN) )
{
- block->i_buffer = val;
- es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
- es_out_Send (demux->out, sys->es, block);
+ block_t *p_block = GrabVBI( VLC_OBJECT(demux), sys->vbi_cap,
+ sys->vbi_sliced, sys->vbi_sliced_size,
+ sys->vbi_raw );
+ if( p_block )
+ {
+ int i;
+ for (i = 0; i < 4; i++)
+ {
+ if (i == 3)
+ es_out_Send( demux->out, sys->p_es_subt[i], p_block );
+ else
+ es_out_Send( demux->out, sys->p_es_subt[i],
+ block_Duplicate(p_block) );
+ }
+ }
}
- else
- block_Release (block);
- vlc_restorecancel (canc);
+#endif
}
assert (0);
}
--
1.7.9.5
More information about the vlc-devel
mailing list