[vlc-devel] [PATCH] demux: ts: support get length for non fastseekable

Zhao Zhili wantlamy at gmail.com
Thu Mar 17 16:06:05 CET 2016


ping?

On Thu, Mar 10, 2016 at 11:35 AM, Zhao Zhili <wantlamy at gmail.com> wrote:

> A new version is attached.
> ---
>  modules/demux/mpeg/ts.c     | 104
> ++++++++++++++++++++++++++------------------
>  modules/demux/mpeg/ts_psi.c |   2 +-
>  2 files changed, 62 insertions(+), 44 deletions(-)
>
> diff --git a/modules/demux/mpeg/ts.c b/modules/demux/mpeg/ts.c
> index f70844b..046cac5 100644
> --- a/modules/demux/mpeg/ts.c
> +++ b/modules/demux/mpeg/ts.c
> @@ -1844,19 +1844,29 @@ static int SeekToTime( demux_t *p_demux, const
> ts_pmt_t *p_pmt, int64_t i_scaled
>      return VLC_SUCCESS;
>  }
>
> -#define PROBE_CHUNK_COUNT 250
> -
> -static int ProbeChunk( demux_t *p_demux, int i_program, bool b_end,
> int64_t *pi_pcr, bool *pb_found )
> +typedef struct
> +{
> +    int i_program;
> +    bool b_end;
> +    mtime_t i_pcr;
> +    bool b_found;
> +    int i_packet_num;
> +} ts_probe_chunk_t;
> +
> +static int ProbeChunk( demux_t *p_demux, ts_probe_chunk_t *p_chunk_info )
>  {
>      demux_sys_t *p_sys = p_demux->p_sys;
>      int i_count = 0;
>      block_t *p_pkt = NULL;
> +    int i_packet_max = p_chunk_info->i_packet_num;
> +    int i_program = p_chunk_info->i_program;
> +    mtime_t i_pcr;
>
>      for( ;; )
>      {
> -        *pi_pcr = -1;
> +        i_pcr = -1;
>
> -        if( i_count++ > PROBE_CHUNK_COUNT || !( p_pkt = ReadTSPacket(
> p_demux ) ) )
> +        if( i_count++ > i_packet_max || !( p_pkt = ReadTSPacket( p_demux
> ) ) )
>          {
>              break;
>          }
> @@ -1872,9 +1882,9 @@ static int ProbeChunk( demux_t *p_demux, int
> i_program, bool b_end, int64_t *pi_
>              bool b_adaptfield = p_pkt->p_buffer[3] & 0x20;
>
>              if( b_adaptfield && p_pkt->i_buffer >= 4 + 2 + 5 )
> -                *pi_pcr = GetPCR( p_pkt );
> +                i_pcr = GetPCR( p_pkt );
>
> -            if( *pi_pcr == -1 &&
> +            if( i_pcr == -1 &&
>                  (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* payload start */
>                  (p_pkt->p_buffer[3] & 0xD0) == 0x10 && /* Has payload but
> is not encrypted */
>                  p_pid->type == TYPE_PES &&
> @@ -1894,13 +1904,13 @@ static int ProbeChunk( demux_t *p_demux, int
> i_program, bool b_end, int64_t *pi_
>                                                      &i_dts, &i_pts,
> &i_stream_id ) )
>                  {
>                      if( i_dts != -1 )
> -                        *pi_pcr = i_dts;
> +                        i_pcr = i_dts;
>                      else if( i_pts != -1 )
> -                        *pi_pcr = i_pts;
> +                        i_pcr = i_pts;
>                  }
>              }
>
> -            if( *pi_pcr != -1 )
> +            if( i_pcr != -1 )
>              {
>                  ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
>                  for( int i=0; i<p_pat->programs.i_size; i++ )
> @@ -1911,22 +1921,22 @@ static int ProbeChunk( demux_t *p_demux, int
> i_program, bool b_end, int64_t *pi_
>                              PIDReferencedByProgram( p_pmt, p_pid->i_pid )
> )
>                        )
>                      {
> -                        if( b_end )
> +                        if( p_chunk_info->b_end )
>                          {
> -                            p_pmt->i_last_dts = *pi_pcr;
> +                            p_pmt->i_last_dts = i_pcr;
>                          }
>                          /* Start, only keep first */
>                          else if( b_pcrresult && p_pmt->pcr.i_first == -1 )
>                          {
> -                            p_pmt->pcr.i_first = *pi_pcr;
> +                            p_pmt->pcr.i_first = i_pcr;
>                          }
>                          else if( p_pmt->pcr.i_first_dts < VLC_TS_0 )
>                          {
> -                            p_pmt->pcr.i_first_dts = FROM_SCALE(*pi_pcr);
> +                            p_pmt->pcr.i_first_dts = FROM_SCALE(i_pcr);
>                          }
>
>                          if( i_program == 0 || i_program ==
> p_pmt->i_number )
> -                            *pb_found = true;
> +                            p_chunk_info->b_found = true;
>                      }
>                  }
>              }
> @@ -1935,6 +1945,8 @@ static int ProbeChunk( demux_t *p_demux, int
> i_program, bool b_end, int64_t *pi_
>          block_Release( p_pkt );
>      }
>
> +    p_chunk_info->i_pcr = i_pcr;
> +
>      return i_count;
>  }
>
> @@ -1942,31 +1954,23 @@ int ProbeStart( demux_t *p_demux, int i_program )
>  {
>      demux_sys_t *p_sys = p_demux->p_sys;
>      const int64_t i_initial_pos = stream_Tell( p_sys->stream );
> -    int64_t i_stream_size = stream_Size( p_sys->stream );
> -
> -    int i_probe_count = 0;
> -    int64_t i_pos;
> -    mtime_t i_pcr = -1;
> -    bool b_found = false;
> -
> -    do
> -    {
> -        i_pos = p_sys->i_packet_size * i_probe_count;
> -        i_pos = __MIN( i_pos, i_stream_size );
> -
> -        if( stream_Seek( p_sys->stream, i_pos ) )
> -            return VLC_EGENERIC;
> -
> -        ProbeChunk( p_demux, i_program, false, &i_pcr, &b_found );
> +    ts_probe_chunk_t chunk_info = {
> +        .i_program = i_program,
> +        .b_end = false,
> +        .i_pcr = -1,
> +        .b_found = false,
> +        .i_packet_num = 500,
> +    };
> +
> +    if( stream_Seek( p_sys->stream, 0 ) )
> +        return VLC_EGENERIC;
>
> -        /* Go ahead one more chunk if end of file contained only stuffing
> packets */
> -        i_probe_count += PROBE_CHUNK_COUNT;
> -    } while( i_pos > 0 && (i_pcr == -1 || !b_found) && i_probe_count < (2
> * PROBE_CHUNK_COUNT) );
> +    ProbeChunk( p_demux, &chunk_info );
>
>      if( stream_Seek( p_sys->stream, i_initial_pos ) )
>          return VLC_EGENERIC;
>
> -    return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
> +    return (chunk_info.b_found) ? VLC_SUCCESS : VLC_EGENERIC;
>  }
>
>  int ProbeEnd( demux_t *p_demux, int i_program )
> @@ -1975,11 +1979,23 @@ int ProbeEnd( demux_t *p_demux, int i_program )
>      const int64_t i_initial_pos = stream_Tell( p_sys->stream );
>      int64_t i_stream_size = stream_Size( p_sys->stream );
>
> -    int i_probe_count = PROBE_CHUNK_COUNT;
>      int64_t i_pos;
> -    mtime_t i_pcr = -1;
> -    bool b_found = false;
> -
> +    int i_probe_count, i_probe_max;
> +    ts_probe_chunk_t chunk_info = {
> +        .i_program = i_program,
> +        .b_end = true,
> +        .i_pcr = -1,
> +        .b_found = false,
> +        .i_packet_num = 250,
> +    };
> +
> +    i_probe_max = 5 * chunk_info.i_packet_num;
> +
> +    /* Probe a single big chunk for non fastseekable */
> +    if ( p_sys->b_canfastseek == false )
> +        chunk_info.i_packet_num = i_probe_max;
> +
> +    i_probe_count = chunk_info.i_packet_num;
>      do
>      {
>          i_pos = i_stream_size - (p_sys->i_packet_size * i_probe_count);
> @@ -1988,16 +2004,18 @@ int ProbeEnd( demux_t *p_demux, int i_program )
>          if( stream_Seek( p_sys->stream, i_pos ) )
>              return VLC_EGENERIC;
>
> -        ProbeChunk( p_demux, i_program, true, &i_pcr, &b_found );
> +        ProbeChunk( p_demux, &chunk_info );
>
>          /* Go ahead one more chunk if end of file contained only stuffing
> packets */
> -        i_probe_count += PROBE_CHUNK_COUNT;
> -    } while( i_pos > 0 && (i_pcr == -1 || !b_found) && i_probe_count < (6
> * PROBE_CHUNK_COUNT) );
> +        i_probe_count += chunk_info.i_packet_num;
> +    } while( i_pos > 0 &&
> +            (chunk_info.i_pcr == -1 || chunk_info.b_found == false) &&
> +            i_probe_count <= i_probe_max );
>
>      if( stream_Seek( p_sys->stream, i_initial_pos ) )
>          return VLC_EGENERIC;
>
> -    return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
> +    return (chunk_info.b_found) ? VLC_SUCCESS : VLC_EGENERIC;
>  }
>
>  static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t
> i_pcr )
> diff --git a/modules/demux/mpeg/ts_psi.c b/modules/demux/mpeg/ts_psi.c
> index ac14b79..05623ac 100644
> --- a/modules/demux/mpeg/ts_psi.c
> +++ b/modules/demux/mpeg/ts_psi.c
> @@ -1714,7 +1714,7 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t
> *p_dvbpsipmt )
>      }
>
>      /* Probe Boundaries */
> -    if( p_sys->b_canfastseek && p_pmt->i_last_dts == -1 )
> +    if( p_sys->b_canseek && p_pmt->i_last_dts == -1 )
>      {
>          p_pmt->i_last_dts = 0;
>          ProbeStart( p_demux, p_pmt->i_number );
> --
> 1.9.1
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20160317/b5c4e1e9/attachment.html>


More information about the vlc-devel mailing list