[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