]> git.sesse.net Git - vlc/blobdiff - modules/demux/mp4/mp4.c
mp4: set amr-nb samplerate to 8000, as it's only valid one
[vlc] / modules / demux / mp4 / mp4.c
index 68b105dcb456afade6d30e7157720a804a71c94f..bd84188f614060b086820dc62395289514741e2e 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * mp4.c : MP4 file input module for vlc
  *****************************************************************************
- * Copyright (C) 2001-2004 the VideoLAN team
+ * Copyright (C) 2001-2004, 2010 the VideoLAN team
  * $Id$
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -41,6 +41,7 @@
 
 #include "libmp4.h"
 #include "drms.h"
+#include "../../meta_engine/id3genres.h"
 
 /*****************************************************************************
  * Module descriptor
@@ -494,7 +495,7 @@ static int Open( vlc_object_t * p_this )
             p_sys->p_tref_chap = p_chap;
     }
 
-    /* now process each track and extract all usefull information */
+    /* now process each track and extract all useful information */
     for( i = 0; i < p_sys->i_tracks; i++ )
     {
         p_trak = MP4_BoxGet( p_sys->p_root, "/moov/trak[%d]", i );
@@ -903,6 +904,11 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                     SET( vlc_meta_SetGenre );
                     break;
 
+                case FOURCC_gnre:
+                    if( p_0xa9xxx->data.p_gnre->i_genre <= NUM_GENRES )
+                        vlc_meta_SetGenre( p_meta, ppsz_genres[p_0xa9xxx->data.p_gnre->i_genre - 1] );
+                    break;
+
                 case FOURCC_0xa9alb: /* Album */
                     SET( vlc_meta_SetAlbum );
                     break;
@@ -910,7 +916,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                 case FOURCC_0xa9trk: /* Track */
                     SET( vlc_meta_SetTrackNum );
                     break;
-
+                case FOURCC_trkn:
+                {
+                    char psz_trck[11];
+                    snprintf( psz_trck, sizeof( psz_trck ), "%i",
+                              p_0xa9xxx->data.p_trkn->i_track_number );
+                    vlc_meta_SetTrackNum( p_meta, psz_trck );
+                    break;
+                }
                 case FOURCC_0xa9cmt: /* Commment */
                     SET( vlc_meta_SetDescription );
                     break;
@@ -919,32 +932,53 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
                     SET( vlc_meta_SetURL );
                     break;
 
+                case FOURCC_0xa9too: /* Encoder Tool */
                 case FOURCC_0xa9enc: /* Encoded By */
                     SET( vlc_meta_SetEncodedBy );
                     break;
-                    
-                case FOURCC_0xa9swr:
-                case FOURCC_0xa9inf: /* Information */
-                case FOURCC_0xa9dir: /* Director */
-                case FOURCC_0xa9dis: /* Disclaimer */
-                case FOURCC_0xa9req: /* Requirements */
-                case FOURCC_0xa9fmt: /* Original Format */
-                case FOURCC_0xa9dsa: /* Display Source As */
-                case FOURCC_0xa9hst: /* Host Computer */
-                case FOURCC_0xa9prd: /* Producer */
-                case FOURCC_0xa9prf: /* Performers */
-                case FOURCC_0xa9ope: /* Original Performer */
-                case FOURCC_0xa9src: /* Providers Source Content */
-                case FOURCC_0xa9wrt: /* Writer */
-                case FOURCC_0xa9com: /* Composer */
-                case FOURCC_WLOC:    /* Window Location */
-                    /* TODO one day, but they aren't really meaningfull */
-                    break;
-#undef SET
 
                 default:
                     break;
                 }
+#undef SET
+                static const struct { uint32_t xa9_type; char metadata[25]; } xa9typetoextrameta[] = 
+                {
+                    { FOURCC_0xa9wrt, N_("Writer") },
+                    { FOURCC_0xa9com, N_("Composr") },
+                    { FOURCC_0xa9prd, N_("Producer") },
+                    { FOURCC_0xa9inf, N_("Information") },
+                    { FOURCC_0xa9dir, N_("Director") },
+                    { FOURCC_0xa9dis, N_("Disclaimer") },
+                    { FOURCC_0xa9req, N_("Requirements") },
+                    { FOURCC_0xa9fmt, N_("Original Format") },
+                    { FOURCC_0xa9dsa, N_("Display Source As") },
+                    { FOURCC_0xa9hst, N_("Host Computer") },
+                    { FOURCC_0xa9prf, N_("Performers") },
+                    { FOURCC_0xa9ope, N_("Original Performer") },
+                    { FOURCC_0xa9src, N_("Providers Source Content") },
+                    { FOURCC_0xa9wrn, N_("Warning") },
+                    { FOURCC_0xa9swr, N_("Software") },
+                    { FOURCC_0xa9lyr, N_("Lyrics") },
+                    { FOURCC_0xa9mak, N_("Make") },
+                    { FOURCC_0xa9mod, N_("Model") },
+                    { FOURCC_0xa9PRD, N_("Product") },
+                    { FOURCC_0xa9grp, N_("Grouping") },
+                    { 0, "" },
+                };
+                for( unsigned i = 0; xa9typetoextrameta[i].xa9_type; i++ )
+                {
+                    if( p_0xa9xxx->i_type == xa9typetoextrameta[i].xa9_type )
+                    {
+                        char *psz_utf = strdup( p_0xa9xxx->data.p_0xa9xxx->psz_text ? p_0xa9xxx->data.p_0xa9xxx->psz_text : "" );
+                        if( psz_utf )
+                        {
+                             EnsureUTF8( psz_utf );
+                             vlc_meta_AddExtra( p_meta, _(xa9typetoextrameta[i].metadata), psz_utf );
+                             free( psz_utf );
+                        }
+                        break;
+                    }
+                }
             }
             return VLC_SUCCESS;
         }
@@ -1522,6 +1556,7 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
                 case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
                 case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
                     p_soun->i_samplesize = 8;
+                    p_track->i_sample_size = p_soun->i_channelcount;
                     break;
                 case VLC_FOURCC( 'N', 'O', 'N', 'E' ):
                 case VLC_FOURCC( 'r', 'a', 'w', ' ' ):
@@ -1540,6 +1575,28 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
             p_soun->i_qt_version = 0;
         }
     }
+    else if( p_track->fmt.i_cat == AUDIO_ES && p_sample->data.p_sample_soun->i_qt_version == 1 )
+    {
+        MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
+
+        switch( p_sample->i_type )
+        {
+            case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
+            case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
+            {
+                if( p_track->i_sample_size > 1 )
+                    p_soun->i_qt_version = 0;
+                break;
+            }
+            case( VLC_FOURCC( 'a', 'c', '-', '3' ) ):
+            case( VLC_FOURCC( 'e', 'c', '-', '3' ) ):
+            case( VLC_FOURCC( 'm', 's', 0x20, 0x00 ) ):
+                p_soun->i_qt_version = 0;
+                break;
+            default:
+                break;
+        }
+    }
 
     /* */
     switch( p_track->fmt.i_cat )
@@ -1607,10 +1664,7 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
         case( VLC_FOURCC( '.', 'm', 'p', '3' ) ):
         case( VLC_FOURCC( 'm', 's', 0x00, 0x55 ) ):
         {
-            MP4_Box_data_sample_soun_t *p_soun = p_sample->data.p_sample_soun;
             p_track->fmt.i_codec = VLC_FOURCC( 'm', 'p', 'g', 'a' );
-            if( p_track->i_sample_size > 1 )
-                p_soun->i_qt_version = 0;
             break;
         }
         case( VLC_FOURCC( 'a', 'c', '-', '3' ) ):
@@ -1727,6 +1781,12 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
                 break;
             case( 0x40):
                 p_track->fmt.i_codec = VLC_FOURCC( 'm','p','4','a' );
+                if( p_decconfig->i_decoder_specific_info_len >= 2 &&
+                     p_decconfig->p_decoder_specific_info[0]       == 0xF8 &&
+                    (p_decconfig->p_decoder_specific_info[1]&0xE0) == 0x80 )
+                {
+                    p_track->fmt.i_codec = VLC_CODEC_ALS;
+                }
                 break;
             case( 0x60):
             case( 0x61):
@@ -1835,9 +1895,10 @@ static int TrackCreateES( demux_t *p_demux, mp4_track_t *p_track,
                             p_track->fmt.i_extra);
                 }
                 break;
+            case VLC_FOURCC( 's', 'a', 'm', 'r' ):
+                p_track->fmt.audio.i_rate = 8000;
             case VLC_FOURCC( 'Q', 'D', 'M', 'C' ):
             case VLC_FOURCC( 'Q', 'D', 'M', '2' ):
-            case VLC_FOURCC( 's', 'a', 'm', 'r' ):
             case VLC_FOURCC( 'a', 'l', 'a', 'c' ):
                 p_track->fmt.i_extra =
                     p_sample->data.p_sample_soun->i_qt_description;