summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Greer <justin@zencoder.com>2012-08-21 21:57:45 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-08-21 22:31:26 +0200
commit37a15f3e669372075c88254e070c971aecb485aa (patch)
tree3d70fae1b2e95a2d7826b52f9c9414db97e3b1fe
parent50df56161f42da21a455204b76e17148ac3d9659 (diff)
mov: parse custom "----" Metadata
This fixes the priming samples for NERO AAC LC Simplified-by: Michael Niedermayer Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r--libavformat/mov.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index cb8307fe8f..8b966b1891 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -131,6 +131,74 @@ static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
return 0;
}
+static int mov_read_custom_metadata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+{
+ char key[1024]={0}, data[1024]={0};
+ int i;
+ AVStream *st;
+ MOVStreamContext *sc;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+ st = c->fc->streams[c->fc->nb_streams-1];
+ sc = st->priv_data;
+
+ if (atom.size <= 8) return 0;
+
+ for (i = 0; i < 3; i++) { // Parse up to three sub-atoms looking for name and data.
+ int data_size = avio_rb32(pb);
+ int tag = avio_rl32(pb);
+ int str_size = 0, skip_size = 0;
+ char *target = NULL;
+
+ switch (tag) {
+ case MKTAG('n','a','m','e'):
+ avio_rb32(pb); // version/flags
+ str_size = skip_size = data_size - 12;
+ atom.size -= 12;
+ target = key;
+ break;
+ case MKTAG('d','a','t','a'):
+ avio_rb32(pb); // version/flags
+ avio_rb32(pb); // reserved (zero)
+ str_size = skip_size = data_size - 16;
+ atom.size -= 16;
+ target = data;
+ break;
+ default:
+ skip_size = data_size - 8;
+ str_size = 0;
+ break;
+ }
+
+ if (target) {
+ str_size = FFMIN3(sizeof(data)-1, str_size, atom.size);
+ avio_read(pb, target, str_size);
+ target[str_size] = 0;
+ }
+ atom.size -= skip_size;
+
+ // If we didn't read the full data chunk for the sub-atom, skip to the end of it.
+ if (skip_size > str_size) avio_skip(pb, skip_size - str_size);
+ }
+
+ if (*key && *data) {
+ if (strcmp(key, "iTunSMPB") == 0) {
+ int priming, remainder, samples;
+ if(sscanf(data, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
+ if(priming>0 && priming<16384)
+ sc->start_pad = priming;
+ return 1;
+ }
+ }
+ if (strcmp(key, "cdec") == 0) {
+// av_dict_set(&st->metadata, key, data, 0);
+ return 1;
+ }
+ }
+ return 0;
+}
+
static const uint32_t mac_to_unicode[128] = {
0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
@@ -221,6 +289,9 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
uint32_t data_type = 0, str_size;
int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
+ if (c->itunes_metadata && atom.type == MKTAG('-','-','-','-'))
+ return mov_read_custom_metadata(c, pb, atom);
+
switch (atom.type) {
case MKTAG(0xa9,'n','a','m'): key = "title"; break;
case MKTAG(0xa9,'a','u','t'):
@@ -2971,7 +3042,8 @@ static int mov_read_header(AVFormatContext *s)
AVStream *st = s->streams[i];
MOVStreamContext *sc = st->priv_data;
if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) {
- sc->start_pad = 2112;
+ if(!sc->start_pad)
+ sc->start_pad = 2112;
st->skip_samples = sc->start_pad;
}
}