]> git.sesse.net Git - vlc/blobdiff - modules/demux/mp4/mp4.c
All: missing #include "charset.h"
[vlc] / modules / demux / mp4 / mp4.c
index 50535edfe4f6433ff4649fd2b1a3109a0644d499..4dd570ce892bf8dbedf80bc29030b224797c8c23 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * mp4.c : MP4 file input module for vlc
  *****************************************************************************
- * Copyright (C) 2001-2004 VideoLAN
+ * Copyright (C) 2001-2004 the VideoLAN team
  * $Id$
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -17,7 +17,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 /*****************************************************************************
@@ -28,6 +28,7 @@
 #include <vlc/vlc.h>
 #include <vlc/input.h>
 #include <vlc_playlist.h>
+#include <vlc_md5.h>
 #include "iso_lang.h"
 #include "vlc_meta.h"
 
@@ -164,7 +165,7 @@ static int      MP4_TrackSampleSize( mp4_track_t * );
 static int      MP4_TrackNextSample( demux_t *, mp4_track_t * );
 static void     MP4_TrackSetELST( demux_t *, mp4_track_t *, int64_t );
 
-/* Return time in ยตs of a track */
+/* Return time in s of a track */
 static inline int64_t MP4_TrackGetDTS( demux_t *p_demux, mp4_track_t *p_track )
 {
 #define chunk p_track->chunk[p_track->i_chunk]
@@ -405,7 +406,13 @@ static int Open( vlc_object_t * p_this )
                     else
                     {
                         /* msg dbg relative ? */
-                        char *psz_absolute = alloca( strlen( p_demux->psz_access ) + 3 + strlen( p_demux->psz_path ) + strlen( psz_ref ) + 1);
+                        int i_path_size = strlen( p_demux->psz_access ) + 3 +
+                                         strlen( p_demux->psz_path ) + strlen( psz_ref ) + 1;
+#ifdef HAVE_ALLOCA
+                        char *psz_absolute = alloca( i_path_size );
+#else
+                        char *psz_absolute = (char *)malloc( i_path_size );
+#endif
                         char *end = strrchr( p_demux->psz_path, '/' );
 
                         if( end )
@@ -438,6 +445,9 @@ static int Open( vlc_object_t * p_this )
                                 b_play = VLC_TRUE;
                             }
                         }
+#ifndef HAVE_ALLOCA
+                        free( psz_absolute );
+#endif
                     }
                 }
                 else
@@ -690,7 +700,7 @@ static int Demux( demux_t *p_demux )
                 p_block->i_dts = MP4_TrackGetDTS( p_demux, tk ) + 1;
                 /* pts */
                 i_delta = MP4_TrackGetPTSDelta( p_demux, tk );
-                if( i_delta >= 0 )
+                if( i_delta != -1 )
                     p_block->i_pts = p_block->i_dts + i_delta;
                 else if( tk->fmt.i_cat != VIDEO_ES )
                     p_block->i_pts = p_block->i_dts;
@@ -1269,14 +1279,34 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
         case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
             p_track->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
             break;
+
         case( VLC_FOURCC( 'r', 'a', 'w', ' ' ) ):
             p_track->fmt.i_codec = VLC_FOURCC( 'a', 'r', 'a', 'w' );
+
+            /* Buggy files workaround */
+            if( p_sample->data.p_sample_soun && (p_track->i_timescale !=
+                p_sample->data.p_sample_soun->i_sampleratehi) )
+            {
+                MP4_Box_data_sample_soun_t *p_soun =
+                    p_sample->data.p_sample_soun;
+
+                msg_Warn( p_demux, "i_timescale ("I64Fu") != i_sampleratehi "
+                          "(%u), making both equal (report any problem).",
+                          p_track->i_timescale, p_soun->i_sampleratehi );
+
+                if( p_soun->i_sampleratehi )
+                    p_track->i_timescale = p_soun->i_sampleratehi;
+                else
+                    p_soun->i_sampleratehi = p_track->i_timescale;
+            }
             break;
+
         case( VLC_FOURCC( 's', '2', '6', '3' ) ):
             p_track->fmt.i_codec = VLC_FOURCC( 'h', '2', '6', '3' );
             break;
 
         case( VLC_FOURCC( 't', 'e', 'x', 't' ) ):
+        case( VLC_FOURCC( 't', 'x', '3', 'g' ) ):
             p_track->fmt.i_codec = VLC_FOURCC( 's', 'u', 'b', 't' );
             /* FIXME: Not true, could be UTF-16 with a Byte Order Mark (0xfeff) */
             /* FIXME UTF-8 doesn't work here ? */
@@ -1338,6 +1368,10 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
                 if( p_track->fmt.i_cat == SPU_ES )
                 {
                     p_track->fmt.i_codec = VLC_FOURCC( 's','p','u',' ' );
+                    if( p_track->i_width > 0 )
+                        p_track->fmt.subs.spu.i_original_frame_width = p_track->i_width;
+                    if( p_track->i_height > 0 )
+                        p_track->fmt.subs.spu.i_original_frame_height = p_track->i_height;
                     break;
                 }
             /* Fallback */
@@ -1425,6 +1459,8 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
     case( VIDEO_ES ):
         p_track->fmt.video.i_width = p_sample->data.p_sample_vide->i_width;
         p_track->fmt.video.i_height = p_sample->data.p_sample_vide->i_height;
+        p_track->fmt.video.i_bits_per_pixel =
+            p_sample->data.p_sample_vide->i_depth;
 
         /* fall on display size */
         if( p_track->fmt.video.i_width <= 0 )
@@ -1544,8 +1580,8 @@ static int TrackTimeToSampleChunk( demux_t *p_demux, mp4_track_t *p_track,
             break;
         }
 
-        if( i_start >= p_track->chunk[i_chunk].i_first_dts &&
-            i_start <  p_track->chunk[i_chunk + 1].i_first_dts )
+        if( (uint64_t)i_start >= p_track->chunk[i_chunk].i_first_dts &&
+            (uint64_t)i_start <  p_track->chunk[i_chunk + 1].i_first_dts )
         {
             break;
         }
@@ -1558,7 +1594,7 @@ static int TrackTimeToSampleChunk( demux_t *p_demux, mp4_track_t *p_track,
     {
         if( i_dts +
             p_track->chunk[i_chunk].p_sample_count_dts[i_index] *
-            p_track->chunk[i_chunk].p_sample_delta_dts[i_index] < i_start )
+            p_track->chunk[i_chunk].p_sample_delta_dts[i_index] < (uint64_t)i_start )
         {
             i_dts    +=
                 p_track->chunk[i_chunk].p_sample_count_dts[i_index] *
@@ -1713,7 +1749,7 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track,
     unsigned int i;
     char language[4];
 
-    /* hint track unsuported */
+    /* hint track unsupported */
 
     /* set default value (-> track unusable) */
     p_track->b_ok       = VLC_FALSE;
@@ -1776,6 +1812,7 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track,
 
         case( FOURCC_text ):
         case( FOURCC_subp ):
+        case( FOURCC_tx3g ):
             p_track->fmt.i_cat = SPU_ES;
             break;
 
@@ -1788,7 +1825,7 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track,
     if( ( p_track->p_elst = p_elst = MP4_BoxGet( p_box_trak, "edts/elst" ) ) )
     {
         MP4_Box_data_elst_t *elst = p_elst->data.p_elst;
-        int i;
+        unsigned int i;
 
         msg_Warn( p_demux, "elst box found" );
         for( i = 0; i < elst->i_entry_count; i++ )
@@ -1797,7 +1834,8 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track,
                      "ms) rate=%d.%d", i,
                      elst->i_segment_duration[i] * 1000 / p_sys->i_timescale,
                      elst->i_media_time[i] >= 0 ?
-                     elst->i_media_time[i] * 1000 / p_track->i_timescale : -1,
+                     (int64_t)(elst->i_media_time[i] * 1000 / p_track->i_timescale) :
+                     I64C(-1),
                      elst->i_media_rate_integer[i],
                      elst->i_media_rate_fraction[i] );
         }
@@ -1842,32 +1880,6 @@ static void MP4_TrackCreate( demux_t *p_demux, mp4_track_t *p_track,
         }
     }
 
-    /* fxi i_timescale for AUDIO_ES with i_qt_version == 0 */
-    if( p_track->fmt.i_cat == AUDIO_ES ) //&& p_track->i_sample_size == 1 )
-    {
-        MP4_Box_t *p_sample;
-
-        p_sample = MP4_BoxGet(  p_track->p_stsd, "[0]" );
-        if( p_sample && p_sample->data.p_sample_soun)
-        {
-            MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
-            if( p_soun->i_qt_version == 0 &&
-                p_track->i_timescale != p_soun->i_sampleratehi )
-            {
-                msg_Warn( p_demux,
-                          "i_timescale ("I64Fu") != i_sampleratehi (%u) with "
-                          "qt_version == 0\n"
-                          "Making both equal. (report any problem)",
-                          p_track->i_timescale, p_soun->i_sampleratehi );
-
-                if( p_soun->i_sampleratehi )
-                    p_track->i_timescale = p_soun->i_sampleratehi;
-                else
-                    p_soun->i_sampleratehi = p_track->i_timescale;
-            }
-        }
-    }
-
     /* Create chunk index table and sample index table */
     if( TrackCreateChunksIndex( p_demux,p_track  ) ||
         TrackCreateSamplesIndex( p_demux, p_track ) )
@@ -2004,7 +2016,11 @@ static int MP4_TrackSeek( demux_t *p_demux, mp4_track_t *p_track,
         VLC_SUCCESS )
     {
         p_track->b_selected = VLC_TRUE;
+
+        es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
+                        p_track->p_es, i_start );
     }
+
     return( p_track->b_selected ? VLC_SUCCESS : VLC_EGENERIC );
 }
 
@@ -2156,10 +2172,10 @@ static int MP4_TrackNextSample( demux_t *p_demux, mp4_track_t *p_track )
     {
         demux_sys_t *p_sys = p_demux->p_sys;
         MP4_Box_data_elst_t *elst = p_track->p_elst->data.p_elst;
-        int64_t i_mvt = MP4_TrackGetDTS( p_demux, p_track ) *
+        uint64_t i_mvt = MP4_TrackGetDTS( p_demux, p_track ) *
                         p_sys->i_timescale / (int64_t)1000000;
 
-        if( p_track->i_elst < elst->i_entry_count &&
+        if( (unsigned int)p_track->i_elst < elst->i_entry_count &&
             i_mvt >= p_track->i_elst_time +
                      elst->i_segment_duration[p_track->i_elst] )
         {
@@ -2185,7 +2201,7 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk,
         MP4_Box_data_elst_t *elst = tk->p_elst->data.p_elst;
         int64_t i_mvt= i_time * p_sys->i_timescale / (int64_t)1000000;
 
-        for( tk->i_elst = 0; tk->i_elst < elst->i_entry_count; tk->i_elst++ )
+        for( tk->i_elst = 0; (unsigned int)tk->i_elst < elst->i_entry_count; tk->i_elst++ )
         {
             mtime_t i_dur = elst->i_segment_duration[tk->i_elst];
 
@@ -2196,7 +2212,7 @@ static void MP4_TrackSetELST( demux_t *p_demux, mp4_track_t *tk,
             tk->i_elst_time += i_dur;
         }
 
-        if( tk->i_elst >= elst->i_entry_count )
+        if( (unsigned int)tk->i_elst >= elst->i_entry_count )
         {
             /* msg_Dbg( p_demux, "invalid number of entry in elst" ); */
             tk->i_elst = elst->i_entry_count - 1;