[vlc-devel] [PATCH] fixed .ts file open issue

Olivier Gass 0l1v1312.6455 at gmail.com
Sat Mar 19 01:10:34 CET 2011


.ts file open did not work ( "TS module discarded (lost sync)" )
when first 0x47 byte of the file was not a sync byte.
Test files available here:
http://www.neufgiga.com/n/50-17/share/LNK84694d8296101aba4/
---
 modules/demux/ts.c |  188 ++++++++++++++++++----------------------------------
 1 files changed, 65 insertions(+), 123 deletions(-)

diff --git a/modules/demux/ts.c b/modules/demux/ts.c
index 4c209f2..9993c62 100644
--- a/modules/demux/ts.c
+++ b/modules/demux/ts.c
@@ -427,138 +427,80 @@ static int Open( vlc_object_t *p_this )
     ts_pid_t    *pat;
     const char  *psz_mode;
     bool         b_append;
-    bool         b_topfield = false;
 
-    if( stream_Peek( p_demux->s, &p_peek, TS_PACKET_SIZE_MAX ) <
-        TS_PACKET_SIZE_MAX ) return VLC_EGENERIC;
 
-    if( memcmp( p_peek, "TFrc", 4 ) == 0 )
-    {
-        b_topfield = true;
-        msg_Dbg( p_demux, "this is a topfield file" );
-    }
-
-    /* Search first sync byte */
-    for( i_sync = 0; i_sync < TS_PACKET_SIZE_MAX; i_sync++ )
-    {
-        if( p_peek[i_sync] == 0x47 ) break;
-    }
-    if( i_sync >= TS_PACKET_SIZE_MAX && !b_topfield )
-    {
-        if( !p_demux->b_force )
-            return VLC_EGENERIC;
-        msg_Warn( p_demux, "this does not look like a TS stream, continuing" );
-    }
-
-    if( b_topfield )
-    {
-        /* Read the entire Topfield header */
-        i_peek = TS_TOPFIELD_HEADER;
-    }
-    else
-    {
-        /* Check next 3 sync bytes */
-        i_peek = TS_PACKET_SIZE_MAX * 3 + i_sync + 1;
-    }
+    i_peek = 4*TS_PACKET_SIZE_MAX;
 
-    if( ( stream_Peek( p_demux->s, &p_peek, i_peek ) ) < i_peek )
-    {
-        msg_Err( p_demux, "cannot peek" );
+    if( stream_Peek( p_demux->s, &p_peek, i_peek ) < i_peek )
         return VLC_EGENERIC;
-    }
-    if( p_peek[i_sync + TS_PACKET_SIZE_188] == 0x47 &&
-        p_peek[i_sync + 2 * TS_PACKET_SIZE_188] == 0x47 &&
-        p_peek[i_sync + 3 * TS_PACKET_SIZE_188] == 0x47 )
-    {
-        i_packet_size = TS_PACKET_SIZE_188;
-    }
-    else if( p_peek[i_sync + TS_PACKET_SIZE_192] == 0x47 &&
-             p_peek[i_sync + 2 * TS_PACKET_SIZE_192] == 0x47 &&
-             p_peek[i_sync + 3 * TS_PACKET_SIZE_192] == 0x47 )
-    {
-        i_packet_size = TS_PACKET_SIZE_192;
-    }
-    else if( p_peek[i_sync + TS_PACKET_SIZE_204] == 0x47 &&
-             p_peek[i_sync + 2 * TS_PACKET_SIZE_204] == 0x47 &&
-             p_peek[i_sync + 3 * TS_PACKET_SIZE_204] == 0x47 )
-    {
-        i_packet_size = TS_PACKET_SIZE_204;
-    }
-    else if( p_demux->b_force )
-    {
-        i_packet_size = TS_PACKET_SIZE_188;
-    }
-    else if( b_topfield )
+
+    if( memcmp( p_peek, "TFrc", 4 ) == 0 )
     {
+        /* Topfield header
+        TBD: skip header then check sync bytes presence and packet size.
+        For now, we assume sync bytes are present and packet size is 188.
+        Fortunately, this seems to work well enough, as demux re-sync process
+        automatically eliminates the 'garbage' (topfield header, in our case) */
         i_packet_size = TS_PACKET_SIZE_188;
-#if 0
-        /* I used the TF5000PVR 2004 Firmware .doc header documentation,
-         * http://www.i-topfield.com/data/product/firmware/Structure%20of%20Recorded%20File%20in%20TF5000PVR%20(Feb%2021%202004).doc
-         * but after the filename the offsets seem to be incorrect.  - DJ */
-        int i_duration, i_name;
-        char *psz_name = malloc(25);
-        char *psz_event_name;
-        char *psz_event_text = malloc(130);
-        char *psz_ext_text = malloc(1025);
-
-        // 2 bytes version Uimsbf (4,5)
-        // 2 bytes reserved (6,7)
-        // 2 bytes duration in minutes Uimsbf (8,9(
-        i_duration = (int) (p_peek[8] << 8) | p_peek[9];
-        msg_Dbg( p_demux, "Topfield recording length: +/- %d minutes", i_duration);
-        // 2 bytes service number in channel list (10, 11)
-        // 2 bytes service type Bslbf 0=TV 1=Radio Bslb (12, 13)
-        // 4 bytes of reserved + tuner info (14,15,16,17)
-        // 2 bytes of Service ID  Bslbf (18,19)
-        // 2 bytes of PMT PID  Uimsbf (20,21)
-        // 2 bytes of PCR PID  Uimsbf (22,23)
-        // 2 bytes of Video PID  Uimsbf (24,25)
-        // 2 bytes of Audio PID  Uimsbf (26,27)
-        // 24 bytes filename Bslbf
-        memcpy( psz_name, &p_peek[28], 24 );
-        psz_name[24] = '\0';
-        msg_Dbg( p_demux, "recordingname=%s", psz_name );
-        // 1 byte of sat index Uimsbf  (52)
-        // 3 bytes (1 bit of polarity Bslbf +23 bits reserved)
-        // 4 bytes of freq. Uimsbf (56,57,58,59)
-        // 2 bytes of symbol rate Uimsbf (60,61)
-        // 2 bytes of TS stream ID Uimsbf (62,63)
-        // 4 bytes reserved
-        // 2 bytes reserved
-        // 2 bytes duration Uimsbf (70,71)
-        //i_duration = (int) (p_peek[70] << 8) | p_peek[71];
-        //msg_Dbg( p_demux, "Topfield 2nd duration field: +/- %d minutes", i_duration);
-        // 4 bytes EventID Uimsbf (72-75)
-        // 8 bytes of Start and End time info (76-83)
-        // 1 byte reserved (84)
-        // 1 byte event name length Uimsbf (89)
-        i_name = (int)(p_peek[89]&~0x81);
-        msg_Dbg( p_demux, "event name length = %d", i_name);
-        psz_event_name = malloc( i_name+1 );
-        // 1 byte parental rating (90)
-        // 129 bytes of event text
-        memcpy( psz_event_name, &p_peek[91], i_name );
-        psz_event_name[i_name] = '\0';
-        memcpy( psz_event_text, &p_peek[91+i_name], 129-i_name );
-        psz_event_text[129-i_name] = '\0';
-        msg_Dbg( p_demux, "event name=%s", psz_event_name );
-        msg_Dbg( p_demux, "event text=%s", psz_event_text );
-        // 12 bytes reserved (220)
-        // 6 bytes reserved
-        // 2 bytes Event Text Length Uimsbf
-        // 4 bytes EventID Uimsbf
-        // FIXME We just have 613 bytes. not enough for this entire text
-        // 1024 bytes Extended Event Text Bslbf
-        memcpy( psz_ext_text, p_peek+372, 1024 );
-        psz_ext_text[1024] = '\0';
-        msg_Dbg( p_demux, "extended event text=%s", psz_ext_text );
-        // 52 bytes reserved Bslbf
-#endif
+        msg_Warn( p_demux, "this is a topfield file" );
     }
     else
     {
-        msg_Warn( p_demux, "TS module discarded (lost sync)" );
-        return VLC_EGENERIC;
+        /* Find Sync bytes
+        One or more 0x47 bytes may be present in the first TS_PACKET_SIZE_MAX
+        bytes. Each one is checked in turn, until packet size can be
+        determined with certainty. */
+
+        i_sync = 0;
+        i_packet_size = 0;
+
+        while( !i_packet_size && ( i_sync < TS_PACKET_SIZE_MAX ) )
+        {
+            for( ; i_sync < TS_PACKET_SIZE_MAX; i_sync++ )
+            {
+                if( p_peek[i_sync] == 0x47 ) break;
+            }
+
+            if( i_sync < TS_PACKET_SIZE_MAX )
+            {
+                if( p_peek[i_sync + TS_PACKET_SIZE_188] == 0x47 &&
+                    p_peek[i_sync + 2 * TS_PACKET_SIZE_188] == 0x47 &&
+                    p_peek[i_sync + 3 * TS_PACKET_SIZE_188] == 0x47 )
+                {
+                    i_packet_size = TS_PACKET_SIZE_188;
+                }
+                else if( p_peek[i_sync + TS_PACKET_SIZE_192] == 0x47 &&
+                         p_peek[i_sync + 2 * TS_PACKET_SIZE_192] == 0x47 &&
+                         p_peek[i_sync + 3 * TS_PACKET_SIZE_192] == 0x47 )
+                {
+                    i_packet_size = TS_PACKET_SIZE_192;
+                }
+                else if( p_peek[i_sync + TS_PACKET_SIZE_204] == 0x47 &&
+                         p_peek[i_sync + 2 * TS_PACKET_SIZE_204] == 0x47 &&
+                         p_peek[i_sync + 3 * TS_PACKET_SIZE_204] == 0x47 )
+                {
+                    i_packet_size = TS_PACKET_SIZE_204;
+                }
+
+                if( !i_packet_size ) ++i_sync;
+            }
+
+        }
+
+        if( !i_packet_size )
+        {
+            if( !p_demux->b_force )
+            {
+                msg_Warn( p_demux, "TS module discarded (lost sync)" );
+                return VLC_EGENERIC;
+            }
+            else
+            {
+                i_packet_size = TS_PACKET_SIZE_188;
+                msg_Warn( p_demux, "this does not look like a TS stream, continuing" );
+            }
+        }
+
     }
 
     p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
-- 
1.7.2.3




More information about the vlc-devel mailing list