summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
Diffstat (limited to 'apps')
-rw-r--r--apps/metadata.c159
1 files changed, 158 insertions, 1 deletions
diff --git a/apps/metadata.c b/apps/metadata.c
index 2f00787e6f..872dfd72f5 100644
--- a/apps/metadata.c
+++ b/apps/metadata.c
@@ -49,6 +49,7 @@ enum tagtype { TAGTYPE_APE = 1, TAGTYPE_VORBIS };
49#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T') 49#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T')
50#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm') 50#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm')
51#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't') 51#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
52#define MP4_esds MP4_ID('e', 's', 'd', 's')
52#define MP4_ftyp MP4_ID('f', 't', 'y', 'p') 53#define MP4_ftyp MP4_ID('f', 't', 'y', 'p')
53#define MP4_gnre MP4_ID('g', 'n', 'r', 'e') 54#define MP4_gnre MP4_ID('g', 'n', 'r', 'e')
54#define MP4_hdlr MP4_ID('h', 'd', 'l', 'r') 55#define MP4_hdlr MP4_ID('h', 'd', 'l', 'r')
@@ -228,6 +229,14 @@ static unsigned long get_long(void* buf)
228 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 229 return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
229} 230}
230 231
232/* Read an unaligned 32-bit big endian long from buffer. */
233static unsigned long get_long_be(void* buf)
234{
235 unsigned char* p = (unsigned char*) buf;
236
237 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
238}
239
231/* Read a string tag from an M4A file */ 240/* Read a string tag from an M4A file */
232void read_m4a_tag_string(int fd, int len,char** bufptr,size_t* bytes_remaining, char** dest) 241void read_m4a_tag_string(int fd, int len,char** bufptr,size_t* bytes_remaining, char** dest)
233{ 242{
@@ -1036,6 +1045,136 @@ static unsigned int read_mp4_atom(int fd, unsigned int* size,
1036 return size_left; 1045 return size_left;
1037} 1046}
1038 1047
1048static unsigned int read_mp4_length(int fd, unsigned int* size)
1049{
1050 unsigned int length = 0;
1051 int bytes = 0;
1052 unsigned char c;
1053
1054 do
1055 {
1056 read(fd, &c, 1);
1057 bytes++;
1058 (*size)--;
1059 length = (length << 7) | (c & 0x7F);
1060 }
1061 while ((c & 0x80) && (bytes < 4) && (*size > 0));
1062
1063 return length;
1064}
1065
1066static bool read_mp4_esds(int fd, struct mp3entry* id3,
1067 unsigned int* size)
1068{
1069 unsigned char buf[8];
1070 bool sbr = false;
1071
1072 lseek(fd, 4, SEEK_CUR); /* Version and flags. */
1073 read(fd, buf, 1); /* Verify ES_DescrTag. */
1074 *size -= 5;
1075
1076 if (*buf == 3)
1077 {
1078 /* read length */
1079 if (read_mp4_length(fd, size) < 20)
1080 {
1081 return sbr;
1082 }
1083
1084 lseek(fd, 3, SEEK_CUR);
1085 *size -= 3;
1086 }
1087 else
1088 {
1089 lseek(fd, 2, SEEK_CUR);
1090 *size -= 2;
1091 }
1092
1093 read(fd, buf, 1); /* Verify DecoderConfigDescrTab. */
1094 *size -= 1;
1095
1096 if (*buf != 4)
1097 {
1098 return sbr;
1099 }
1100
1101 if (read_mp4_length(fd, size) < 13)
1102 {
1103 return sbr;
1104 }
1105
1106 lseek(fd, 13, SEEK_CUR); /* Skip audio type, bit rates, etc. */
1107 read(fd, buf, 1);
1108 *size -= 14;
1109
1110 if (*buf != 5) /* Verify DecSpecificInfoTag. */
1111 {
1112 return sbr;
1113 }
1114
1115 {
1116 static const int sample_rates[] =
1117 {
1118 96000, 88200, 64000, 48000, 44100, 32000,
1119 24000, 22050, 16000, 12000, 11025, 8000
1120 };
1121 unsigned long bits;
1122 unsigned int length;
1123 unsigned int index;
1124 int type;
1125
1126 /* Read the (leading part of the) decoder config. */
1127 length = read_mp4_length(fd, size);
1128 length = MIN(length, *size);
1129 length = MIN(length, sizeof(buf));
1130 read(fd, buf, length);
1131 *size -= length;
1132
1133 /* Decoder config format:
1134 * Object type - 5 bits
1135 * Frequency index - 4 bits
1136 * Channel configuration - 4 bits
1137 */
1138 bits = get_long_be(buf);
1139 type = bits >> 27;
1140 index = (bits >> 23) & 0xf;
1141
1142 if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
1143 {
1144 id3->frequency = sample_rates[index];
1145 }
1146
1147 if (type == 5)
1148 {
1149 sbr = true;
1150 /* Extended frequency index - 4 bits */
1151 index = (bits >> 15) & 0xf;
1152
1153 if (index == 15)
1154 {
1155 /* 17 bits read so far... */
1156 bits = get_long_be(&buf[2]);
1157 id3->frequency = (bits >> 7) & 0x00FFFFFF;
1158 }
1159 else if (index < (sizeof(sample_rates) / sizeof(*sample_rates)))
1160 {
1161 id3->frequency = sample_rates[index];
1162 }
1163 }
1164 else if (id3->frequency < 24000)
1165 {
1166 /* SBR not indicated, but the file might still contain SBR.
1167 * MPEG specification says that one should assume SBR if
1168 * samplerate <= 24000 Hz.
1169 */
1170 id3->frequency *= 2;
1171 sbr = true;
1172 }
1173 }
1174
1175 return sbr;
1176}
1177
1039static bool read_mp4_tags(int fd, struct mp3entry* id3, 1178static bool read_mp4_tags(int fd, struct mp3entry* id3,
1040 unsigned int size_left) 1179 unsigned int size_left)
1041{ 1180{
@@ -1268,7 +1407,25 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
1268 read_uint32be(fd, &frequency); 1407 read_uint32be(fd, &frequency);
1269 size -= 26; 1408 size -= 26;
1270 id3->frequency = frequency; 1409 id3->frequency = frequency;
1271 /* There're some child atoms here, but we don't need them */ 1410
1411 if (type == MP4_mp4a)
1412 {
1413 unsigned int subsize;
1414 unsigned int subtype;
1415
1416 /* Get frequency from the decoder info tag, if possible. */
1417 lseek(fd, 2, SEEK_CUR);
1418 /* The esds atom is a part of the mp4a atom, so ignore
1419 * the returned size (it's already accounted for).
1420 */
1421 read_mp4_atom(fd, &subsize, &subtype, size);
1422 size -= 10;
1423
1424 if (subtype == MP4_esds)
1425 {
1426 read_mp4_esds(fd, id3, &size);
1427 }
1428 }
1272 } 1429 }
1273 break; 1430 break;
1274 1431