]> git.sesse.net Git - vlc/blobdiff - modules/demux/mp4/libmp4.c
LGPL
[vlc] / modules / demux / mp4 / libmp4.c
index 838b0f965cfd2f86c29d2ab9ffbe8a67e680d88b..9f467a09cc87fcb333579d4e0d4427873a569467 100644 (file)
@@ -1,23 +1,23 @@
 /*****************************************************************************
  * libmp4.c : LibMP4 library for mp4 module for vlc
  *****************************************************************************
- * Copyright (C) 2001-2004, 2010 the VideoLAN team
+ * Copyright (C) 2001-2004, 2010 VLC authors and VideoLAN
  *
  * Author: Laurent Aimar <fenrir@via.ecp.fr>
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
  *
- * 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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -1448,9 +1448,10 @@ static int MP4_ReadBox_dvc1( stream_t *p_stream, MP4_Box_t *p_box )
     p_dvc1 = p_box->data.p_dvc1;
 
     MP4_GET1BYTE( p_dvc1->i_profile_level ); /* profile is on 4bits, level 3bits */
-    if( (p_dvc1->i_profile_level & 0xf0) >> 4 != 0x06 )
+    uint8_t i_profile = (p_dvc1->i_profile_level & 0xf0) >> 4;
+    if( i_profile != 0x06 && i_profile != 0x0c )
     {
-        msg_Warn( p_stream, "unsupported VC-1 profile, please report" );
+        msg_Warn( p_stream, "unsupported VC-1 profile (%"PRIu8"), please report", i_profile );
         MP4_READBOX_EXIT( 0 );
     }
 
@@ -1466,8 +1467,8 @@ static int MP4_ReadBox_dvc1( stream_t *p_stream, MP4_Box_t *p_box )
 
 #ifdef MP4_VERBOSE
     msg_Dbg( p_stream,
-             "read box: \"dvc1\" profile=%i level=%i",
-             p_dvc1->i_profile_level & 0xf0 >> 4, p_dvc1->i_profile_level & 0x0e >> 1 );
+             "read box: \"dvc1\" profile=%"PRIu8" level=%i",
+             i_profile, p_dvc1->i_profile_level & 0x0e >> 1 );
 #endif
 
     MP4_READBOX_EXIT( 1 );
@@ -3492,13 +3493,10 @@ error:
     return NULL;
 }
 
-#define MAX_SKIP 8
 MP4_Box_t *MP4_BoxGetNextChunk( stream_t *s )
 {
     /* p_chunk is a virtual root container for the moof and mdat boxes */
     MP4_Box_t *p_chunk;
-    MP4_Box_t *p_moof = NULL;
-    MP4_Box_t *p_sidx = NULL;
     MP4_Box_t *p_tmp_box = NULL;
 
     p_tmp_box = calloc( 1, sizeof( MP4_Box_t ) );
@@ -3510,10 +3508,12 @@ MP4_Box_t *MP4_BoxGetNextChunk( stream_t *s )
 
     if( (p_tmp_box->i_type == ATOM_uuid && !CmpUUID( &p_tmp_box->i_uuid, &SmooBoxUUID )) )
     {
+        free( p_tmp_box );
         return MP4_BoxGetSmooBox( s );
     }
     else if( p_tmp_box->i_type == ATOM_ftyp )
     {
+        free( p_tmp_box );
         return MP4_BoxGetRoot( s );
     }
     free( p_tmp_box );
@@ -3525,50 +3525,11 @@ MP4_Box_t *MP4_BoxGetNextChunk( stream_t *s )
     p_chunk->i_type = ATOM_root;
     p_chunk->i_shortsize = 1;
 
-    /* there may be some boxes before moof,
-     * we skip them (but sidx) for now, but put a reasonable limit */
-    for( int i = 0 ; i < MAX_SKIP; i++ )
-    {
-        p_moof = MP4_ReadBox( s, p_chunk );
-        if( !p_moof )
-            goto error;
-        if( p_moof->i_type != ATOM_moof )
-        {
-            if( i == MAX_SKIP - 1 )
-            {
-                MP4_BoxFree( s, p_moof );
-                goto error;
-            }
-            if( p_moof->i_type != ATOM_sidx )
-            {
-                MP4_BoxFree( s, p_moof );
-                stream_Read( s, NULL, p_moof->i_size );
-            }
-            else
-                p_sidx = p_moof;
-        }
-        else
-            break;
-    }
-
-    p_chunk->p_first = p_moof;
-    p_chunk->p_last = p_moof;
-
-    if( p_sidx )
-    {
-        p_chunk->p_first = p_sidx;
-        p_sidx->p_next = p_moof;
-    }
+    MP4_ReadBoxContainerChildren( s, p_chunk, ATOM_moof );
 
     return p_chunk;
-
-error:
-    free( p_chunk );
-    return NULL;
 }
 
-#undef MAX_SKIP
-
 /*****************************************************************************
  * MP4_BoxGetRoot : Parse the entire file, and create all boxes in memory
  *****************************************************************************
@@ -3610,12 +3571,14 @@ MP4_Box_t *MP4_BoxGetRoot( stream_t *s )
         return p_root;
 
     p_root->i_size = stream_Size( s );
-    stream_Seek( p_stream, 0 );
-    /* Get the rest of the file */
-    i_result = MP4_ReadBoxContainerRaw( p_stream, p_root );
+    if( stream_Tell( s ) < stream_Size( s ) )
+    {
+        /* Get the rest of the file */
+        i_result = MP4_ReadBoxContainerRaw( p_stream, p_root );
 
-    if( !i_result )
-        goto error;
+        if( !i_result )
+            goto error;
+    }
 
     MP4_Box_t *p_moov;
     MP4_Box_t *p_cmov;