Commit a99f3b3b authored by Jean-Paul Saman's avatar Jean-Paul Saman

oss: use a seperate thread to capture audio

Capture audio in a seperate thread. It ensures that --input-slave oss:// runs independent of the video capturing and resulting in higher throughput.
parent 7f6e0fd0
/*****************************************************************************
* oss.c : OSS input module for vlc
*****************************************************************************
* Copyright (C) 2002-2009 the VideoLAN team
* Copyright (C) 2002-2010 the VideoLAN team
* $Id$
*
* Authors: Benjamin Pracht <bigben at videolan dot org>
......@@ -61,7 +61,6 @@
static int DemuxOpen ( vlc_object_t * );
static void DemuxClose( vlc_object_t * );
#define STEREO_TEXT N_( "Stereo" )
#define STEREO_LONGTEXT N_( \
"Capture the audio stream in stereo." )
......@@ -116,6 +115,17 @@ struct buffer_t
size_t length;
};
typedef struct
{
VLC_COMMON_MEMBERS
demux_t *p_demux;
block_fifo_t *p_fifo;
} audio_grab_thread_t;
static void* GrabAudioThread( vlc_object_t * );
struct demux_sys_t
{
const char *psz_device; /* OSS device from MRL */
......@@ -131,6 +141,9 @@ struct demux_sys_t
es_out_id_t *p_es;
int64_t i_next_demux_date; /* Used to handle oss:// as input-slave properly */
/* capture thread */
audio_grab_thread_t *p_grab;
};
static int FindMainDevice( demux_t *p_demux )
......@@ -179,6 +192,7 @@ static int DemuxOpen( vlc_object_t *p_this )
p_sys->p_es = NULL;
p_sys->p_block = NULL;
p_sys->i_next_demux_date = -1;
p_sys->p_grab = NULL;
if( p_demux->psz_path && *p_demux->psz_path )
p_sys->psz_device = p_demux->psz_path;
......@@ -191,6 +205,20 @@ static int DemuxOpen( vlc_object_t *p_this )
return VLC_EGENERIC;
}
/* Now create our event thread catcher */
p_sys->p_grab = vlc_object_create( p_demux, sizeof( audio_grab_thread_t ) );
if( !p_sys->p_grab )
{
DemuxClose( p_this );
return VLC_EGENERIC;
}
p_sys->p_grab->p_fifo = block_FifoNew();
p_sys->p_grab->p_demux = p_demux;
vlc_thread_create( p_sys->p_grab, "GrabAudioThread",
GrabAudioThread, VLC_THREAD_PRIORITY_INPUT );
return VLC_SUCCESS;
}
......@@ -204,7 +232,21 @@ static void DemuxClose( vlc_object_t *p_this )
if( p_sys->i_fd >= 0 ) close( p_sys->i_fd );
if( p_sys->p_block ) block_Release( p_sys->p_block );
if( p_sys->p_grab )
{
/* stop audio grab thread */
vlc_object_kill( p_sys->p_grab );
vlc_thread_join( p_sys->p_grab );
if( p_sys->p_grab->p_fifo )
block_FifoRelease( p_sys->p_grab->p_fifo );
vlc_object_release( p_sys->p_grab );
}
if( p_sys->p_block )
block_Release( p_sys->p_block );
free( p_sys );
}
......@@ -256,39 +298,47 @@ static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
static int Demux( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
block_t *p_block;
do {
p_block = NULL;
if( block_FifoCount( p_sys->p_grab->p_fifo ) > 0 )
{
p_block = block_FifoGet( p_sys->p_grab->p_fifo );
if( p_block )
es_out_Send( p_demux->out, p_sys->p_es, p_block );
if( p_sys->i_next_demux_date <= 0 &&
p_block->i_pts >= p_sys->i_next_demux_date )
goto out;
}
} while( p_block );
struct pollfd fd;
fd.fd = p_sys->i_fd;
fd.events = POLLIN|POLLPRI;
fd.revents = 0;
out:
return 1;
}
static void* GrabAudioThread( vlc_object_t *p_this )
{
audio_grab_thread_t *p_grab = (audio_grab_thread_t *)p_this;
demux_t *p_demux = (demux_t *)p_grab->p_demux;
block_t *p_block = NULL;
do
{
p_block = GrabAudio( p_demux );
if( p_block )
{
es_out_Send( p_demux->out, p_sys->p_es, p_block );
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
block_FifoPut( p_grab->p_fifo, p_block );
p_block = NULL;
}
/* Wait for data */
if( poll( &fd, 1, 10 ) ) /* Timeout after 0.01 seconds. Bigger delays are an issue when used with/as an input-slave since all the inputs run in the same thread. */
{
if( fd.revents & (POLLIN|POLLPRI) )
{
p_block = GrabAudio( p_demux );
if( p_block )
es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
}
}
} while( p_block && p_sys->i_next_demux_date > 0 &&
p_block->i_pts < p_sys->i_next_demux_date );
} while( vlc_object_alive( p_grab ) || !p_grab->b_error );
if( p_block )
es_out_Send( p_demux->out, p_sys->p_es, p_block );
block_Release( p_block );
return 1;
return NULL;
}
/*****************************************************************************
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment