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

Zhao Zhili wantlamy at gmail.com
Thu Mar 10 04:35:39 CET 2016


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/20160310/a2681248/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-demux-ts-support-get-length-for-non-fastseekable.patch
Type: text/x-patch
Size: 8095 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20160310/a2681248/attachment.bin>


More information about the vlc-devel mailing list