]> git.sesse.net Git - vlc/blobdiff - modules/demux/ts.c
demux: dash: rename startIndex -> startNumber
[vlc] / modules / demux / ts.c
index 10c08faa38747dd463529838e31fb11faeb95c13..14736b1ced90de08fb0b6cfba05ad7f85c8ce199 100644 (file)
@@ -307,6 +307,8 @@ typedef struct
 
 struct demux_sys_t
 {
+    stream_t   *stream;
+    bool        b_canseek;
     vlc_mutex_t     csa_lock;
 
     /* TS packet size (188, 192, 204) */
@@ -334,6 +336,7 @@ struct demux_sys_t
 #ifdef HAVE_ARIBB24
         arib_instance_t *p_instance;
 #endif
+        stream_t     *b25stream;
     } arib;
 
     /* All pid */
@@ -620,6 +623,9 @@ static int Open( vlc_object_t *p_this )
     p_sys->i_dvb_start = 0;
     p_sys->i_dvb_length = 0;
 
+    p_sys->arib.b25stream = NULL;
+    p_sys->stream = p_demux->s;
+
     p_sys->b_broken_charset = false;
 
     for( int i = 0; i < 8192; i++ )
@@ -789,6 +795,7 @@ static int Open( vlc_object_t *p_this )
 
     p_sys->b_split_es = var_InheritBool( p_demux, "ts-split-es" );
 
+    p_sys->b_canseek = false;
     p_sys->i_pid_ref_pcr = -1;
     p_sys->i_first_pcr = -1;
     p_sys->i_current_pcr = -1;
@@ -806,18 +813,23 @@ static int Open( vlc_object_t *p_this )
         return VLC_ENOMEM;
     }
 
-    bool can_seek = false;
-    stream_Control( p_demux->s, STREAM_CAN_FASTSEEK, &can_seek );
-    if( can_seek  )
-    {
-        GetFirstPCR( p_demux );
-        CheckPCR( p_demux );
-        GetLastPCR( p_demux );
-    }
-    if( p_sys->i_first_pcr < 0 || p_sys->i_last_pcr < 0 )
+    bool b_can_fastseek = false;
+    stream_Control( p_sys->stream, STREAM_CAN_SEEK, &p_sys->b_canseek );
+    stream_Control( p_sys->stream, STREAM_CAN_FASTSEEK, &b_can_fastseek );
+    if ( p_sys->b_canseek )
     {
-        msg_Dbg( p_demux, "Force Seek Per Percent: PCR's not found,");
-        p_sys->b_force_seek_per_percent = true;
+        if( b_can_fastseek )
+        {
+            GetFirstPCR( p_demux );
+            CheckPCR( p_demux );
+            GetLastPCR( p_demux );
+        }
+
+        if( p_sys->i_first_pcr < 0 || p_sys->i_last_pcr < 0 )
+        {
+            msg_Dbg( p_demux, "Force Seek Per Percent: PCR's not found,");
+            p_sys->b_force_seek_per_percent = true;
+        }
     }
 
     while( p_sys->i_pmt_es <= 0 && vlc_object_alive( p_demux ) )
@@ -913,6 +925,12 @@ static void Close( vlc_object_t *p_this )
         arib_instance_destroy( p_sys->arib.p_instance );
 #endif
 
+    if ( p_sys->arib.b25stream )
+    {
+        p_sys->arib.b25stream->p_source = NULL; /* don't chain kill demuxer's source */
+        stream_Delete( p_sys->arib.b25stream );
+    }
+
     vlc_mutex_destroy( &p_sys->csa_lock );
     free( p_sys );
 }
@@ -960,7 +978,7 @@ static int Demux( demux_t *p_demux )
         if( p_sys->b_start_record )
         {
             /* Enable recording once synchronized */
-            stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, true, "ts" );
+            stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE, true, "ts" );
             p_sys->b_start_record = false;
         }
 
@@ -1059,9 +1077,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             int64_t i_time, i_length;
             if( !DVBEventInformation( p_demux, &i_time, &i_length ) && i_length > 0 )
                 *pf = (double)i_time/(double)i_length;
-            else if( (i64 = stream_Size( p_demux->s) ) > 0 )
+            else if( (i64 = stream_Size( p_sys->stream) ) > 0 )
             {
-                int64_t offset = stream_Tell( p_demux->s );
+                int64_t offset = stream_Tell( p_sys->stream );
 
                 *pf = (double)offset / (double)i64;
             }
@@ -1077,12 +1095,15 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     case DEMUX_SET_POSITION:
         f = (double) va_arg( args, double );
 
+        if(!p_sys->b_canseek)
+            return VLC_EGENERIC;
+
         if( p_sys->b_force_seek_per_percent ||
             (p_sys->b_dvb_meta && p_sys->b_access_control) ||
             p_sys->i_last_pcr - p_sys->i_first_pcr <= 0 )
         {
-            i64 = stream_Size( p_demux->s );
-            if( stream_Seek( p_demux->s, (int64_t)(i64 * f) ) )
+            i64 = stream_Size( p_sys->stream );
+            if( stream_Seek( p_sys->stream, (int64_t)(i64 * f) ) )
                 return VLC_EGENERIC;
         }
         else
@@ -1188,17 +1209,17 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
 
         *va_arg( args, int* ) = 0; /* Title offset */
         *va_arg( args, int* ) = 0; /* Chapter offset */
-        return stream_Control( p_demux->s, STREAM_GET_TITLE_INFO, v, c );
+        return stream_Control( p_sys->stream, STREAM_GET_TITLE_INFO, v, c );
     }
 
     case DEMUX_SET_TITLE:
-        return stream_vaControl( p_demux->s, STREAM_SET_TITLE, args );
+        return stream_vaControl( p_sys->stream, STREAM_SET_TITLE, args );
 
     case DEMUX_SET_SEEKPOINT:
-        return stream_vaControl( p_demux->s, STREAM_SET_SEEKPOINT, args );
+        return stream_vaControl( p_sys->stream, STREAM_SET_SEEKPOINT, args );
 
     case DEMUX_GET_META:
-        return stream_vaControl( p_demux->s, STREAM_GET_META, args );
+        return stream_vaControl( p_sys->stream, STREAM_GET_META, args );
 
     case DEMUX_CAN_RECORD:
         pb_bool = (bool*)va_arg( args, bool * );
@@ -1209,12 +1230,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
         b_bool = (bool)va_arg( args, int );
 
         if( !b_bool )
-            stream_Control( p_demux->s, STREAM_SET_RECORD_STATE, false );
+            stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE, false );
         p_sys->b_start_record = b_bool;
         return VLC_SUCCESS;
 
     case DEMUX_GET_SIGNAL:
-        return stream_vaControl( p_demux->s, STREAM_GET_SIGNAL, args );
+        return stream_vaControl( p_sys->stream, STREAM_GET_SIGNAL, args );
 
     default:
         return VLC_EGENERIC;
@@ -1371,7 +1392,7 @@ static int SetPIDFilter( demux_t *p_demux, int i_pid, bool b_selected )
     if( !p_sys->b_access_control )
         return VLC_EGENERIC;
 
-    return stream_Control( p_demux->s, STREAM_SET_PRIVATE_ID_STATE,
+    return stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_STATE,
                            i_pid, b_selected );
 }
 
@@ -1895,9 +1916,9 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
                         block_Duplicate( p_block ) );
             }
 
-            if (!p_sys->b_trust_pcr)
+            if (!p_sys->b_trust_pcr && p_block->i_dts > VLC_TS_INVALID )
                 es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
-                        pid->i_owner_number, p_block->i_pts);
+                        pid->i_owner_number, p_block->i_dts);
 
             es_out_Send( p_demux->out, pid->es->id, p_block );
 
@@ -1989,7 +2010,7 @@ static block_t* ReadTSPacket( demux_t *p_demux )
     block_t     *p_pkt;
 
     /* Get a new TS packet */
-    if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
+    if( !( p_pkt = stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
     {
         msg_Dbg( p_demux, "eof ?" );
         return NULL;
@@ -2012,7 +2033,7 @@ static block_t* ReadTSPacket( demux_t *p_demux )
             const uint8_t *p_peek;
             int i_peek, i_skip = 0;
 
-            i_peek = stream_Peek( p_demux->s, &p_peek,
+            i_peek = stream_Peek( p_sys->stream, &p_peek,
                     p_sys->i_packet_size * 10 );
             if( i_peek < p_sys->i_packet_size + 1 )
             {
@@ -2030,14 +2051,14 @@ static block_t* ReadTSPacket( demux_t *p_demux )
                 i_skip++;
             }
             msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );
-            stream_Read( p_demux->s, NULL, i_skip );
+            stream_Read( p_sys->stream, NULL, i_skip );
 
             if( i_skip < i_peek - p_sys->i_packet_size )
             {
                 break;
             }
         }
-        if( !( p_pkt = stream_Block( p_demux->s, p_sys->i_packet_size ) ) )
+        if( !( p_pkt = stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
         {
             msg_Dbg( p_demux, "eof ?" );
             return NULL;
@@ -2054,7 +2075,7 @@ static mtime_t AdjustPCRWrapAround( demux_t *p_demux, mtime_t i_pcr )
      * So, need to add 0x1FFFFFFFF, for calculating duration or current position.
      */
     mtime_t i_adjust = 0;
-    int64_t i_pos = stream_Tell( p_demux->s );
+    int64_t i_pos = stream_Tell( p_sys->stream );
     int i;
     for( i = 1; i < p_sys->i_pcrs_num && p_sys->p_pos[i] <= i_pos; ++i )
     {
@@ -2092,16 +2113,16 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos )
     demux_sys_t *p_sys = p_demux->p_sys;
 
     mtime_t i_pcr = -1;
-    const int64_t i_initial_pos = stream_Tell( p_demux->s );
+    const int64_t i_initial_pos = stream_Tell( p_sys->stream );
 
     if( i_pos < 0 )
         return VLC_EGENERIC;
 
-    int64_t i_last_pos = stream_Size( p_demux->s ) - p_sys->i_packet_size;
+    int64_t i_last_pos = stream_Size( p_sys->stream ) - p_sys->i_packet_size;
     if( i_pos > i_last_pos )
         i_pos = i_last_pos;
 
-    if( stream_Seek( p_demux->s, i_pos ) )
+    if( stream_Seek( p_sys->stream, i_pos ) )
         return VLC_EGENERIC;
 
     while( vlc_object_alive( p_demux ) )
@@ -2119,13 +2140,13 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos )
         block_Release( p_pkt );
         if( i_pcr >= 0 )
             break;
-        if( stream_Tell( p_demux->s ) >= i_last_pos )
+        if( stream_Tell( p_sys->stream ) >= i_last_pos )
             break;
     }
     if( i_pcr < 0 )
     {
-        stream_Seek( p_demux->s, i_initial_pos );
-        assert( i_initial_pos == stream_Tell( p_demux->s ) );
+        stream_Seek( p_sys->stream, i_initial_pos );
+        assert( i_initial_pos == stream_Tell( p_sys->stream ) );
         return VLC_EGENERIC;
     }
 
@@ -2137,7 +2158,7 @@ static int Seek( demux_t *p_demux, double f_percent )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
 
-    int64_t i_initial_pos = stream_Tell( p_demux->s );
+    int64_t i_initial_pos = stream_Tell( p_sys->stream );
     mtime_t i_initial_pcr = p_sys->i_current_pcr;
 
     /*
@@ -2158,7 +2179,7 @@ static int Seek( demux_t *p_demux, double f_percent )
                 break;
         }
         i_head_pos = p_sys->p_pos[i-1];
-        i_tail_pos = ( i < p_sys->i_pcrs_num ) ?  p_sys->p_pos[i] : stream_Size( p_demux->s );
+        i_tail_pos = ( i < p_sys->i_pcrs_num ) ?  p_sys->p_pos[i] : stream_Size( p_sys->stream );
     }
     msg_Dbg( p_demux, "Seek():i_head_pos:%"PRId64", i_tail_pos:%"PRId64, i_head_pos, i_tail_pos);
 
@@ -2193,7 +2214,7 @@ static int Seek( demux_t *p_demux, double f_percent )
     if( !b_found )
     {
         msg_Dbg( p_demux, "Seek():cannot find a time position. i_cnt:%d", i_cnt );
-        stream_Seek( p_demux->s, i_initial_pos );
+        stream_Seek( p_sys->stream, i_initial_pos );
         p_sys->i_current_pcr = i_initial_pcr;
         return VLC_EGENERIC;
     }
@@ -2208,9 +2229,9 @@ static void GetFirstPCR( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
 
-    int64_t i_initial_pos = stream_Tell( p_demux->s );
+    int64_t i_initial_pos = stream_Tell( p_sys->stream );
 
-    if( stream_Seek( p_demux->s, 0 ) )
+    if( stream_Seek( p_sys->stream, 0 ) )
         return;
 
     while( vlc_object_alive (p_demux) )
@@ -2232,17 +2253,17 @@ static void GetFirstPCR( demux_t *p_demux )
         if( p_sys->i_first_pcr >= 0 )
             break;
     }
-    stream_Seek( p_demux->s, i_initial_pos );
+    stream_Seek( p_sys->stream, i_initial_pos );
 }
 
 static void GetLastPCR( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
 
-    const int64_t i_initial_pos = stream_Tell( p_demux->s );
+    const int64_t i_initial_pos = stream_Tell( p_sys->stream );
     mtime_t i_initial_pcr = p_sys->i_current_pcr;
 
-    int64_t i_stream_size = stream_Size( p_demux->s );
+    int64_t i_stream_size = stream_Size( p_sys->stream );
     int64_t i_last_pos = i_stream_size - p_sys->i_packet_size;
     /* Round i_pos to a multiple of p_sys->i_packet_size */
     int64_t i_pos = i_last_pos - p_sys->i_packet_size * 4500; /* FIXME if the value is not reasonable, please change it. */
@@ -2259,12 +2280,12 @@ static void GetLastPCR( demux_t *p_demux )
         if( SeekToPCR( p_demux, i_pos ) )
             break;
         p_sys->i_last_pcr = AdjustPCRWrapAround( p_demux, p_sys->i_current_pcr );
-        if( ( i_pos = stream_Tell( p_demux->s ) ) >= i_last_pos )
+        if( ( i_pos = stream_Tell( p_sys->stream ) ) >= i_last_pos )
             break;
     }
     if( p_sys->i_last_pcr >= 0 )
     {
-        int64_t i_size = stream_Size( p_demux->s );
+        int64_t i_size = stream_Size( p_sys->stream );
         mtime_t i_duration_msec = ( p_sys->i_last_pcr - p_sys->i_first_pcr ) * 100 / 9 / 1000;
         int64_t i_rate = ( i_size < 0 || i_duration_msec <= 0 ) ? 0 : i_size * 1000 * 8 / i_duration_msec;
         const int64_t TS_SUPPOSED_MAXRATE = 55 * 1000 * 1000; //FIXME I think it's enough.
@@ -2276,8 +2297,8 @@ static void GetLastPCR( demux_t *p_demux )
             p_sys->i_last_pcr = -1;
         }
     }
-    stream_Seek( p_demux->s, i_initial_pos );
-    assert( i_initial_pos == stream_Tell( p_demux->s ) );
+    stream_Seek( p_sys->stream, i_initial_pos );
+    assert( i_initial_pos == stream_Tell( p_sys->stream ) );
     p_sys->i_current_pcr = i_initial_pcr;
 }
 
@@ -2285,10 +2306,10 @@ static void CheckPCR( demux_t *p_demux )
 {
     demux_sys_t   *p_sys = p_demux->p_sys;
 
-    int64_t i_initial_pos = stream_Tell( p_demux->s );
+    int64_t i_initial_pos = stream_Tell( p_sys->stream );
     mtime_t i_initial_pcr = p_sys->i_current_pcr;
 
-    int64_t i_size = stream_Size( p_demux->s );
+    int64_t i_size = stream_Size( p_sys->stream );
 
     int i = 0;
     p_sys->p_pcrs[0] = p_sys->i_first_pcr;
@@ -2303,7 +2324,7 @@ static void CheckPCR( demux_t *p_demux )
         if( SeekToPCR( p_demux, i_pos ) )
             break;
         p_sys->p_pcrs[i] = p_sys->i_current_pcr;
-        p_sys->p_pos[i] = stream_Tell( p_demux->s );
+        p_sys->p_pos[i] = stream_Tell( p_sys->stream );
         if( p_sys->p_pcrs[i-1] > p_sys->p_pcrs[i] )
         {
             msg_Dbg( p_demux, "PCR Wrap Around found between %d%% and %d%% (pcr:%"PRId64"(0x%09"PRIx64") pcr:%"PRId64"(0x%09"PRIx64"))",
@@ -2316,7 +2337,7 @@ static void CheckPCR( demux_t *p_demux )
         p_sys->b_force_seek_per_percent = true;
     }
 
-    stream_Seek( p_demux->s, i_initial_pos );
+    stream_Seek( p_sys->stream, i_initial_pos );
     p_sys->i_current_pcr = i_initial_pcr;
 }
 
@@ -2457,9 +2478,10 @@ static bool GatherData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
                       i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
 
             pid->i_cc = i_cc;
-            if( pid->es->p_data && pid->es->fmt.i_cat != VIDEO_ES )
+            if( pid->es->p_data && pid->es->fmt.i_cat != VIDEO_ES &&
+                pid->es->fmt.i_cat != AUDIO_ES )
             {
-                /* Small video artifacts are usually better than
+                /* Small audio/video artifacts are usually better than
                  * dropping full frames */
                 pid->es->p_data->i_flags |= BLOCK_FLAG_CORRUPTED;
             }
@@ -4024,7 +4046,7 @@ static void PMTSetupEs0x06( demux_t *p_demux, ts_pid_t *pid,
         p_fmt->i_codec = VLC_CODEC_A52;
     }
     else if( (desc = PMTEsFindDescriptor( p_es, 0x7f ) ) && desc->i_length >= 2 &&
-              desc->p_data[0] == 0x80)
+              PMTEsHasRegistration(p_demux, p_es, "Opus"))
     {
         OpusSetup(p_demux, desc->p_data, desc->i_length, p_fmt);
     }
@@ -4485,7 +4507,7 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_pmt )
                 break;
             }
         }
-        if ( i_arib_flags == 0b111 )
+        if ( i_arib_flags == 0x07 ) //0b111
             p_sys->arib.e_mode = ARIBMODE_ENABLED;
     }
 
@@ -4768,10 +4790,21 @@ static void PMTCallBack( void *data, dvbpsi_pmt_t *p_pmt )
     }
 
     /* Set CAM descrambling */
-    if( !ProgramIsSelected( p_demux, prg->i_number )
-     || stream_Control( p_demux->s, STREAM_SET_PRIVATE_ID_CA,
-                        p_pmt ) != VLC_SUCCESS )
+    if( !ProgramIsSelected( p_demux, prg->i_number ) )
+    {
         dvbpsi_DeletePMT( p_pmt );
+    }
+    else if( stream_Control( p_sys->stream, STREAM_SET_PRIVATE_ID_CA,
+                             p_pmt ) != VLC_SUCCESS )
+    {
+        if ( p_sys->arib.e_mode == ARIBMODE_ENABLED )
+        {
+            p_sys->arib.b25stream = stream_FilterNew( p_demux->s, "aribcam" );
+            p_sys->stream = ( p_sys->arib.b25stream ) ? p_sys->arib.b25stream : p_demux->s;
+            if (!p_sys->arib.b25stream)
+                dvbpsi_DeletePMT( p_pmt );
+        } else dvbpsi_DeletePMT( p_pmt );
+    }
 
     for( int i = 0; i < i_clean; i++ )
     {