Commit cf0633ae authored by David Flynn's avatar David Flynn Committed by Laurent Aimar

rawvideo: Fix timestamps & input options

demux:
 - Use accurate timestamps (date_t)
 - Signal frame rate in fmt_out
 - Fix aspect ratio for YUV4MPEG2
 - Reoganise input options to allow sensible overrides
   Ie: extension gussing < yuv4mpeg < cmdline

codec/packetizer:
 - Fix incorrect assumption of 25 fps video
 - Use accurate timestamps (date_t)
 - Copy input format as output format (to preserve frame rate)
 - Set progressive flag per picture

TODO:
 - Have module option for interlaced
 - Detect interlaced in demux for YUV4MPEG2
 - Have codec read set the interlaced flags in the video
 All seems rather tricky for the moment (well, YUV4MPEG2 bit does,
 since the demuxer strips the headers that reveal the interlace
 mode).
Signed-off-by: default avatarDavid Flynn <davidf@rd.bbc.co.uk>
Signed-off-by: default avatarLaurent Aimar <fenrir@videolan.org>
parent 038ff7b2
...@@ -50,8 +50,7 @@ struct decoder_sys_t ...@@ -50,8 +50,7 @@ struct decoder_sys_t
/* /*
* Common properties * Common properties
*/ */
mtime_t i_pts; date_t pts;
}; };
/**************************************************************************** /****************************************************************************
...@@ -135,7 +134,6 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -135,7 +134,6 @@ static int OpenDecoder( vlc_object_t *p_this )
return VLC_ENOMEM; return VLC_ENOMEM;
/* Misc init */ /* Misc init */
p_dec->p_sys->b_packetizer = false; p_dec->p_sys->b_packetizer = false;
p_sys->i_pts = 0;
p_sys->b_invert = 0; p_sys->b_invert = 0;
if( (int)p_dec->fmt_in.video.i_height < 0 ) if( (int)p_dec->fmt_in.video.i_height < 0 )
...@@ -153,6 +151,19 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -153,6 +151,19 @@ static int OpenDecoder( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
if( p_dec->fmt_out.video.i_frame_rate == 0 ||
p_dec->fmt_out.video.i_frame_rate_base == 0)
{
msg_Err( p_dec, "invalid frame rate %d/%d",
p_dec->fmt_out.video.i_frame_rate,
p_dec->fmt_out.video.i_frame_rate_base);
return VLC_EGENERIC;
}
date_Init( &p_sys->pts, p_dec->fmt_out.video.i_frame_rate,
p_dec->fmt_out.video.i_frame_rate_base);
/* Find out p_vdec->i_raw_size */ /* Find out p_vdec->i_raw_size */
vout_InitFormat( &p_dec->fmt_out.video, p_dec->fmt_in.i_codec, vout_InitFormat( &p_dec->fmt_out.video, p_dec->fmt_in.i_codec,
p_dec->fmt_in.video.i_width, p_dec->fmt_in.video.i_width,
...@@ -161,22 +172,11 @@ static int OpenDecoder( vlc_object_t *p_this ) ...@@ -161,22 +172,11 @@ static int OpenDecoder( vlc_object_t *p_this )
p_sys->i_raw_size = p_dec->fmt_out.video.i_bits_per_pixel * p_sys->i_raw_size = p_dec->fmt_out.video.i_bits_per_pixel *
p_dec->fmt_out.video.i_width * p_dec->fmt_out.video.i_height / 8; p_dec->fmt_out.video.i_width * p_dec->fmt_out.video.i_height / 8;
/* Set output properties */
p_dec->fmt_out.i_cat = VIDEO_ES;
p_dec->fmt_out.i_codec = p_dec->fmt_in.i_codec;
if( !p_dec->fmt_in.video.i_aspect ) if( !p_dec->fmt_in.video.i_aspect )
{ {
p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR *
p_dec->fmt_out.video.i_width / p_dec->fmt_out.video.i_height; p_dec->fmt_out.video.i_width / p_dec->fmt_out.video.i_height;
} }
else p_dec->fmt_out.video.i_aspect = p_dec->fmt_in.video.i_aspect;
if( p_dec->fmt_in.video.i_rmask )
p_dec->fmt_out.video.i_rmask = p_dec->fmt_in.video.i_rmask;
if( p_dec->fmt_in.video.i_gmask )
p_dec->fmt_out.video.i_gmask = p_dec->fmt_in.video.i_gmask;
if( p_dec->fmt_in.video.i_bmask )
p_dec->fmt_out.video.i_bmask = p_dec->fmt_in.video.i_bmask;
/* Set callbacks */ /* Set callbacks */
p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **)) p_dec->pf_decode_video = (picture_t *(*)(decoder_t *, block_t **))
...@@ -213,18 +213,25 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -213,18 +213,25 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_block = *pp_block; p_block = *pp_block;
if( !p_sys->i_pts && !p_block->i_pts && !p_block->i_dts ) if( (!p_block->i_pts || !p_block->i_dts) && !date_Get( &p_sys->pts ) )
{ {
/* We've just started the stream, wait for the first PTS. */ /* We've just started the stream, wait for the first PTS. */
block_Release( p_block ); block_Release( p_block );
return NULL; return NULL;
} }
/* Date management */ /* Date management: If there is a pts avaliable, use that. */
if( p_block->i_pts > 0 || p_block->i_dts > 0 ) if( p_block->i_pts )
{
date_Set( &p_sys->pts, p_block->i_pts );
}
else if( p_block->i_dts )
{ {
if( p_block->i_pts > 0 ) p_sys->i_pts = p_block->i_pts; /* NB, davidf doesn't quite agree with this in general, it is ok
else if( p_block->i_dts > 0 ) p_sys->i_pts = p_block->i_dts; * for rawvideo since it is in order (ie pts=dts), however, it
* may not be ok for an out-of-order codec, so don't copy this
* without thinking */
date_Set( &p_sys->pts, p_block->i_dts );
} }
if( p_block->i_buffer < p_sys->i_raw_size ) if( p_block->i_buffer < p_sys->i_raw_size )
...@@ -246,7 +253,7 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -246,7 +253,7 @@ static void *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
} }
/* Date management: 1 frame per packet */ /* Date management: 1 frame per packet */
p_sys->i_pts += ( INT64_C(1000000) * 1.0 / 25 /*FIXME*/ ); date_Increment( &p_sys->pts, 1 );
*pp_block = NULL; *pp_block = NULL;
return p_buf; return p_buf;
...@@ -298,7 +305,8 @@ static picture_t *DecodeFrame( decoder_t *p_dec, block_t *p_block ) ...@@ -298,7 +305,8 @@ static picture_t *DecodeFrame( decoder_t *p_dec, block_t *p_block )
FillPicture( p_dec, p_block, p_pic ); FillPicture( p_dec, p_block, p_pic );
p_pic->date = p_sys->i_pts; p_pic->date = date_Get( &p_sys->pts );
p_pic->b_progressive = true;
block_Release( p_block ); block_Release( p_block );
return p_pic; return p_pic;
...@@ -311,7 +319,7 @@ static block_t *SendFrame( decoder_t *p_dec, block_t *p_block ) ...@@ -311,7 +319,7 @@ static block_t *SendFrame( decoder_t *p_dec, block_t *p_block )
{ {
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
p_block->i_dts = p_block->i_pts = p_sys->i_pts; p_block->i_dts = p_block->i_pts = date_Get( &p_sys->pts );
if( p_sys->b_invert ) if( p_sys->b_invert )
{ {
......
This diff is collapsed.
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