summaryrefslogtreecommitdiffstats
path: root/lib/rbcodec/metadata/mp4.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/metadata/mp4.c')
-rw-r--r--lib/rbcodec/metadata/mp4.c70
1 files changed, 31 insertions, 39 deletions
diff --git a/lib/rbcodec/metadata/mp4.c b/lib/rbcodec/metadata/mp4.c
index 41f38480b1..706a50e503 100644
--- a/lib/rbcodec/metadata/mp4.c
+++ b/lib/rbcodec/metadata/mp4.c
@@ -57,10 +57,6 @@
#define MP4_gnre FOURCC('g', 'n', 'r', 'e')
#define MP4_hdlr FOURCC('h', 'd', 'l', 'r')
#define MP4_ilst FOURCC('i', 'l', 's', 't')
-#define MP4_isom FOURCC('i', 's', 'o', 'm')
-#define MP4_M4A FOURCC('M', '4', 'A', ' ')
-#define MP4_m4a FOURCC('m', '4', 'a', ' ') /*technically its "M4A "*/
-#define MP4_M4B FOURCC('M', '4', 'B', ' ') /*but files exist with lower case*/
#define MP4_mdat FOURCC('m', 'd', 'a', 't')
#define MP4_mdia FOURCC('m', 'd', 'i', 'a')
#define MP4_mdir FOURCC('m', 'd', 'i', 'r')
@@ -68,8 +64,6 @@
#define MP4_minf FOURCC('m', 'i', 'n', 'f')
#define MP4_moov FOURCC('m', 'o', 'o', 'v')
#define MP4_mp4a FOURCC('m', 'p', '4', 'a')
-#define MP4_mp42 FOURCC('m', 'p', '4', '2')
-#define MP4_qt FOURCC('q', 't', ' ', ' ')
#define MP4_soun FOURCC('s', 'o', 'u', 'n')
#define MP4_stbl FOURCC('s', 't', 'b', 'l')
#define MP4_stsd FOURCC('s', 't', 's', 'd')
@@ -195,7 +189,7 @@ static unsigned int read_mp4_length(int fd, uint32_t* size)
{
unsigned int length = 0;
int bytes = 0;
- unsigned char c;
+ unsigned char c = '\0';
do
{
@@ -211,8 +205,9 @@ static unsigned int read_mp4_length(int fd, uint32_t* size)
static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
{
- unsigned char buf[8];
+ unsigned char buf[8] = {0};
bool sbr = false;
+ bool sbr_signaled = false;
lseek(fd, 4, SEEK_CUR); /* Version and flags. */
read(fd, buf, 1); /* Verify ES_DescrTag. */
@@ -282,6 +277,7 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
* Object type - 5 bits
* Frequency index - 4 bits
* Channel configuration - 4 bits
+ * Also see libfaad/mp4.c AudioSpecificConfig2 (consider using it instead of manual parsing)
*/
bits = get_long_be(buf);
type = bits >> 27; /* Object type - 5 bits */
@@ -326,6 +322,7 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
if (type == 5)
{
sbr = bits >> 31;
+ sbr_signaled = true;
if (sbr)
{
@@ -352,14 +349,15 @@ static bool read_mp4_esds(int fd, struct mp3entry* id3, uint32_t* size)
}
}
}
-
- if (!sbr && (id3->frequency <= 24000) && (length <= 2))
+#ifndef CODEC_AAC_SBR_DEC
+ //SBR_DEC is disabled so disable sbr implicit signalling
+ sbr_signaled = true;
+#endif
+ if (!sbr && !sbr_signaled && id3->frequency <= 24000)
{
- /* Double the frequency for low-frequency files without a "long"
- * DecSpecificConfig header. The file may or may not contain SBR,
- * but here we guess it does if the header is short. This can
- * fail on some files, but it's the best we can do, short of
- * decoding (parts of) the file.
+ /* As stated in libfaad/mp4.c AudioSpecificConfig2:
+ * no SBR signalled, this could mean either implicit signalling or no SBR in this file
+ * MPEG specification states: assume SBR on files with samplerate <= 24000 Hz
*/
id3->frequency *= 2;
sbr = true;
@@ -533,13 +531,18 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
rd_ret = 0;
tag_name[rd_ret] = 0;
+ static const char *tn_options[] = {"composer", "iTunSMPB",
+ "musicbrainz track id", "album artist", NULL};
+
+ int tn_op = string_option(tag_name, tn_options, true);
- if ((strcasecmp(tag_name, "composer") == 0) && !cwrt)
+
+ if (tn_op == 0 && !cwrt) /*composer*/
{
read_mp4_tag_string(fd, size, &buffer, &buffer_left,
&id3->composer);
}
- else if (strcasecmp(tag_name, "iTunSMPB") == 0)
+ else if (tn_op == 1) /*iTunSMPB*/
{
char value[TAG_VALUE_LENGTH];
char* value_p = value;
@@ -552,12 +555,12 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
DEBUGF("AAC: lead_trim %d, tail_trim %d\n",
id3->lead_trim, id3->tail_trim);
}
- else if (strcasecmp(tag_name, "musicbrainz track id") == 0)
+ else if (tn_op == 2) /*musicbrainz track id*/
{
read_mp4_tag_string(fd, size, &buffer, &buffer_left,
&id3->mb_track_id);
}
- else if ((strcasecmp(tag_name, "album artist") == 0))
+ else if (tn_op == 3) /*album artist*/
{
read_mp4_tag_string(fd, size, &buffer, &buffer_left,
&id3->albumartist);
@@ -612,20 +615,11 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
{
case MP4_ftyp:
{
- uint32_t id;
-
- read_uint32be(fd, &id);
+ // filetype (supported ignore case values: m4a, m4b, mp42, 3gp6, qt, isom)
+ char filetype[4];
+ read(fd, &filetype, 4);
+ DEBUGF("MP4 file type: '%.4s'\n", filetype);
size -= 4;
-
- if ((id != MP4_M4A) && (id != MP4_M4B) && (id != MP4_mp42)
- && (id != MP4_qt) && (id != MP4_3gp6) && (id != MP4_m4a)
- && (id != MP4_isom))
- {
- DEBUGF("Unknown MP4 file type: '%c%c%c%c'\n",
- (int)(id >> 24 & 0xff), (int)(id >> 16 & 0xff),
- (int)(id >> 8 & 0xff), (int)(id & 0xff));
- return false;
- }
}
break;
@@ -702,13 +696,11 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
* need any further special handling. */
if (id3->codectype==AFMT_MP4_AAC_HE && l<=1024)
{
- id3->samples += n * l * 2;
+ l *= 2;
id3->needs_upsampling_correction = true;
}
- else
- {
- id3->samples += n * l;
- }
+
+ id3->samples += (uint64_t) n * l;
}
size = 0;
@@ -784,8 +776,8 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
{
/* ADDME: add support for real chapters. Right now it's only
* used for Nero's gapless hack */
- uint8_t chapters;
- uint64_t timestamp;
+ uint8_t chapters = 0;
+ uint64_t timestamp = 0;
lseek(fd, 8, SEEK_CUR);
read_uint8(fd, &chapters);