[MPlayer-dev-eng] [PATCH] Detect and compensate pts reset in MPEG streams

Nico Sabbi nicola.sabbi at poste.it
Wed Oct 6 13:01:24 CEST 2010


Nicolas George ha scritto:
> Hi.
>
> The attached patch adds an option to detect and compensate pts resets often
> founds in MPEG streams from DVDs.
>
> At the very least, it allowed me to solve an A-V desync problem, see my
> message in mplayer-users yesterday.
>
> Regards,
>
>    
> mplayer-tsreset-20101005-1456.diff
>
>
> diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1
> index 3625a91..02bd7d6 100644
> --- a/DOCS/man/en/mplayer.1
> +++ b/DOCS/man/en/mplayer.1
> @@ -854,6 +854,15 @@ Without \-correct\-pts the subtitle timing will typically be off by some frames.
>   This option does not work correctly with some demuxers and codecs.
>   .
>   .TP
> +.B \-detect\-pts\-reset (EXPERIMENTAL)
> +In some type of streams, expecially DVDs near chapter marks, the timestamps
> +are reset to zero.
> +While not a problem per se, these resets can make other problems, most
> +notably A-V desync, harder to correct.
> +This option activate heuristics to detect and compensate these resets.
> +It is currently only implemented for the MPEG-PS demuxer.
> +.
> +.TP
>   .B \-crash\-debug (DEBUG CODE)
>   Automatically attaches gdb upon crash or SIGTRAP.
>   Support must be compiled in by configuring with \-\-enable\-crash\-debug.
> diff --git a/cfg-common.h b/cfg-common.h
> index e57d342..4e48ba1 100644
> --- a/cfg-common.h
> +++ b/cfg-common.h
> @@ -484,6 +484,10 @@ const m_option_t common_opts[] = {
>       // set A-V sync correction speed (0=disables it):
>       {"mc",&default_max_pts_correction, CONF_TYPE_FLOAT, CONF_RANGE, 0, 100, NULL},
>
> +    // detect and compensate PTS resets
> +    {  "detect-pts-reset",&detect_pts_reset, CONF_TYPE_FLAG, 0, 0, 1, NULL},
> +    {"nodetect-pts-reset",&detect_pts_reset, CONF_TYPE_FLAG, 0, 1, 0, NULL},
> +
>       // force video/audio rate:
>       {"fps",&force_fps, CONF_TYPE_DOUBLE, CONF_MIN, 0, 0, NULL},
>       {"srate",&force_srate, CONF_TYPE_INT, CONF_RANGE, 1000, 8*48000, NULL},
> diff --git a/libmpdemux/demux_mpg.c b/libmpdemux/demux_mpg.c
> index 849ee09..af30b27 100644
> --- a/libmpdemux/demux_mpg.c
> +++ b/libmpdemux/demux_mpg.c
> @@ -54,6 +54,7 @@ typedef struct mpg_demuxer {
>     float last_pts;
>     float first_pts;              // first pts found in stream
>     float first_to_final_pts_len; // difference between final pts and first pts
> +  float offset_pts;             // to compensate for pts resets
>     int has_valid_timestamps;     // !=0 iff time stamps look linear
>                                   // (not necessarily starting with 0)
>     unsigned int es_map[0x40];	//es map of stream types (associated to the pes id) from 0xb0 to 0xef
> @@ -294,6 +295,7 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
>     unsigned char c=0;
>     unsigned long long pts=0;
>     unsigned long long dts=0;
> +  float ptsf=0;
>     int l;
>     int pes_ext2_subid=-1;
>     double stream_pts = MP_NOPTS_VALUE;
> @@ -595,8 +597,20 @@ static int demux_mpg_read_packet(demuxer_t *demux,int id){
>       if(l<len)
>         resize_demux_packet(dp, l);
>       len = l;
> -    if(set_pts)
> -      dp->pts=pts/90000.0f;
> +    if(set_pts) {
> +      ptsf = pts / 90000.0f;
> +      if(detect_pts_reset&&  priv) {
> +        if(ptsf<  MAX_PTS_DIFF_FOR_CONSECUTIVE&&
> +           ptsf + priv->offset_pts<  priv->last_pts - MAX_PTS_DIFF_FOR_CONSECUTIVE) {
> +          priv->offset_pts = priv->last_pts;
> +          mp_msg(MSGT_DEMUX, MSGL_WARN,
> +                 "PTS reset detected, ajusting offset to %f.\n",
> +                 priv->offset_pts);
> +        }
> +        ptsf += priv->offset_pts;
> +      }
> +      dp->pts = ptsf;
> +    }
>    


why do you set it equal to the last pts found? Yes, it may be the 
closest approximation but still it's imprecise and lead
to some frame drop.
It's not the kind of code I'd like to see, but I see it may be useful, 
especially for mencoder.
Did you test it with some telecined or PAFF content?


More information about the MPlayer-dev-eng mailing list