]> git.sesse.net Git - vlc/blobdiff - modules/demux/real.c
* Ensure garbage collector is called when disabling a video track (Closes:#935)
[vlc] / modules / demux / real.c
index 2be24cac4ff00333f93a6de9f566621319e68963..441d93174063ccb56554eb9ea8031f2c52d98cff 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * real.c: Real demuxer.
  *****************************************************************************
- * Copyright (C) 2004 the VideoLAN team
+ * Copyright (C) 2004, 2006 the VideoLAN team
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 /*****************************************************************************
  * Preamble
  *****************************************************************************/
+#include <vlc/vlc.h>
+
+#include <stdio.h>
 #include <stdlib.h>                                      /* malloc(), free() */
 
-#include <vlc/vlc.h>
-#include <vlc/input.h>
+#include <vlc_demux.h>
+#include <vlc_charset.h>
+#include <vlc_meta.h>
 
 /*****************************************************************************
  * Module descriptor
@@ -79,6 +83,14 @@ struct demux_sys_t
     uint32_t i_data_packets;
     int64_t  i_data_offset_next;
 
+    int  i_our_duration;
+    int  i_mux_rate;
+
+    char* psz_title;
+    char* psz_artist;
+    char* psz_copyright;
+    char* psz_description;
+
     int          i_track;
     real_track_t **track;
 
@@ -155,20 +167,26 @@ static void Close( vlc_object_t *p_this )
     for( i = 0; i < p_sys->i_track; i++ )
     {
         real_track_t *tk = p_sys->track[i];
+        int j = tk->i_subpackets;
 
         if( tk->p_frame ) block_Release( tk->p_frame );
         es_format_Clean( &tk->fmt );
 
-        while(  tk->i_subpackets-- )
+        while(  j-- )
         {
-            if( tk->p_subpackets[tk->i_subpackets] )
-                block_Release( tk->p_subpackets[tk->i_subpackets] );
-            if( !tk->i_subpackets ) free( tk->p_subpackets );
+            if( tk->p_subpackets[ j ] )
+                block_Release( tk->p_subpackets[ j ] );
         }
+        if( tk->i_subpackets ) free( tk->p_subpackets );
 
         free( tk );
     }
 
+    if( p_sys->psz_title ) free( p_sys->psz_title );
+    if( p_sys->psz_artist ) free( p_sys->psz_artist );
+    if( p_sys->psz_copyright ) free( p_sys->psz_copyright );
+    if( p_sys->psz_description ) free( p_sys->psz_description );
+
     if( p_sys->i_track > 0 ) free( p_sys->track );
     free( p_sys );
 }
@@ -589,13 +607,16 @@ static int Demux( demux_t *p_demux )
  *****************************************************************************/
 static int Control( demux_t *p_demux, int i_query, va_list args )
 {
-#if 0
     demux_sys_t *p_sys = p_demux->p_sys;
+#if 0
     double f, *pf;
-    int64_t i64, *pi64;
+    int64_t i64;
+#endif
+    int64_t *pi64;
 
     switch( i_query )
     {
+#if 0
         case DEMUX_GET_POSITION:
             pf = (double*) va_arg( args, double* );
             i64 = stream_Size( p_demux->s );
@@ -608,6 +629,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 *pf = 0.0;
             }
             return VLC_SUCCESS;
+
         case DEMUX_SET_POSITION:
             f = (double) va_arg( args, double );
             i64 = stream_Size( p_demux->s );
@@ -625,23 +647,50 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             }
             *pi64 = 0;
             return VLC_EGENERIC;
+#endif
 
         case DEMUX_GET_LENGTH:
             pi64 = (int64_t*)va_arg( args, int64_t * );
-            if( p_sys->i_mux_rate > 0 )
+            
+            /* the commented following lines are fen's implementation, which doesn't seem to
+             * work for one reason or another -- FK */
+            /*if( p_sys->i_mux_rate > 0 )
             {
                 *pi64 = (int64_t)1000000 * ( stream_Size( p_demux->s ) / 50 ) / p_sys->i_mux_rate;
+                return VLC_SUCCESS;
+            }*/
+            if( p_sys->i_our_duration > 0 )
+            {
+                /* our stored duration is in ms, so... */
+                *pi64 = (int64_t)1000 * p_sys->i_our_duration;
+                
                 return VLC_SUCCESS;
             }
             *pi64 = 0;
             return VLC_EGENERIC;
 
+        case DEMUX_GET_META:
+        {
+            vlc_meta_t *p_meta = (vlc_meta_t*)va_arg( args, vlc_meta_t* );
+
+            /* the core will crash if we provide NULL strings, so check 
+             * every string first */
+            if( p_sys->psz_title )
+                vlc_meta_SetTitle( p_meta, p_sys->psz_title );
+            if( p_sys->psz_artist )
+                vlc_meta_SetArtist( p_meta, p_sys->psz_artist );
+            if( p_sys->psz_copyright )
+                vlc_meta_SetCopyright( p_meta, p_sys->psz_copyright );
+            if( p_sys->psz_description )
+                vlc_meta_SetDescription( p_meta, p_sys->psz_description );
+            return VLC_SUCCESS;
+        }
+
         case DEMUX_SET_TIME:
         case DEMUX_GET_FPS:
         default:
             return VLC_EGENERIC;
     }
-#endif
     return VLC_EGENERIC;
 }
 
@@ -672,7 +721,7 @@ static int HeaderRead( demux_t *p_demux )
         msg_Dbg( p_demux, "object %4.4s size=%d version=%d",
                  (char*)&i_id, i_size, i_version );
 
-        if( i_size < 10 )
+        if( i_size < 10 && i_id != VLC_FOURCC('D','A','T','A') )
         {
             msg_Dbg( p_demux, "invalid size for object %4.4s", (char*)&i_id );
             return VLC_EGENERIC;
@@ -703,6 +752,10 @@ static int HeaderRead( demux_t *p_demux )
             msg_Dbg( p_demux, "    - index offset=%d", GetDWBE(&header[28]) );
             msg_Dbg( p_demux, "    - data offset=%d", GetDWBE(&header[32]) );
             msg_Dbg( p_demux, "    - num streams=%d", GetWBE(&header[36]) );
+            
+            /* set the duration for export in control */
+            p_sys->i_our_duration = (int)GetDWBE(&header[20]);
+            
             i_flags = GetWBE(&header[38]);
             msg_Dbg( p_demux, "    - flags=0x%x %s%s%s",
                      i_flags,
@@ -715,6 +768,9 @@ static int HeaderRead( demux_t *p_demux )
         {
             int i_len;
             char *psz;
+            
+            /* FIXME FIXME: should convert from whatever the character
+             * encoding of the input meta data is to UTF-8. */
 
             stream_Read( p_demux->s, header, 2 );
             if( ( i_len = GetWBE( header ) ) > 0 )
@@ -724,6 +780,8 @@ static int HeaderRead( demux_t *p_demux )
                 psz[i_len] = '\0';
 
                 msg_Dbg( p_demux, "    - title=`%s'", psz );
+                EnsureUTF8( psz );
+                asprintf( &p_sys->psz_title, psz );
                 free( psz );
                 i_skip -= i_len;
             }
@@ -737,6 +795,8 @@ static int HeaderRead( demux_t *p_demux )
                 psz[i_len] = '\0';
 
                 msg_Dbg( p_demux, "    - author=`%s'", psz );
+                EnsureUTF8( psz );
+                asprintf( &p_sys->psz_artist, psz );
                 free( psz );
                 i_skip -= i_len;
             }
@@ -750,6 +810,8 @@ static int HeaderRead( demux_t *p_demux )
                 psz[i_len] = '\0';
 
                 msg_Dbg( p_demux, "    - copyright=`%s'", psz );
+                EnsureUTF8( psz );
+                asprintf( &p_sys->psz_copyright, psz );
                 free( psz );
                 i_skip -= i_len;
             }
@@ -763,6 +825,8 @@ static int HeaderRead( demux_t *p_demux )
                 psz[i_len] = '\0';
 
                 msg_Dbg( p_demux, "    - comment=`%s'", psz );
+                EnsureUTF8( psz );
+                asprintf( &p_sys->psz_description, psz );
                 free( psz );
                 i_skip -= i_len;
             }
@@ -785,6 +849,7 @@ static int HeaderRead( demux_t *p_demux )
             msg_Dbg( p_demux, "    - start time=%d", GetDWBE(&header[18]) );
             msg_Dbg( p_demux, "    - preroll=%d", GetDWBE(&header[22]) );
             msg_Dbg( p_demux, "    - duration=%d", GetDWBE(&header[26]) );
+            
             i_skip -= 30;
 
             stream_Read( p_demux->s, header, 1 );
@@ -904,6 +969,10 @@ static int ReadCodecSpecificData( demux_t *p_demux, int i_len, int i_num )
                  (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height );
 
         tk = malloc( sizeof( real_track_t ) );
+        tk->i_out_subpacket = 0;
+        tk->i_subpacket = 0;
+        tk->i_subpackets = 0;
+        tk->p_subpackets = NULL;
         tk->i_id = i_num;
         tk->fmt = fmt;
         tk->i_frame = 0;