]> git.sesse.net Git - vlc/blobdiff - modules/demux/real.c
demux: ts: flush queues after seek
[vlc] / modules / demux / real.c
index 9a9cd02ea662642262dafee4c8733d4a996c61e8..fa3219867c8905bb55893ef2ae3b201f0bbba2fc 100644 (file)
@@ -68,7 +68,7 @@ static void Close  ( vlc_object_t * );
 
 vlc_module_begin ()
     set_description( N_("Real demuxer" ) )
-    set_capability( "demux", 50 )
+    set_capability( "demux", 0 )
     set_category( CAT_INPUT )
     set_subcategory( SUBCAT_INPUT_DEMUX )
     set_callbacks( Open, Close )
@@ -86,10 +86,10 @@ typedef struct
 
     es_out_id_t *p_es;
 
-    int         i_frame_size;
+    unsigned    i_frame_size;
 
     int         i_frame_num;
-    int         i_frame_pos;
+    unsigned    i_frame_pos;
     int         i_frame_slice;
     int         i_frame_slice_count;
     block_t     *p_frame;
@@ -251,11 +251,8 @@ static void Close( vlc_object_t *p_this )
             if( tk->p_subpackets[ j ] )
                 block_Release( tk->p_subpackets[ j ] );
         }
-        if( tk->i_subpackets )
-        {
-            free( tk->p_subpackets );
-            free( tk->p_subpackets_timecode );
-        }
+        free( tk->p_subpackets );
+        free( tk->p_subpackets_timecode );
         if( tk->p_sipr_packet )
             block_Release( tk->p_sipr_packet );
         free( tk );
@@ -550,7 +547,7 @@ static void DemuxVideo( demux_t *p_demux, real_track_t *tk, mtime_t i_dts, unsig
             if( tk->p_frame )
                 block_Release( tk->p_frame );
 
-            tk->p_frame = block_New( p_demux, tk->i_frame_size );
+            tk->p_frame = block_Alloc( tk->i_frame_size );
             if( !tk->p_frame )
             {
                 tk->i_frame_size = 0;
@@ -636,7 +633,12 @@ static void DemuxAudioMethod1( demux_t *p_demux, real_track_t *tk, mtime_t i_pts
 
         for( int i = 0; i < i_num; i++ )
         {
-            block_t *p_block = block_New( p_demux, tk->i_subpacket_size );
+            int i_index = tk->i_subpacket_h * i +
+                          ((tk->i_subpacket_h + 1) / 2) * (y&1) + (y>>1);
+            if( i_index >= tk->i_subpackets )
+                return;
+
+            block_t *p_block = block_Alloc( tk->i_subpacket_size );
             if( !p_block )
                 return;
             if( &p_buf[tk->i_subpacket_size] > &p_sys->buffer[p_sys->i_buffer] )
@@ -648,9 +650,6 @@ static void DemuxAudioMethod1( demux_t *p_demux, real_track_t *tk, mtime_t i_pts
 
             p_buf += tk->i_subpacket_size;
 
-            int i_index = tk->i_subpacket_h * i +
-                          ((tk->i_subpacket_h + 1) / 2) * (y&1) + (y>>1);
-
             if( tk->p_subpackets[i_index] != NULL )
             {
                 msg_Dbg(p_demux, "p_subpackets[ %d ] not null!",  i_index );
@@ -670,14 +669,16 @@ static void DemuxAudioMethod1( demux_t *p_demux, real_track_t *tk, mtime_t i_pts
 
         for( int i = 0; i < tk->i_subpacket_h / 2; i++ )
         {
-            block_t *p_block = block_New( p_demux, tk->i_coded_frame_size);
+            int i_index = (i * 2 * tk->i_frame_size / tk->i_coded_frame_size) + y;
+            if( i_index >= tk->i_subpackets )
+                return;
+
+            block_t *p_block = block_Alloc( tk->i_coded_frame_size);
             if( !p_block )
                 return;
             if( &p_buf[tk->i_coded_frame_size] > &p_sys->buffer[p_sys->i_buffer] )
                 return;
 
-            int i_index = (i * 2 * tk->i_frame_size / tk->i_coded_frame_size) + y;
-
             memcpy( p_block->p_buffer, p_buf, tk->i_coded_frame_size );
             p_block->i_dts =
             p_block->i_pts = i_index == 0 ? i_pts : VLC_TS_INVALID;
@@ -744,7 +745,7 @@ static void DemuxAudioMethod2( demux_t *p_demux, real_track_t *tk, mtime_t i_pts
     for( unsigned i = 0; i < i_sub; i++ )
     {
         const int i_sub_size = GetWBE( &p_sys->buffer[2+i*2] );
-        block_t *p_block = block_New( p_demux, i_sub_size );
+        block_t *p_block = block_Alloc( i_sub_size );
         if( !p_block )
             break;
 
@@ -768,7 +769,7 @@ static void DemuxAudioMethod3( demux_t *p_demux, real_track_t *tk, mtime_t i_pts
     if( p_sys->i_buffer <= 0 )
         return;
 
-    block_t *p_block = block_New( p_demux, p_sys->i_buffer );
+    block_t *p_block = block_Alloc( p_sys->i_buffer );
     if( !p_block )
         return;
 
@@ -839,17 +840,17 @@ static void DemuxAudioSipr( demux_t *p_demux, real_track_t *tk, mtime_t i_pts )
     demux_sys_t *p_sys = p_demux->p_sys;
     block_t *p_block = tk->p_sipr_packet;
 
-    if( p_sys->i_buffer < tk->i_frame_size )
+    if( p_sys->i_buffer < tk->i_frame_size
+     || tk->i_sipr_subpacket_count >= tk->i_subpacket_h )
         return;
 
     if( !p_block )
     {
-        p_block = block_New( p_demux, tk->i_frame_size * tk->i_subpacket_h );
+        p_block = block_Alloc( tk->i_frame_size * tk->i_subpacket_h );
         if( !p_block )
             return;
         tk->p_sipr_packet = p_block;
     }
-
     memcpy( p_block->p_buffer + tk->i_sipr_subpacket_count * tk->i_frame_size,
             p_sys->buffer, tk->i_frame_size );
     if (!tk->i_sipr_subpacket_count)
@@ -962,7 +963,7 @@ static char *StreamReadString2( stream_t *s )
     if( i_length <= 0 )
         return NULL;
 
-    char *psz_string = calloc( 1, i_length + 1 );
+    char *psz_string = xcalloc( 1, i_length + 1 );
 
     stream_Read( s, psz_string, i_length ); /* Valid even if !psz_string */
 
@@ -1376,12 +1377,12 @@ static int CodecVideoParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
     fmt.video.i_frame_rate = (GetWBE( &p_data[22] ) << 16) | GetWBE( &p_data[24] );
     fmt.video.i_frame_rate_base = 1 << 16;
 
-    fmt.i_extra = 8;
-    fmt.p_extra = malloc( 8 );
+    fmt.i_extra = i_data - 26;
+    fmt.p_extra = malloc( fmt.i_extra );
     if( !fmt.p_extra )
         return VLC_ENOMEM;
 
-    memcpy( fmt.p_extra, &p_data[26], 8 );
+    memcpy( fmt.p_extra, &p_data[26], fmt.i_extra );
 
     //msg_Dbg( p_demux, "    - video 0x%08x 0x%08x", dw0, dw1 );
 
@@ -1444,7 +1445,7 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
     int i_subpacket_h = 0;
     int i_frame_size = 0;
     int i_subpacket_size = 0;
-    char p_genr[4];
+    char p_genr[4] = {0,0,0,0};
     int i_version = GetWBE( &p_data[4] );
     int i_extra_codec = 0;
 
@@ -1481,7 +1482,10 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
         i_frame_size = R16( &p_data, &i_data );
         i_subpacket_size = R16( &p_data, &i_data );
         if( !i_frame_size || !i_coded_frame_size )
+        {
+            es_format_Clean( &fmt );
             return VLC_EGENERIC;
+        }
 
         RVoid( &p_data, &i_data, 2 + (i_version == 5 ? 6 : 0 ) );
 
@@ -1536,6 +1540,11 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
         break;
 
     case VLC_FOURCC('2','8','_','8'):
+        if( i_coded_frame_size <= 0 )
+        {
+            es_format_Clean( &fmt );
+            return VLC_EGENERIC;
+        }
         fmt.i_codec = VLC_CODEC_RA_288;
         fmt.audio.i_blockalign = i_coded_frame_size;
         break;
@@ -1558,17 +1567,24 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
         {
             fmt.p_extra = malloc( i_extra_codec );
             if( !fmt.p_extra || i_extra_codec > i_data )
+            {
+                free( fmt.p_extra );
                 return VLC_ENOMEM;
+            }
 
             fmt.i_extra = i_extra_codec;
             memcpy( fmt.p_extra, p_data, fmt.i_extra );
         }
         break;
 
-    case VLC_FOURCC( 's','i','p','r' ):
+    case VLC_CODEC_SIPR:
         fmt.i_codec = VLC_CODEC_SIPR;
         if( i_flavor > 3 )
+        {
+            msg_Dbg( p_demux, "    - unsupported sipr flavorc=%i", i_flavor );
+            es_format_Clean( &fmt );
             return VLC_EGENERIC;
+        }
 
         i_subpacket_size = i_subpacket_size_sipr[i_flavor];
         // The libavcodec sipr decoder requires stream bitrate
@@ -1577,8 +1593,8 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
         fmt.i_bitrate = fmt.audio.i_rate;
         msg_Dbg( p_demux, "    - sipr flavor=%i", i_flavor );
 
-    case VLC_FOURCC( 'c','o','o','k' ):
-    case VLC_FOURCC( 'a','t','r','c' ):
+    case VLC_CODEC_COOK:
+    case VLC_CODEC_ATRAC3:
         if( i_subpacket_size <= 0 || i_frame_size / i_subpacket_size <= 0 )
         {
             es_format_Clean( &fmt );
@@ -1589,16 +1605,14 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
         else
             fmt.audio.i_blockalign = i_coded_frame_size;
 
-        if( fmt.i_codec == VLC_FOURCC( 'c','o','o','k' ) )
-            fmt.i_codec = VLC_CODEC_COOK;
-        else if( fmt.i_codec == VLC_FOURCC( 'a','t','r','c' ) )
-            fmt.i_codec = VLC_CODEC_ATRAC3;
-
         if( i_extra_codec > 0 )
         {
             fmt.p_extra = malloc( i_extra_codec );
             if( !fmt.p_extra || i_extra_codec > i_data )
+            {
+                free( fmt.p_extra );
                 return VLC_ENOMEM;
+            }
 
             fmt.i_extra = i_extra_codec;
             memcpy( fmt.p_extra, p_data, fmt.i_extra );
@@ -1607,13 +1621,11 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
         break;
 
     case VLC_FOURCC('r','a','l','f'):
-        msg_Dbg( p_demux, "    - audio codec not supported=%4.4s",
-                 (char*)&fmt.i_codec );
-        break;
-
     default:
         msg_Dbg( p_demux, "    - unknown audio codec=%4.4s",
-                 (char*)&fmt.i_codec );
+                (char*)&fmt.i_codec );
+        es_format_Clean( &fmt );
+        return VLC_EGENERIC;
         break;
     }
     msg_Dbg( p_demux, "    - extra data=%d", fmt.i_extra );
@@ -1650,18 +1662,18 @@ static int CodecAudioParse( demux_t *p_demux, int i_tk_id, const uint8_t *p_data
         tk->i_subpackets =
             i_subpacket_h * i_frame_size / tk->i_subpacket_size;
         tk->p_subpackets =
-            calloc( tk->i_subpackets, sizeof(block_t *) );
+            xcalloc( tk->i_subpackets, sizeof(block_t *) );
         tk->p_subpackets_timecode =
-            calloc( tk->i_subpackets , sizeof( int64_t ) );
+            xcalloc( tk->i_subpackets , sizeof( int64_t ) );
     }
     else if( fmt.i_codec == VLC_CODEC_RA_288 )
     {
         tk->i_subpackets =
             i_subpacket_h * i_frame_size / tk->i_coded_frame_size;
         tk->p_subpackets =
-            calloc( tk->i_subpackets, sizeof(block_t *) );
+            xcalloc( tk->i_subpackets, sizeof(block_t *) );
         tk->p_subpackets_timecode =
-            calloc( tk->i_subpackets , sizeof( int64_t ) );
+            xcalloc( tk->i_subpackets , sizeof( int64_t ) );
     }
 
     /* Check if the calloc went correctly */