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

v4l2: try grabbing exact number of frames requested

The framerate calculation previously done in v4l2 access input was always late. Reworked the calculation to move closer to the requested framerate by setting a new frame grab deadline based on grab-date + duration + late (deadline miss). On a fast CPU it will not make much difference, but on a slow CPU the algorithm will grab frames based on FPS settings.
parent 62f3656b
...@@ -558,10 +558,9 @@ struct demux_sys_t ...@@ -558,10 +558,9 @@ struct demux_sys_t
int i_height; int i_height;
int i_pitch; int i_pitch;
float f_fps; /* <= 0.0 mean to grab at full rate */ float f_fps; /* <= 0.0 mean to grab at full rate */
mtime_t i_video_pts; /* only used when f_fps > 0 */
int i_fourcc; int i_fourcc;
mtime_t i_duration; /* frame duration calculation */ mtime_t i_duration; /* frame duration calculation */
mtime_t i_deadline; /* only used when f_fps > 0 */
es_out_id_t *p_es; es_out_id_t *p_es;
/* Tuner */ /* Tuner */
...@@ -696,7 +695,7 @@ static int DemuxOpen( vlc_object_t *p_this ) ...@@ -696,7 +695,7 @@ static int DemuxOpen( vlc_object_t *p_this )
*****************************************************************************/ *****************************************************************************/
static void GetV4L2Params( demux_sys_t *p_sys, vlc_object_t *p_obj ) static void GetV4L2Params( demux_sys_t *p_sys, vlc_object_t *p_obj )
{ {
p_sys->i_video_pts = -1; p_sys->i_deadline = -1;
p_sys->i_selected_standard_id = p_sys->i_selected_standard_id =
i_standards_list[var_CreateGetInteger( p_obj, "v4l2-standard" )]; i_standards_list[var_CreateGetInteger( p_obj, "v4l2-standard" )];
...@@ -1299,11 +1298,32 @@ static block_t* GrabVideo( demux_t *p_demux ) ...@@ -1299,11 +1298,32 @@ static block_t* GrabVideo( demux_t *p_demux )
struct v4l2_buffer buf; struct v4l2_buffer buf;
ssize_t i_ret; ssize_t i_ret;
if( p_sys->f_fps >= 0.1 && p_sys->i_video_pts > 0 ) if( p_sys->f_fps >= 0.1 && p_sys->i_deadline > 0 )
{ {
mtime_t now = mdate();
/* Did we wait long enough ? (frame rate reduction) */ /* Did we wait long enough ? (frame rate reduction) */
if( p_sys->i_video_pts + p_sys->i_duration > mdate() ) return NULL; if( p_sys->i_deadline > now )
return NULL;
/* Did we miss the deadline? */
mtime_t i_late = now - p_sys->i_deadline;
if( i_late > 0 )
{
if( i_late > ( now + p_sys->i_duration ) )
i_late = p_sys->i_duration;
p_sys->i_deadline = now + p_sys->i_duration - i_late;
}
else if( i_late < 0 )
{
if( i_late < p_sys->i_duration )
i_late = 0;
p_sys->i_deadline = now + p_sys->i_duration + i_late;
}
msg_Info( p_demux, "missed deadline by %"PRId64" microseconds", i_late );
} }
else if( p_sys->f_fps >= 0.1 && p_sys->i_deadline < 0 )
p_sys->i_deadline = mdate() + p_sys->i_duration;
/* Grab Video Frame */ /* Grab Video Frame */
switch( p_sys->io ) switch( p_sys->io )
...@@ -1427,7 +1447,7 @@ static block_t* GrabVideo( demux_t *p_demux ) ...@@ -1427,7 +1447,7 @@ static block_t* GrabVideo( demux_t *p_demux )
} }
/* Timestamp */ /* Timestamp */
p_sys->i_video_pts = p_block->i_pts = p_block->i_dts = mdate(); p_block->i_pts = p_block->i_dts = mdate();
return p_block; return p_block;
} }
......
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