changeset 3005:3d6a2732f26a

Update mp4ff as well. Eternal glory for the one who finds the hidden PACKAGE in the about dialog.
author Tony Vroon <chainsaw@gentoo.org>
date Wed, 08 Apr 2009 22:16:01 +0100
parents 8867d3491f60
children 169f6ee38cad
files src/aac/include/faad.h src/aac/include/neaacdec.h src/aac/libfaad2/decoder.c src/aac/libfaad2/mp4.c src/aac/libmp4.c src/aac/mp4ff/mp4atom.c src/aac/mp4ff/mp4ff.c src/aac/mp4ff/mp4ff.h src/aac/mp4ff/mp4ff_int_types.h src/aac/mp4ff/mp4ffint.h src/aac/mp4ff/mp4meta.c src/aac/mp4ff/mp4sample.c src/aac/mp4ff/mp4tagupdate.c src/aac/mp4ff/mp4util.c
diffstat 14 files changed, 597 insertions(+), 421 deletions(-) [+]
line wrap: on
line diff
--- a/src/aac/include/faad.h	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/include/faad.h	Wed Apr 08 22:16:01 2009 +0100
@@ -1,28 +1,31 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: faad.h,v 1.47 2004/04/03 19:08:37 menno Exp $
+** $Id: faad.h,v 1.51 2007/11/01 12:33:29 menno Exp $
 **/
 
 /* Backwards compatible link */
--- a/src/aac/include/neaacdec.h	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/include/neaacdec.h	Wed Apr 08 22:16:01 2009 +0100
@@ -1,28 +1,31 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: neaacdec.h,v 1.5 2004/09/04 14:56:27 menno Exp $
+** $Id: neaacdec.h,v 1.13 2009/01/26 23:51:15 menno Exp $
 **/
 
 #ifndef __NEAACDEC_H__
@@ -66,7 +69,7 @@
   #endif
 #endif
 
-#define FAAD2_VERSION "2.1 beta"
+#define FAAD2_VERSION "2.7"
 
 /* object types for AAC */
 #define MAIN       1
@@ -83,6 +86,7 @@
 #define RAW        0
 #define ADIF       1
 #define ADTS       2
+#define LATM       3
 
 /* SBR signalling */
 #define NO_SBR           0
@@ -213,9 +217,11 @@
                               unsigned char *channels);
 
 /* Init the library using a DecoderSpecificInfo */
-signed char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hDecoder, unsigned char *pBuffer,
+signed char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hDecoder,
+                               unsigned char *pBuffer,
                                unsigned long SizeOfDecoderSpecificInfo,
-                               unsigned int *samplerate, unsigned char *channels);
+                               unsigned long *samplerate,
+                               unsigned char *channels);
 
 /* Init the library for DRM */
 signed char NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, unsigned long samplerate,
--- a/src/aac/libfaad2/decoder.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/libfaad2/decoder.c	Wed Apr 08 22:16:01 2009 +0100
@@ -366,7 +366,7 @@
 }
 
 /* Init the library using a DecoderSpecificInfo */
-char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hpDecoder,
+signed char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hpDecoder,
                                unsigned char *pBuffer,
                                unsigned long SizeOfDecoderSpecificInfo,
                                unsigned long *samplerate,
--- a/src/aac/libfaad2/mp4.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/libfaad2/mp4.c	Wed Apr 08 22:16:01 2009 +0100
@@ -114,7 +114,7 @@
 };
 
 /* Table 1.6.1 */
-char NEAACDECAPI NeAACDecAudioSpecificConfig(unsigned char *pBuffer,
+signed char NEAACDECAPI NeAACDecAudioSpecificConfig(unsigned char *pBuffer,
                                              unsigned long buffer_size,
                                              mp4AudioSpecificConfig *mp4ASC)
 {
--- a/src/aac/libmp4.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/libmp4.c	Wed Apr 08 22:16:01 2009 +0100
@@ -2,7 +2,7 @@
 #include <gtk/gtk.h>
 #include <string.h>
 #include <stdlib.h>
-#include "faad.h"
+#include "neaacdec.h"
 #include "mp4ff.h"
 #include "tagging.h"
 
@@ -26,7 +26,9 @@
 #define AAC_MAGIC     (unsigned char [4]) { 0xFF, 0xF9, 0x5C, 0x80 }
 
 static void        mp4_init(void);
+/*
 static void        mp4_about(void);
+*/
 static int         mp4_is_our_file(char *);
 static void        mp4_play(InputPlayback *);
 static void        mp4_stop(InputPlayback *);
@@ -47,7 +49,9 @@
 {
     .description = "MP4 Audio Plugin",
     .init = mp4_init,
+/*
     .about = mp4_about,
+*/
     .is_our_file = mp4_is_our_file,
     .play_file = mp4_play,
     .stop = mp4_stop,
@@ -277,9 +281,10 @@
   return 0;
 }
 
+/* XXX TODO: Figure out cause of freaky symbol collision and resurrect
 static void mp4_about(void)
 {
-    static GtkWidget *aboutbox = NULL;
+    static GtkWidget aboutbox = NULL;
     gchar *about_text;
 
     about_text = g_strjoin ("", _("Using libfaad2-"), FAAD2_VERSION,
@@ -295,6 +300,7 @@
                      G_CALLBACK(gtk_widget_destroyed), &aboutbox);
     g_free(about_text);
 }
+*/
 
 static void mp4_pause(InputPlayback *playback, short flag)
 {
--- a/src/aac/mp4ff/mp4atom.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4atom.c	Wed Apr 08 22:16:01 2009 +0100
@@ -1,43 +1,48 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4atom.c,v 1.17 2004/01/11 15:52:18 menno Exp $
+** $Id: mp4atom.c,v 1.29 2009/01/19 23:56:30 menno Exp $
 **/
 
 #include <stdlib.h>
 #include "mp4ffint.h"
 
+#define       COPYRIGHT_SYMBOL        ((int8_t)0xA9)
+
 /* parse atom header size */
-int32_t mp4ff_atom_get_size(const uint8_t *data)
+static int32_t mp4ff_atom_get_size(const int8_t *data)
 {
     uint32_t result;
     uint32_t a, b, c, d;
 
-    a = data[0];
-    b = data[1];
-    c = data[2];
-    d = data[3];
+    a = (uint8_t)data[0];
+    b = (uint8_t)data[1];
+    c = (uint8_t)data[2];
+    d = (uint8_t)data[3];
 
     result = (a<<24) | (b<<16) | (c<<8) | d;
     //if (result > 0 && result < 8) result = 8;
@@ -46,7 +51,7 @@
 }
 
 /* comnapre 2 atom names, returns 1 for equal, 0 for unequal */
-int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
+static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
                                   const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2)
 {
     if (a1 == a2 && b1 == b2 && c1 == c2 && d1 == d2)
@@ -55,7 +60,7 @@
         return 0;
 }
 
-uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b,
+static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b,
                                        const int8_t c, const int8_t d)
 {
     if (a == 'm')
@@ -91,6 +96,16 @@
             return ATOM_TRACK;
         else if (mp4ff_atom_compare(a,b,c,d, 't','m','p','o'))
             return ATOM_TEMPO;
+        else if (mp4ff_atom_compare(a,b,c,d, 't','v','n','n'))
+            return ATOM_NETWORK;
+        else if (mp4ff_atom_compare(a,b,c,d, 't','v','s','h'))
+            return ATOM_SHOW;
+        else if (mp4ff_atom_compare(a,b,c,d, 't','v','e','n'))
+            return ATOM_EPISODENAME;
+        else if (mp4ff_atom_compare(a,b,c,d, 't','v','s','n'))
+            return ATOM_SEASON;
+        else if (mp4ff_atom_compare(a,b,c,d, 't','v','e','s'))
+            return ATOM_EPISODE;
     } else if (a == 's') {
         if (mp4ff_atom_compare(a,b,c,d, 's','t','b','l'))
             return ATOM_STBL;
@@ -114,23 +129,39 @@
             return ATOM_SINF;
         else if (mp4ff_atom_compare(a,b,c,d, 's','c','h','i'))
             return ATOM_SCHI;
-    } else if (a == '©') {
-        if (mp4ff_atom_compare(a,b,c,d, '©','n','a','m'))
+        else if (mp4ff_atom_compare(a,b,c,d, 's','o','n','m'))
+            return ATOM_SORTTITLE;
+        else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','l'))
+            return ATOM_SORTALBUM;
+        else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','r'))
+            return ATOM_SORTARTIST;
+        else if (mp4ff_atom_compare(a,b,c,d, 's','o','a','a'))
+            return ATOM_SORTALBUMARTIST;
+        else if (mp4ff_atom_compare(a,b,c,d, 's','o','c','o'))
+            return ATOM_SORTWRITER;
+        else if (mp4ff_atom_compare(a,b,c,d, 's','o','s','n'))
+            return ATOM_SORTSHOW;
+    } else if (a == COPYRIGHT_SYMBOL) {
+        if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'n','a','m'))
             return ATOM_TITLE;
-        else if (mp4ff_atom_compare(a,b,c,d, '©','A','R','T'))
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'A','R','T'))
             return ATOM_ARTIST;
-        else if (mp4ff_atom_compare(a,b,c,d, '©','w','r','t'))
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'w','r','t'))
             return ATOM_WRITER;
-        else if (mp4ff_atom_compare(a,b,c,d, '©','a','l','b'))
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'a','l','b'))
             return ATOM_ALBUM;
-        else if (mp4ff_atom_compare(a,b,c,d, '©','d','a','y'))
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'d','a','y'))
             return ATOM_DATE;
-        else if (mp4ff_atom_compare(a,b,c,d, '©','t','o','o'))
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'t','o','o'))
             return ATOM_TOOL;
-        else if (mp4ff_atom_compare(a,b,c,d, '©','c','m','t'))
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'c','m','t'))
             return ATOM_COMMENT;
-        else if (mp4ff_atom_compare(a,b,c,d, '©','g','e','n'))
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'g','e','n'))
             return ATOM_GENRE1;
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'g','r','p'))
+            return ATOM_CONTENTGROUP;
+        else if (mp4ff_atom_compare(a,b,c,d, COPYRIGHT_SYMBOL,'l','y','r'))
+            return ATOM_LYRICS;
     }
 
     if (mp4ff_atom_compare(a,b,c,d, 'e','d','t','s'))
@@ -158,18 +189,30 @@
     else if (mp4ff_atom_compare(a,b,c,d, 'g','n','r','e'))
         return ATOM_GENRE2;
     else if (mp4ff_atom_compare(a,b,c,d, 'c','o','v','r'))
-		return ATOM_COVER;
+        return ATOM_COVER;
     else if (mp4ff_atom_compare(a,b,c,d, 'c','p','i','l'))
         return ATOM_COMPILATION;
     else if (mp4ff_atom_compare(a,b,c,d, 'c','t','t','s'))
-		return ATOM_CTTS;
+        return ATOM_CTTS;
+    else if (mp4ff_atom_compare(a,b,c,d, 'd','r','m','s'))
+        return ATOM_DRMS;
     else if (mp4ff_atom_compare(a,b,c,d, 'f','r','m','a'))
-		return ATOM_FRMA;
+        return ATOM_FRMA;
     else if (mp4ff_atom_compare(a,b,c,d, 'p','r','i','v'))
-		return ATOM_PRIV;
+        return ATOM_PRIV;
     else if (mp4ff_atom_compare(a,b,c,d, 'i','v','i','v'))
-		return ATOM_IVIV;
-	else
+        return ATOM_IVIV;
+    else if (mp4ff_atom_compare(a,b,c,d, 'u','s','e','r'))
+        return ATOM_USER;
+    else if (mp4ff_atom_compare(a,b,c,d, 'k','e','y',' '))
+        return ATOM_KEY;
+    else if (mp4ff_atom_compare(a,b,c,d, 'a','A','R','T'))
+        return ATOM_ALBUM_ARTIST;
+    else if (mp4ff_atom_compare(a,b,c,d, 'd','e','s','c'))
+        return ATOM_DESCRIPTION;
+    else if (mp4ff_atom_compare(a,b,c,d, 'p','c','s','t'))
+        return ATOM_PODCAST;
+    else
         return ATOM_UNKNOWN;
 }
 
@@ -178,7 +221,7 @@
 {
     uint64_t size;
     int32_t ret;
-    uint8_t atom_header[8];
+    int8_t atom_header[8];
 
     ret = mp4ff_read_data(f, atom_header, 8);
     if (ret != 8)
@@ -201,7 +244,7 @@
     return size;
 }
 
-int32_t mp4ff_read_stsz(mp4ff_t *f)
+static int32_t mp4ff_read_stsz(mp4ff_t *f)
 {
     mp4ff_read_char(f); /* version */
     mp4ff_read_int24(f); /* flags */
@@ -223,11 +266,11 @@
     return 0;
 }
 
-int32_t mp4ff_read_esds(mp4ff_t *f)
+static int32_t mp4ff_read_esds(mp4ff_t *f)
 {
     uint8_t tag;
-	uint32_t temp;
-	
+    uint32_t temp;
+
     mp4ff_read_char(f); /* version */
     mp4ff_read_int24(f); /* flags */
 
@@ -254,14 +297,14 @@
     }
 
     /* read length */
-	temp = mp4ff_read_mp4_descr_length(f);
+    temp = mp4ff_read_mp4_descr_length(f);
     if (temp < 13) return 1;
 
-	f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
+    f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
     mp4ff_read_int32(f);//0x15000414 ????
     f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f);
     f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f);
-    
+
     /* get and verify DecSpecificInfoTag */
     if (mp4ff_read_char(f) != 0x05)
     {
@@ -269,7 +312,7 @@
     }
 
     /* read length */
-    f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f); 
+    f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f);
 
     if (f->track[f->total_tracks - 1]->decoderConfig)
         free(f->track[f->total_tracks - 1]->decoderConfig);
@@ -285,7 +328,7 @@
     return 0;
 }
 
-int32_t mp4ff_read_mp4a(mp4ff_t *f)
+static int32_t mp4ff_read_mp4a(mp4ff_t *f)
 {
     uint64_t size;
     int32_t i;
@@ -320,7 +363,7 @@
     return 0;
 }
 
-int32_t mp4ff_read_stsd(mp4ff_t *f)
+static int32_t mp4ff_read_stsd(mp4ff_t *f)
 {
     int32_t i;
     uint8_t header_size = 0;
@@ -356,12 +399,12 @@
     return 0;
 }
 
-int32_t mp4ff_read_stsc(mp4ff_t *f)
+static int32_t mp4ff_read_stsc(mp4ff_t *f)
 {
     int32_t i;
 
-    mp4ff_read_char(f); /* version */ 
-    mp4ff_read_int24(f); /* flags */ 
+    mp4ff_read_char(f); /* version */
+    mp4ff_read_int24(f); /* flags */
     f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
 
     f->track[f->total_tracks - 1]->stsc_first_chunk =
@@ -381,7 +424,7 @@
     return 0;
 }
 
-int32_t mp4ff_read_stco(mp4ff_t *f)
+static int32_t mp4ff_read_stco(mp4ff_t *f)
 {
     int32_t i;
 
@@ -400,12 +443,12 @@
     return 0;
 }
 
-int32_t mp4ff_read_ctts(mp4ff_t *f)
+static int32_t mp4ff_read_ctts(mp4ff_t *f)
 {
     int32_t i;
-	mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
+    mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
 
-	if (p_track->ctts_entry_count) return 0;
+    if (p_track->ctts_entry_count) return 0;
 
     mp4ff_read_char(f); /* version */
     mp4ff_read_int24(f); /* flags */
@@ -414,30 +457,30 @@
     p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
     p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
 
-	if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
-	{
-		if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;}
-		if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;}
-		p_track->ctts_entry_count = 0;
-		return 0;
-	}
-	else
-	{
-		for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
-		{
-			p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
-			p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
-		}
-		return 1;
-	}
+    if (p_track->ctts_sample_count == 0 || p_track->ctts_sample_offset == 0)
+    {
+        if (p_track->ctts_sample_count) {free(p_track->ctts_sample_count);p_track->ctts_sample_count=0;}
+        if (p_track->ctts_sample_offset) {free(p_track->ctts_sample_offset);p_track->ctts_sample_offset=0;}
+        p_track->ctts_entry_count = 0;
+        return 0;
+    }
+    else
+    {
+        for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
+        {
+            p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
+            p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
+        }
+        return 1;
+    }
 }
 
-int32_t mp4ff_read_stts(mp4ff_t *f)
+static int32_t mp4ff_read_stts(mp4ff_t *f)
 {
     int32_t i;
-	mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
+    mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
 
-	if (p_track->stts_entry_count) return 0;
+    if (p_track->stts_entry_count) return 0;
 
     mp4ff_read_char(f); /* version */
     mp4ff_read_int24(f); /* flags */
@@ -445,26 +488,26 @@
 
     p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
     p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
-	
-	if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
-	{
-		if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;}
-		if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;}
-		p_track->stts_entry_count = 0;
-		return 0;
-	}
-	else
-	{
-		for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
-		{
-			p_track->stts_sample_count[i] = mp4ff_read_int32(f);
-			p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
-		}
-		return 1;
-	}
+
+    if (p_track->stts_sample_count == 0 || p_track->stts_sample_delta == 0)
+    {
+        if (p_track->stts_sample_count) {free(p_track->stts_sample_count);p_track->stts_sample_count=0;}
+        if (p_track->stts_sample_delta) {free(p_track->stts_sample_delta);p_track->stts_sample_delta=0;}
+        p_track->stts_entry_count = 0;
+        return 0;
+    }
+    else
+    {
+        for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
+        {
+            p_track->stts_sample_count[i] = mp4ff_read_int32(f);
+            p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
+        }
+        return 1;
+    }
 }
 
-int32_t mp4ff_read_mvhd(mp4ff_t *f)
+static int32_t mp4ff_read_mvhd(mp4ff_t *f)
 {
     int32_t i;
 
@@ -496,76 +539,76 @@
 }
 
 #if 0
-int32_t mp4ff_read_tkhd(mp4ff_t *f)
+static int32_t mp4ff_read_tkhd(mp4ff_t *f)
 {
-	uint8_t version;
-	uint32_t flags;
+    uint8_t version;
+    uint32_t flags;
     version = mp4ff_read_char(f); /* version */
     flags = mp4ff_read_int24(f); /* flags */
-	if (version==1)
-	{
-		mp4ff_read_int64(f);//creation-time
-		mp4ff_read_int64(f);//modification-time
-		mp4ff_read_int32(f);//track-id
-		mp4ff_read_int32(f);//reserved
-		f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
-	}
-	else //version == 0
-	{
-		mp4ff_read_int32(f);//creation-time
-		mp4ff_read_int32(f);//modification-time
-		mp4ff_read_int32(f);//track-id
-		mp4ff_read_int32(f);//reserved
-		f->track[f->total_tracks - 1]->duration = mp4ff_read_int32(f);//duration
-		if (f->track[f->total_tracks - 1]->duration == 0xFFFFFFFF)
-			f->track[f->total_tracks - 1]->duration = 0xFFFFFFFFFFFFFFFF;
+    if (version==1)
+    {
+        mp4ff_read_int64(f);//creation-time
+        mp4ff_read_int64(f);//modification-time
+        mp4ff_read_int32(f);//track-id
+        mp4ff_read_int32(f);//reserved
+        f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
+    }
+    else //version == 0
+    {
+        mp4ff_read_int32(f);//creation-time
+        mp4ff_read_int32(f);//modification-time
+        mp4ff_read_int32(f);//track-id
+        mp4ff_read_int32(f);//reserved
+        f->track[f->total_tracks - 1]->duration = mp4ff_read_int32(f);//duration
+        if (f->track[f->total_tracks - 1]->duration == 0xFFFFFFFF)
+            f->track[f->total_tracks - 1]->duration = 0xFFFFFFFFFFFFFFFF;
 
-	}
-	mp4ff_read_int32(f);//reserved
-	mp4ff_read_int32(f);//reserved
-	mp4ff_read_int16(f);//layer
-	mp4ff_read_int16(f);//pre-defined
-	mp4ff_read_int16(f);//volume
-	mp4ff_read_int16(f);//reserved
-	
-	//matrix
-	mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
-	mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
-	mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
-	mp4ff_read_int32(f);//width
-	mp4ff_read_int32(f);//height
-	return 1;
+    }
+    mp4ff_read_int32(f);//reserved
+    mp4ff_read_int32(f);//reserved
+    mp4ff_read_int16(f);//layer
+    mp4ff_read_int16(f);//pre-defined
+    mp4ff_read_int16(f);//volume
+    mp4ff_read_int16(f);//reserved
+
+    //matrix
+    mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
+    mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
+    mp4ff_read_int32(f); mp4ff_read_int32(f); mp4ff_read_int32(f);
+    mp4ff_read_int32(f);//width
+    mp4ff_read_int32(f);//height
+    return 1;
 }
 #endif
 
-int32_t mp4ff_read_mdhd(mp4ff_t *f)
+static int32_t mp4ff_read_mdhd(mp4ff_t *f)
 {
-	uint32_t version;
+    uint32_t version;
 
-	version = mp4ff_read_int32(f);
-	if (version==1)
-	{
-		mp4ff_read_int64(f);//creation-time
-		mp4ff_read_int64(f);//modification-time
-		f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
-		f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
-	}
-	else //version == 0
-	{
-		uint32_t temp;
+    version = mp4ff_read_int32(f);
+    if (version==1)
+    {
+        mp4ff_read_int64(f);//creation-time
+        mp4ff_read_int64(f);//modification-time
+        f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
+        f->track[f->total_tracks - 1]->duration = mp4ff_read_int64(f);//duration
+    }
+    else //version == 0
+    {
+        uint32_t temp;
 
-		mp4ff_read_int32(f);//creation-time
-		mp4ff_read_int32(f);//modification-time
-		f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
-		temp = mp4ff_read_int32(f);
-		f->track[f->total_tracks - 1]->duration = (temp == (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp);
-	}
-	mp4ff_read_int16(f);
-	mp4ff_read_int16(f);
-	return 1;
+        mp4ff_read_int32(f);//creation-time
+        mp4ff_read_int32(f);//modification-time
+        f->track[f->total_tracks - 1]->timeScale = mp4ff_read_int32(f);//timescale
+        temp = mp4ff_read_int32(f);
+        f->track[f->total_tracks - 1]->duration = (temp == (uint32_t)(-1)) ? (uint64_t)(-1) : (uint64_t)(temp);
+    }
+    mp4ff_read_int16(f);
+    mp4ff_read_int16(f);
+    return 1;
 }
 #ifdef USE_TAGGING
-int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
+static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
 {
     uint64_t subsize, sumsize = 0;
     uint8_t atom_type;
@@ -574,9 +617,11 @@
     mp4ff_read_char(f); /* version */
     mp4ff_read_int24(f); /* flags */
 
-    while (sumsize < (size-12))
+    while (sumsize < (size-(header_size+4)))
     {
         subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
+        if (subsize <= header_size+4)
+            return 1;
         if (atom_type == ATOM_ILST)
         {
             mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4)));
@@ -592,7 +637,7 @@
 
 int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type)
 {
-	uint64_t dest_position = mp4ff_position(f)+size-8;
+    uint64_t dest_position = mp4ff_position(f)+size-8;
     if (atom_type == ATOM_STSZ)
     {
         /* sample size box */
@@ -600,9 +645,9 @@
     } else if (atom_type == ATOM_STTS) {
         /* time to sample box */
         mp4ff_read_stts(f);
-	} else if (atom_type == ATOM_CTTS) {
-		/* composition offset box */
-		mp4ff_read_ctts(f);
+    } else if (atom_type == ATOM_CTTS) {
+        /* composition offset box */
+        mp4ff_read_ctts(f);
     } else if (atom_type == ATOM_STSC) {
         /* sample to chunk box */
         mp4ff_read_stsc(f);
@@ -618,24 +663,13 @@
     } else if (atom_type == ATOM_MDHD) {
         /* track header */
         mp4ff_read_mdhd(f);
-#ifdef ITUNES_DRM
-    } else if (atom_type == ATOM_FRMA) {
-        /* DRM track format */
-        mp4ff_read_frma(f);
-    } else if (atom_type == ATOM_IVIV) {
-        mp4ff_read_iviv(f, size-8);
-    } else if (atom_type == ATOM_NAME) {
-        mp4ff_read_name(f, size-8);
-    } else if (atom_type == ATOM_PRIV) {
-        mp4ff_read_priv(f, size-8);
-#endif
 #ifdef USE_TAGGING
     } else if (atom_type == ATOM_META) {
         /* iTunes Metadata box */
         mp4ff_read_meta(f, size);
 #endif
     }
-     
+
     mp4ff_set_position(f, dest_position);
 
 
--- a/src/aac/mp4ff/mp4ff.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4ff.c	Wed Apr 08 22:16:01 2009 +0100
@@ -1,28 +1,31 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4ff.c,v 1.15 2004/01/11 15:52:18 menno Exp $
+** $Id: mp4ff.c,v 1.22 2009/01/26 23:01:40 menno Exp $
 **/
 
 #include <stdlib.h>
@@ -37,7 +40,20 @@
 
     ff->stream = f;
 
-    parse_atoms(ff);
+    parse_atoms(ff,0);
+
+    return ff;
+}
+
+mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f)
+{
+    mp4ff_t *ff = malloc(sizeof(mp4ff_t));
+
+    memset(ff, 0, sizeof(mp4ff_t));
+
+    ff->stream = f;
+
+    parse_atoms(ff,1);
 
     return ff;
 }
@@ -70,6 +86,10 @@
 				free(ff->track[i]->ctts_sample_count);
 			if (ff->track[i]->ctts_sample_offset)
 				free(ff->track[i]->ctts_sample_offset);
+#ifdef ITUNES_DRM
+            if (ff->track[i]->p_drms)
+                drms_free(ff->track[i]->p_drms);
+#endif
             free(ff->track[i]);
         }
     }
@@ -90,8 +110,35 @@
     memset(f->track[f->total_tracks - 1], 0, sizeof(mp4ff_track_t));
 }
 
+static int need_parse_when_meta_only(uint8_t atom_type)
+{
+	switch(atom_type)
+	{
+	case ATOM_EDTS:
+//	case ATOM_MDIA:
+//	case ATOM_MINF:
+	case ATOM_DRMS:
+	case ATOM_SINF:
+	case ATOM_SCHI:
+//	case ATOM_STBL:
+//	case ATOM_STSD:
+	case ATOM_STTS:
+	case ATOM_STSZ:
+	case ATOM_STZ2:
+	case ATOM_STCO:
+	case ATOM_STSC:
+//	case ATOM_CTTS:
+	case ATOM_FRMA:
+	case ATOM_IVIV:
+	case ATOM_PRIV:
+		return 0;
+	default:
+		return 1;
+	}
+}
+
 /* parse atoms that are sub atoms of other atoms */
-int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size)
+int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only)
 {
     uint64_t size;
     uint8_t atom_type = 0;
@@ -116,9 +163,12 @@
         }
 
         /* parse subatoms */
-        if (atom_type < SUBATOMIC)
+		if (meta_only && !need_parse_when_meta_only(atom_type))
+		{
+			mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
+		} else if (atom_type < SUBATOMIC)
         {
-            parse_sub_atoms(f, size-header_size);
+            parse_sub_atoms(f, size-header_size,meta_only);
         } else {
             mp4ff_atom_read(f, (uint32_t)size, atom_type);
         }
@@ -128,7 +178,7 @@
 }
 
 /* parse root atoms */
-int32_t parse_atoms(mp4ff_t *f)
+int32_t parse_atoms(mp4ff_t *f,int meta_only)
 {
     uint64_t size;
     uint8_t atom_type = 0;
@@ -141,6 +191,13 @@
         f->file_size += size;
         f->last_atom = atom_type;
 
+        if (atom_type == ATOM_MDAT && f->moov_read)
+        {
+            /* moov atom is before mdat, we can stop reading when mdat is encountered */
+            /* file position will stay at beginning of mdat data */
+//            break;
+        }
+
         if (atom_type == ATOM_MOOV && size > header_size)
         {
             f->moov_read = 1;
@@ -149,9 +206,12 @@
         }
 
         /* parse subatoms */
-        if (atom_type < SUBATOMIC)
+		if (meta_only && !need_parse_when_meta_only(atom_type))
+		{
+			mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
+		} else if (atom_type < SUBATOMIC)
         {
-            parse_sub_atoms(f, size-header_size);
+            parse_sub_atoms(f, size-header_size,meta_only);
         } else {
             /* skip this atom */
             mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
@@ -164,7 +224,7 @@
 int32_t mp4ff_get_decoder_config(const mp4ff_t *f, const int32_t track,
                                  uint8_t** ppBuf, uint32_t* pBufSize)
 {
-    if (track < 0 || track >= f->total_tracks)
+    if (track >= f->total_tracks)
     {
         *ppBuf = NULL;
         *pBufSize = 0;
@@ -191,10 +251,7 @@
 
 int32_t mp4ff_get_track_type(const mp4ff_t *f, const int track)
 {
-    if (track < 0)
-	return -1;
-
-    return f->track[track]->type;
+	return f->track[track]->type;
 }
 
 int32_t mp4ff_total_tracks(const mp4ff_t *f)
@@ -204,34 +261,22 @@
 
 int32_t mp4ff_time_scale(const mp4ff_t *f, const int32_t track)
 {
-    if (track < 0)
-	return -1;
-
     return f->track[track]->timeScale;
 }
 
 uint32_t mp4ff_get_avg_bitrate(const mp4ff_t *f, const int32_t track)
 {
-    if (track < 0)
-	return -1;
-
 	return f->track[track]->avgBitrate;
 }
 
 uint32_t mp4ff_get_max_bitrate(const mp4ff_t *f, const int32_t track)
 {
-    if (track < 0)
-	return -1;
-
 	return f->track[track]->maxBitrate;
 }
 
 int64_t mp4ff_get_track_duration(const mp4ff_t *f, const int32_t track)
 {
-    if (track < 0)
-	return -1;
-
-    return f->track[track]->duration;
+	return f->track[track]->duration;
 }
 
 int64_t mp4ff_get_track_duration_use_offsets(const mp4ff_t *f, const int32_t track)
@@ -252,9 +297,6 @@
     int32_t i;
     int32_t total = 0;
 
-    if (track < 0)
-	return -1;
-
     for (i = 0; i < f->track[track]->stts_entry_count; i++)
     {
         total += f->track[track]->stts_sample_count[i];
@@ -396,6 +438,12 @@
         return 0;
 	}
 
+#ifdef ITUNES_DRM
+    if (f->track[track]->p_drms != NULL)
+    {
+        drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
+    }
+#endif
 
     return *bytes;
 }
@@ -409,6 +457,13 @@
 	mp4ff_set_sample_position(f, track, sample);
 	result = mp4ff_read_data(f,buffer,size);
 
+#ifdef ITUNES_DRM
+    if (f->track[track]->p_drms != NULL)
+    {
+        drms_decrypt(f->track[track]->p_drms, (uint32_t*)buffer, size);
+    }
+#endif
+
     return result;
 }
 
--- a/src/aac/mp4ff/mp4ff.h	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4ff.h	Wed Apr 08 22:16:01 2009 +0100
@@ -1,28 +1,31 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4ff.h,v 1.19 2004/01/11 15:52:18 menno Exp $
+** $Id: mp4ff.h,v 1.27 2009/01/29 00:41:08 menno Exp $
 **/
 
 #ifndef MP4FF_H
@@ -32,7 +35,11 @@
 extern "C" {
 #endif /* __cplusplus */
 
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else
 #include "mp4ff_int_types.h"
+#endif
 
 /* file callback structure */
 typedef struct
@@ -51,6 +58,7 @@
 /* API */
 
 mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
+mp4ff_t *mp4ff_open_read_metaonly(mp4ff_callback_t *f);
 void mp4ff_close(mp4ff_t *f);
 int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
 int32_t mp4ff_get_sample_duration_use_offsets(const mp4ff_t *f, const int32_t track, const int32_t sample);
@@ -87,7 +95,6 @@
 int mp4ff_meta_get_num_items(const mp4ff_t *f);
 int mp4ff_meta_get_by_index(const mp4ff_t *f, unsigned int index,
                             char **item, char **value);
-int mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value);
 int mp4ff_meta_get_title(const mp4ff_t *f, char **value);
 int mp4ff_meta_get_artist(const mp4ff_t *f, char **value);
 int mp4ff_meta_get_writer(const mp4ff_t *f, char **value);
@@ -98,6 +105,8 @@
 int mp4ff_meta_get_genre(const mp4ff_t *f, char **value);
 int mp4ff_meta_get_track(const mp4ff_t *f, char **value);
 int mp4ff_meta_get_disc(const mp4ff_t *f, char **value);
+int mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value);
+int mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value);
 int mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
 int mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
 int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
@@ -108,7 +117,6 @@
 {
     char *item;
     char *value;
-    uint32_t value_length;
 } mp4ff_tag_t;
 
 /* metadata list structure */
@@ -128,4 +136,3 @@
 #endif /* __cplusplus */
 
 #endif
-
--- a/src/aac/mp4ff/mp4ff_int_types.h	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4ff_int_types.h	Wed Apr 08 22:16:01 2009 +0100
@@ -1,32 +1,27 @@
-#include "../../../config.h"
-
 #ifndef _MP4FF_INT_TYPES_H_
 #define _MP4FF_INT_TYPES_H_
 
-#ifdef _WIN32
+#if defined (_WIN32)
 
-typedef char int8_t;
+#ifdef __MINGW32__
+#include <stdlib.h>
+#endif /* #ifdef __MINGW32__ */
+
+typedef signed char int8_t;
 typedef unsigned char uint8_t;
-typedef short int16_t;
+typedef signed short int16_t;
 typedef unsigned short uint16_t;
-typedef long int32_t;
+typedef signed long int32_t;
 typedef unsigned long uint32_t;
 
-typedef __int64 int64_t;
+typedef signed __int64 int64_t;
 typedef unsigned __int64 uint64_t;
 
 #else
 
-#if HAVE_STDINT_H
-# include <stdint.h>
-#else
-# if HAVE_INTTYPES_H
-# include <inttypes.h>
-# endif
-#endif
+#include <stdint.h>
 
 #endif
 
 
 #endif
-
--- a/src/aac/mp4ff/mp4ffint.h	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4ffint.h	Wed Apr 08 22:16:01 2009 +0100
@@ -1,28 +1,31 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4ffint.h,v 1.15 2004/01/14 20:50:22 menno Exp $
+** $Id: mp4ffint.h,v 1.26 2009/01/25 20:14:34 menno Exp $
 **/
 
 #ifndef MP4FF_INTERNAL_H
@@ -33,12 +36,7 @@
 #endif /* __cplusplus */
 
 #include "mp4ff_int_types.h"
-
-
-#ifdef _WIN32
-#define ITUNES_DRM
-#endif
-
+#include <stdlib.h>
 
 #define MAX_TRACKS 1024
 #define TRACK_UNKNOWN 0
@@ -76,6 +74,25 @@
 #define ATOM_FRMA 152
 #define ATOM_IVIV 153
 #define ATOM_PRIV 154
+#define ATOM_USER 155
+#define ATOM_KEY  156
+
+#define ATOM_ALBUM_ARTIST	157
+#define ATOM_CONTENTGROUP   158
+#define ATOM_LYRICS         159
+#define ATOM_DESCRIPTION    160
+#define ATOM_NETWORK        161
+#define ATOM_SHOW           162
+#define ATOM_EPISODENAME    163
+#define ATOM_SORTTITLE      164
+#define ATOM_SORTALBUM      165
+#define ATOM_SORTARTIST     166
+#define ATOM_SORTALBUMARTIST    167
+#define ATOM_SORTWRITER     168
+#define ATOM_SORTSHOW       169
+#define ATOM_SEASON         170
+#define ATOM_EPISODE        171
+#define ATOM_PODCAST        172
 
 #define ATOM_UNKNOWN 255
 #define ATOM_FREE ATOM_UNKNOWN
@@ -104,13 +121,19 @@
 #define ATOM_GENRE2 20
 #define ATOM_TEMPO 21
 #define ATOM_COVER 22
+#define ATOM_DRMS 23
 #define ATOM_SINF 24
 #define ATOM_SCHI 25
 
-#include "config.h"
+#ifdef HAVE_CONFIG_H
+#include "../../config.h"   
+#endif
 
-#ifndef _WIN32
+#if !(defined(_WIN32) || defined(_WIN32_WCE))
 #define stricmp strcasecmp
+#else
+#define stricmp _stricmp
+#define strdup _strdup
 #endif
 
 /* file callback structure */
@@ -119,7 +142,7 @@
     uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
     uint32_t (*write)(void *udata, void *buffer, uint32_t length);
     uint32_t (*seek)(void *user_data, uint64_t position);
-	uint32_t (*truncate)(void *user_data);
+    uint32_t (*truncate)(void *user_data);
     void *user_data;
 } mp4ff_callback_t;
 
@@ -129,7 +152,6 @@
 {
     char *item;
     char *value;
-    uint32_t value_length;
 } mp4ff_tag_t;
 
 /* metadata list structure */
@@ -146,50 +168,45 @@
     int32_t channelCount;
     int32_t sampleSize;
     uint16_t sampleRate;
-	int32_t audioType;
+    int32_t audioType;
 
     /* stsd */
     int32_t stsd_entry_count;
 
     /* stsz */
-	int32_t stsz_sample_size;
-	int32_t stsz_sample_count;
+    int32_t stsz_sample_size;
+    int32_t stsz_sample_count;
     int32_t *stsz_table;
 
     /* stts */
-	int32_t stts_entry_count;
+    int32_t stts_entry_count;
     int32_t *stts_sample_count;
     int32_t *stts_sample_delta;
 
     /* stsc */
-	int32_t stsc_entry_count;
+    int32_t stsc_entry_count;
     int32_t *stsc_first_chunk;
     int32_t *stsc_samples_per_chunk;
     int32_t *stsc_sample_desc_index;
 
     /* stsc */
-	int32_t stco_entry_count;
+    int32_t stco_entry_count;
     int32_t *stco_chunk_offset;
 
-	/* ctts */
-	int32_t ctts_entry_count;
-	int32_t *ctts_sample_count;
-	int32_t *ctts_sample_offset;
+    /* ctts */
+    int32_t ctts_entry_count;
+    int32_t *ctts_sample_count;
+    int32_t *ctts_sample_offset;
 
     /* esde */
     uint8_t *decoderConfig;
     int32_t decoderConfigLen;
 
-	uint32_t maxBitrate;
-	uint32_t avgBitrate;
-	
-	uint32_t timeScale;
-	uint64_t duration;
+    uint32_t maxBitrate;
+    uint32_t avgBitrate;
 
-#ifdef ITUNES_DRM
-    /* drms */
-    void *p_drms;
-#endif
+    uint32_t timeScale;
+    uint64_t duration;
 
 } mp4ff_track_t;
 
@@ -197,7 +214,7 @@
 typedef struct
 {
     /* stream to read from */
-	mp4ff_callback_t *stream;
+    mp4ff_callback_t *stream;
     int64_t current_position;
 
     int32_t moov_read;
@@ -224,8 +241,8 @@
 
 
 /* mp4util.c */
-int32_t mp4ff_read_data(mp4ff_t *f, uint8_t *data, uint32_t size);
-int32_t mp4ff_write_data(mp4ff_t *f, uint8_t *data, uint32_t size);
+int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size);
+int32_t mp4ff_write_data(mp4ff_t *f, int8_t *data, uint32_t size);
 uint64_t mp4ff_read_int64(mp4ff_t *f);
 uint32_t mp4ff_read_int32(mp4ff_t *f);
 uint32_t mp4ff_read_int24(mp4ff_t *f);
@@ -236,43 +253,43 @@
 int64_t mp4ff_position(const mp4ff_t *f);
 int32_t mp4ff_set_position(mp4ff_t *f, const int64_t position);
 int32_t mp4ff_truncate(mp4ff_t * f);
-unsigned char * mp4ff_read_string(mp4ff_t * f,uint32_t length);
+char * mp4ff_read_string(mp4ff_t * f,uint32_t length);
 
 /* mp4atom.c */
-int32_t mp4ff_atom_get_size(const uint8_t *data);
-int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
+static int32_t mp4ff_atom_get_size(const int8_t *data);
+static int32_t mp4ff_atom_compare(const int8_t a1, const int8_t b1, const int8_t c1, const int8_t d1,
                                   const int8_t a2, const int8_t b2, const int8_t c2, const int8_t d2);
-uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b, const int8_t c, const int8_t d);
+static uint8_t mp4ff_atom_name_to_type(const int8_t a, const int8_t b, const int8_t c, const int8_t d);
 uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size);
-int32_t mp4ff_read_stsz(mp4ff_t *f);
-int32_t mp4ff_read_esds(mp4ff_t *f);
-int32_t mp4ff_read_mp4a(mp4ff_t *f);
-int32_t mp4ff_read_stsd(mp4ff_t *f);
-int32_t mp4ff_read_stsc(mp4ff_t *f);
-int32_t mp4ff_read_stco(mp4ff_t *f);
-int32_t mp4ff_read_stts(mp4ff_t *f);
+static int32_t mp4ff_read_stsz(mp4ff_t *f);
+static int32_t mp4ff_read_esds(mp4ff_t *f);
+static int32_t mp4ff_read_mp4a(mp4ff_t *f);
+static int32_t mp4ff_read_stsd(mp4ff_t *f);
+static int32_t mp4ff_read_stsc(mp4ff_t *f);
+static int32_t mp4ff_read_stco(mp4ff_t *f);
+static int32_t mp4ff_read_stts(mp4ff_t *f);
 #ifdef USE_TAGGING
-int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size);
+static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size);
 #endif
 int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type);
 
 /* mp4sample.c */
-int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
+static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
                                      int32_t *chunk_sample, int32_t *chunk);
-int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk);
-int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
+static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk);
+static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
                                        const int32_t chunk_sample, const int32_t sample);
-int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
+static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample);
 int32_t mp4ff_audio_frame_size(const mp4ff_t *f, const int32_t track, const int32_t sample);
 int32_t mp4ff_set_sample_position(mp4ff_t *f, const int32_t track, const int32_t sample);
 
 #ifdef USE_TAGGING
 /* mp4meta.c */
-int32_t mp4ff_tag_add_field_len(mp4ff_metadata_t *tags, const char *item, const char *value, uint32_t valuelen);
-int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value);
-int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value);
-int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, unsigned char **name);
-int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size);
+static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value);
+static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value);
+static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name);
+static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size);
+static int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value);
 int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size);
 int32_t mp4ff_tag_delete(mp4ff_metadata_t *tags);
 int32_t mp4ff_meta_get_num_items(const mp4ff_t *f);
@@ -299,9 +316,9 @@
 mp4ff_t *mp4ff_open_edit(mp4ff_callback_t *f);
 #endif
 void mp4ff_close(mp4ff_t *ff);
-void mp4ff_track_add(mp4ff_t *f);
-int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size);
-int32_t parse_atoms(mp4ff_t *f);
+//void mp4ff_track_add(mp4ff_t *f);
+int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only);
+int32_t parse_atoms(mp4ff_t *f,int meta_only);
 
 int32_t mp4ff_get_sample_duration(const mp4ff_t *f, const int32_t track, const int32_t sample);
 int64_t mp4ff_get_sample_position(const mp4ff_t *f, const int32_t track, const int32_t sample);
@@ -317,7 +334,7 @@
 int32_t mp4ff_num_samples(const mp4ff_t *f, const int32_t track);
 
 uint32_t mp4ff_meta_genre_to_index(const char * genrestr);//returns 1-based index, 0 if not found
-const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to string
+const char * mp4ff_meta_index_to_genre(uint32_t idx);//returns pointer to static string
 
 
 #ifdef __cplusplus
--- a/src/aac/mp4ff/mp4meta.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4meta.c	Wed Apr 08 22:16:01 2009 +0100
@@ -1,28 +1,31 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4meta.c,v 1.13 2004/01/11 15:52:18 menno Exp $
+** $Id: mp4meta.c,v 1.21 2009/01/19 23:56:30 menno Exp $
 **/
 
 #ifdef USE_TAGGING
@@ -32,7 +35,9 @@
 #include <string.h>
 #include "mp4ffint.h"
 
-int32_t mp4ff_tag_add_field_len(mp4ff_metadata_t *tags, const char *item, const char *value, uint32_t valuelen)
+
+
+static int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value)
 {
     void *backup = (void *)tags->tags;
 
@@ -45,13 +50,7 @@
         return 0;
     } else {
         tags->tags[tags->count].item = strdup(item);
-
-	/* ugly hack to make covers work */	
-        tags->tags[tags->count].value = malloc(valuelen+1);
-	memcpy(tags->tags[tags->count].value, value, valuelen);
-        tags->tags[tags->count].value[valuelen] = '\0';
-
-	tags->tags[tags->count].value_length = valuelen;
+        tags->tags[tags->count].value = strdup(value);
 
         if (!tags->tags[tags->count].item || !tags->tags[tags->count].value)
         {
@@ -59,7 +58,6 @@
             if (!tags->tags[tags->count].value) free (tags->tags[tags->count].value);
             tags->tags[tags->count].item = NULL;
             tags->tags[tags->count].value = NULL;
-            tags->tags[tags->count].value_length = 0;
             return 0;
         }
 
@@ -68,12 +66,7 @@
     }
 }
 
-int32_t mp4ff_tag_add_field(mp4ff_metadata_t *tags, const char *item, const char *value)
-{
-	return mp4ff_tag_add_field_len(tags, item, value, strlen(value));
-}
-
-int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value)
+static int32_t mp4ff_tag_set_field(mp4ff_metadata_t *tags, const char *item, const char *value)
 {
     unsigned int i;
 
@@ -85,7 +78,6 @@
         {
 			free(tags->tags[i].value);
 			tags->tags[i].value = strdup(value);
-			tags->tags[i].value_length = strlen(value);
             return 1;
         }
     }
@@ -111,7 +103,7 @@
     return 0;
 }
 
-const char* ID3v1GenreList[] = {
+static const char* ID3v1GenreList[] = {
     "Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk",
     "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies",
     "Other", "Pop", "R&B", "Rap", "Reggae", "Rock",
@@ -163,7 +155,7 @@
 }
 
 
-int32_t TrackToString(char** str, const uint16_t track, const uint16_t totalTracks)
+static int32_t TrackToString(char** str, const uint16_t track, const uint16_t totalTracks)
 {
 	char temp[32];
     sprintf(temp, "%.5u of %.5u", track, totalTracks);
@@ -171,12 +163,18 @@
     return 0;
 }
 
-int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, unsigned char **name)
+static int32_t mp4ff_set_metadata_name(mp4ff_t *f, const uint8_t atom_type, char **name)
 {
-    char *tag_names[] = {
+    static char *tag_names[] = {
         "unknown", "title", "artist", "writer", "album",
         "date", "tool", "comment", "genre", "track",
-        "disc", "compilation", "genre", "tempo", "cover"
+        "disc", "compilation", "genre", "tempo", "cover",
+		"album_artist", "contentgroup", "lyrics", "description",
+        "network", "show", "episodename",
+        "sorttitle", "sortalbum", "sortartist", "sortalbumartist",
+        "sortwriter", "sortshow",
+        "season", "episode", "podcast"
+
     };
     uint8_t tag_idx = 0;
 
@@ -196,23 +194,39 @@
     case ATOM_GENRE2: tag_idx = 12; break;
     case ATOM_TEMPO: tag_idx = 13; break;
     case ATOM_COVER: tag_idx = 14; break;
+	case ATOM_ALBUM_ARTIST: tag_idx = 15; break;
+    case ATOM_CONTENTGROUP: tag_idx = 16; break;
+    case ATOM_LYRICS: tag_idx = 17; break;
+    case ATOM_DESCRIPTION: tag_idx = 18; break;
+    case ATOM_NETWORK: tag_idx = 19; break;
+    case ATOM_SHOW: tag_idx = 20; break;
+    case ATOM_EPISODENAME: tag_idx = 21; break;
+    case ATOM_SORTTITLE: tag_idx = 22; break;
+    case ATOM_SORTALBUM: tag_idx = 23; break;
+    case ATOM_SORTARTIST: tag_idx = 24; break;
+    case ATOM_SORTALBUMARTIST: tag_idx = 25; break;
+    case ATOM_SORTWRITER: tag_idx = 26; break;
+    case ATOM_SORTSHOW: tag_idx = 27; break;
+    case ATOM_SEASON: tag_idx = 28; break;
+    case ATOM_EPISODE: tag_idx = 29; break;
+    case ATOM_PODCAST: tag_idx = 30; break;
     default: tag_idx = 0; break;
     }
 
-	*name = (unsigned char*)strdup(tag_names[tag_idx]);
+	*name = strdup(tag_names[tag_idx]);
 
     return 0;
 }
 
-int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size)
+static int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size)
 {
     uint8_t atom_type;
     uint8_t header_size = 0;
     uint64_t subsize, sumsize = 0;
-    unsigned char * name = NULL;
-    unsigned char * data = NULL;
-    uint32_t datalen = 0;
-    uint32_t done = 0;
+    char * name = NULL;
+	char * data = NULL;
+	uint32_t done = 0;
+
 
     while (sumsize < size)
     {
@@ -251,14 +265,22 @@
 						done = 1;
 					}
 				} else if (parent_atom_type == ATOM_TRACK || parent_atom_type == ATOM_DISC) {
-					if (!done && subsize - header_size >= 8 + 8)
+					/* if (!done && subsize - header_size >= 8 + 8) */
+					/* modified by AJS */
+					if ( !done && (subsize - header_size) >=
+						(sizeof(char) + sizeof(uint8_t)*3 + sizeof(uint32_t) + /* version + flags + reserved */
+						+ sizeof(uint16_t) /* leading uint16_t */
+						+ sizeof(uint16_t) /* track / disc */
+						+ sizeof(uint16_t)) /* totaltracks / totaldiscs */
+						)
 					{
 						uint16_t index,total;
 						char temp[32];
 						mp4ff_read_int16(f);
 						index = mp4ff_read_int16(f);
 						total = mp4ff_read_int16(f);
-						mp4ff_read_int16(f);
+  						/* modified by AJS */
+						/* mp4ff_read_int16(f); */
 
 						sprintf(temp,"%d",index);
 						mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "track" : "disc", temp);
@@ -273,7 +295,6 @@
 				{
 					if (data) {free(data);data = NULL;}
 					data = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+8)));
-					datalen = (uint32_t)(subsize-(header_size+8));
 				}
 			} else if (atom_type == ATOM_NAME) {
 				if (!done)
@@ -294,7 +315,7 @@
 		if (!done)
 		{
 			if (name == NULL) mp4ff_set_metadata_name(f, parent_atom_type, &name);
-			if (name) mp4ff_tag_add_field_len(&(f->tags), (char *)name, (char *)data, datalen);
+			if (name) mp4ff_tag_add_field(&(f->tags), name, data);
 		}
 
 		free(data);
@@ -312,6 +333,8 @@
     while (sumsize < size)
     {
         subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
+        if (subsize == 0)
+            break;
         mp4ff_parse_tag(f, atom_type, (uint32_t)(subsize-header_size));
         sumsize += subsize;
     }
@@ -321,7 +344,7 @@
 
 /* find a metadata item by name */
 /* returns 0 if item found, 1 if no such item */
-int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value)
+static int32_t mp4ff_meta_find_by_name(const mp4ff_t *f, const char *item, char **value)
 {
     uint32_t i;
 
@@ -329,13 +352,8 @@
     {
         if (!stricmp(f->tags.tags[i].item, item))
         {
-	    uint32_t value_length = f->tags.tags[i].value_length;
-	    
-	    if (value_length > 0) {
-		    *value = malloc(value_length+1);
-		    memcpy(*value, f->tags.tags[i].value, value_length+1);
-		    return value_length;
-	    }
+			*value = strdup(f->tags.tags[i].value);
+            return 1;
         }
     }
 
@@ -410,11 +428,21 @@
     return mp4ff_meta_find_by_name(f, "track", value);
 }
 
+int32_t mp4ff_meta_get_totaltracks(const mp4ff_t *f, char **value)
+{
+    return mp4ff_meta_find_by_name(f, "totaltracks", value);
+}
+
 int32_t mp4ff_meta_get_disc(const mp4ff_t *f, char **value)
 {
     return mp4ff_meta_find_by_name(f, "disc", value);
 }
 
+int32_t mp4ff_meta_get_totaldiscs(const mp4ff_t *f, char **value)
+{
+    return mp4ff_meta_find_by_name(f, "totaldiscs", value);
+}
+
 int32_t mp4ff_meta_get_compilation(const mp4ff_t *f, char **value)
 {
     return mp4ff_meta_find_by_name(f, "compilation", value);
@@ -430,4 +458,4 @@
     return mp4ff_meta_find_by_name(f, "cover", value);
 }
 
-#endif
+#endif
\ No newline at end of file
--- a/src/aac/mp4ff/mp4sample.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4sample.c	Wed Apr 08 22:16:01 2009 +0100
@@ -1,35 +1,38 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4sample.c,v 1.15 2004/01/11 15:52:19 menno Exp $
+** $Id: mp4sample.c,v 1.20 2007/11/01 12:33:29 menno Exp $
 **/
 
 #include <stdlib.h>
 #include "mp4ffint.h"
 
 
-int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
+static int32_t mp4ff_chunk_of_sample(const mp4ff_t *f, const int32_t track, const int32_t sample,
                                      int32_t *chunk_sample, int32_t *chunk)
 {
     int32_t total_entries = 0;
@@ -75,7 +78,7 @@
     return 0;
 }
 
-int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk)
+static int32_t mp4ff_chunk_to_offset(const mp4ff_t *f, const int32_t track, const int32_t chunk)
 {
     const mp4ff_track_t * p_track = f->track[track];
 
@@ -91,7 +94,7 @@
     return 0;
 }
 
-int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
+static int32_t mp4ff_sample_range_size(const mp4ff_t *f, const int32_t track,
                                        const int32_t chunk_sample, const int32_t sample)
 {
     int32_t i, total;
@@ -114,7 +117,7 @@
     return total;
 }
 
-int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
+static int32_t mp4ff_sample_to_offset(const mp4ff_t *f, const int32_t track, const int32_t sample)
 {
     int32_t chunk, chunk_sample, chunk_offset1, chunk_offset2;
 
--- a/src/aac/mp4ff/mp4tagupdate.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4tagupdate.c	Wed Apr 08 22:16:01 2009 +0100
@@ -20,6 +20,21 @@
     return (uint32_t)result;
 }
 
+static uint16_t fix_byte_order_16(uint16_t src)
+{
+    uint16_t result;
+    uint16_t a, b;
+    int8_t data[2];
+    
+    memcpy(data,&src,sizeof(src));
+    a = (uint8_t)data[0];
+    b = (uint8_t)data[1];
+
+    result = (a<<8) | b;
+    return (uint16_t)result;
+}
+
+
 typedef struct
 {
 	void * data;
@@ -128,7 +143,7 @@
 	bufptr = membuffer_get_ptr(buf);
 	if (bufptr==0) return 0;
 	
-	if ((unsigned)mp4ff_read_data(src,(unsigned char*)bufptr + oldsize,bytes)!=bytes)
+	if ((unsigned)mp4ff_read_data(src,(char*)bufptr + oldsize,bytes)!=bytes)
 	{
 		membuffer_set_error(buf);
 		return 0;
@@ -197,19 +212,21 @@
 
 static stdmeta_entry stdmetas[] = 
 {
-	{"©nam","title"},
-	{"©ART","artist"},
-	{"©wrt","writer"},
-	{"©alb","album"},
-	{"©day","date"},
-	{"©too","tool"},
-	{"©cmt","comment"},
-//	{"©gen","genre"},
+	{"\xA9" "nam","title"},
+	{"\xA9" "ART","artist"},
+	{"\xA9" "wrt","writer"},
+	{"\xA9" "alb","album"},
+	{"\xA9" "day","date"},
+	{"\xA9" "too","tool"},
+	{"\xA9" "cmt","comment"},
+//	{"\xA9" "gen","genre"},
 	{"cpil","compilation"},
 //	{"trkn","track"},
 //	{"disk","disc"},
 //	{"gnre","genre"},
 	{"covr","cover"},
+	/* added by AJS */
+	{"aART","album_artist"},
 };
 
 
@@ -250,11 +267,20 @@
 
 static void membuffer_write_std_tag(membuffer * buf,const char * name,const char * value)
 {
+	/* added by AJS */
+	uint32_t flags = 1;
+
+	/* special check for compilation flag */
+	if ( strcmp(name, "cpil") == 0)
+	{
+		flags = 21;
+	}
+
 	membuffer_write_int32(buf,8 /*atom header*/ + 8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value) );
 	membuffer_write_atom_name(buf,name);
 	membuffer_write_int32(buf,8 /*data atom header*/ + 8 /*flags + reserved*/ + strlen(value));
 	membuffer_write_atom_name(buf,"data");
-	membuffer_write_int32(buf,1);//flags
+	membuffer_write_int32(buf,flags);//flags
 	membuffer_write_int32(buf,0);//reserved
 	membuffer_write_data(buf,value,strlen(value));
 }
@@ -383,7 +409,7 @@
 	uint64_t atom_offset = base;
 	for(;;)
 	{
-		unsigned char atom_name[4];
+		char atom_name[4];
 		uint32_t atom_size;
 
 		mp4ff_set_position(f,atom_offset);
@@ -514,7 +540,7 @@
 	{
 		udta_offset = mp4ff_position(f);
 		udta_size = mp4ff_read_int32(f);
-		if (find_atom_v2(f,udta_offset+8,udta_size-8,"meta",4,"ilst")<2)
+		if (!find_atom_v2(f,udta_offset+8,udta_size-8,"meta",4,"ilst"))
 		{
 			membuffer * buf;
 			void * new_meta_buffer;
@@ -591,7 +617,7 @@
     ff->stream = f;
 	mp4ff_set_position(ff,0);
 
-    parse_atoms(ff);
+    parse_atoms(ff,1);
 
 
 	if (!modify_moov(ff,data,&new_moov_data,&new_moov_size))
@@ -603,7 +629,7 @@
     /* copy moov atom to end of the file */
     if (ff->last_atom != ATOM_MOOV)
     {
-        unsigned char *free_data = (unsigned char*)"free";
+        char *free_data = "free";
 
         /* rename old moov to free */
         mp4ff_set_position(ff, ff->moov_offset + 4);
@@ -611,14 +637,14 @@
 	
         mp4ff_set_position(ff, ff->file_size);
 		mp4ff_write_int32(ff,new_moov_size + 8);
-		mp4ff_write_data(ff,(unsigned char*)"moov",4);
+		mp4ff_write_data(ff,"moov",4);
 		mp4ff_write_data(ff, new_moov_data, new_moov_size);
     }
 	else
 	{
         mp4ff_set_position(ff, ff->moov_offset);
 		mp4ff_write_int32(ff,new_moov_size + 8);
-		mp4ff_write_data(ff,(unsigned char*)"moov",4);
+		mp4ff_write_data(ff,"moov",4);
 		mp4ff_write_data(ff, new_moov_data, new_moov_size);
 	}
 
--- a/src/aac/mp4ff/mp4util.c	Wed Apr 08 20:12:57 2009 +0100
+++ b/src/aac/mp4ff/mp4util.c	Wed Apr 08 22:16:01 2009 +0100
@@ -1,49 +1,45 @@
 /*
 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**  
 ** 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
 ** (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.
-**
+** 
 ** 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.
+** along with this program; if not, write to the Free Software 
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 **
 ** Any non-GPL usage of this software or parts of this software is strictly
 ** forbidden.
 **
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
 ** Commercial non-GPL licensing of this software is possible.
-** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
 **
-** $Id: mp4util.c,v 1.15 2004/01/11 15:52:19 menno Exp $
+** $Id: mp4util.c,v 1.20 2007/11/01 12:33:29 menno Exp $
 **/
 
 #include "mp4ffint.h"
 #include <stdlib.h>
 
-int32_t mp4ff_read_data(mp4ff_t *f, uint8_t *data, uint32_t size)
+int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size)
 {
-    int32_t result;
-    uint32_t read = 0;
+    int32_t result = 1;
 
-    while (read < size) {
-        result = f->stream->read(f->stream->user_data, data+read, size-read);
-	if (result <= 0) {
-		break;
-	}
-	read += result;
-    }
+    result = f->stream->read(f->stream->user_data, data, size);
 
-    f->current_position += read;
+    f->current_position += size;
 
-    return read;
+    return result;
 }
 
 int32_t mp4ff_truncate(mp4ff_t * f)
@@ -51,7 +47,7 @@
 	return f->stream->truncate(f->stream->user_data);
 }
 
-int32_t mp4ff_write_data(mp4ff_t *f, uint8_t *data, uint32_t size)
+int32_t mp4ff_write_data(mp4ff_t *f, int8_t *data, uint32_t size)
 {
     int32_t result = 1;
 
@@ -112,13 +108,13 @@
 {
     uint32_t result;
     uint32_t a, b, c, d;
-    uint8_t data[4];
+    int8_t data[4];
     
     mp4ff_read_data(f, data, 4);
-    a = data[0];
-    b = data[1];
-    c = data[2];
-    d = data[3];
+    a = (uint8_t)data[0];
+    b = (uint8_t)data[1];
+    c = (uint8_t)data[2];
+    d = (uint8_t)data[3];
 
     result = (a<<24) | (b<<16) | (c<<8) | d;
     return (uint32_t)result;
@@ -128,12 +124,12 @@
 {
     uint32_t result;
     uint32_t a, b, c;
-    uint8_t data[4];
+    int8_t data[4];
     
     mp4ff_read_data(f, data, 3);
-    a = data[0];
-    b = data[1];
-    c = data[2];
+    a = (uint8_t)data[0];
+    b = (uint8_t)data[1];
+    c = (uint8_t)data[2];
 
     result = (a<<16) | (b<<8) | c;
     return (uint32_t)result;
@@ -143,19 +139,19 @@
 {
     uint32_t result;
     uint32_t a, b;
-    uint8_t data[2];
+    int8_t data[2];
     
     mp4ff_read_data(f, data, 2);
-    a = data[0];
-    b = data[1];
+    a = (uint8_t)data[0];
+    b = (uint8_t)data[1];
 
     result = (a<<8) | b;
     return (uint16_t)result;
 }
 
-unsigned char * mp4ff_read_string(mp4ff_t * f,uint32_t length)
+char * mp4ff_read_string(mp4ff_t * f,uint32_t length)
 {
-	unsigned char * str = (unsigned char*)malloc(length + 1);
+	char * str = (char*)malloc(length + 1);
 	if (str!=0)
 	{
 		if ((uint32_t)mp4ff_read_data(f,str,length)!=length)