diff --git a/libavformat/mov.c b/libavformat/mov.c index 7a40d05f23..48326235bf 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -208,6 +208,44 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) return 0; } +static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len) +{ + char language[4] = { 0 }; + char buf[100]; + uint16_t langcode = 0; + double longitude, latitude, altitude; + const char *key = "location"; + + if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) + return AVERROR_INVALIDDATA; + + avio_skip(pb, 4); // version+flags + langcode = avio_rb16(pb); + ff_mov_lang_to_iso639(langcode, language); + len -= 6; + + len -= avio_get_str(pb, len, buf, sizeof(buf)); // place name + if (len < 1) + return AVERROR_INVALIDDATA; + avio_skip(pb, 1); // role + len -= 1; + + if (len < 14) + return AVERROR_INVALIDDATA; + longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16); + latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16); + altitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16); + + // Try to output in the same format as the ?xyz field + snprintf(buf, sizeof(buf), "%+08.4f%+09.4f/", latitude, longitude); + if (*language && strcmp(language, "und")) { + char key2[16]; + snprintf(key2, sizeof(key2), "%s-%s", key, language); + av_dict_set(&c->fc->metadata, key2, buf, 0); + } + return av_dict_set(&c->fc->metadata, key, buf, 0); +} + static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) { #ifdef MOV_EXPORT_ALL_METADATA @@ -237,6 +275,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) case MKTAG(0xa9,'t','o','o'): case MKTAG(0xa9,'s','w','r'): key = "encoder"; break; case MKTAG(0xa9,'e','n','c'): key = "encoder"; break; + case MKTAG(0xa9,'x','y','z'): key = "location"; break; case MKTAG( 'd','e','s','c'): key = "description";break; case MKTAG( 'l','d','e','s'): key = "synopsis"; break; case MKTAG( 't','v','s','h'): key = "show"; break; @@ -256,6 +295,8 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) parse = mov_metadata_int8_no_padding; break; case MKTAG( 'p','g','a','p'): key = "gapless_playback"; parse = mov_metadata_int8_no_padding; break; + case MKTAG( 'l','o','c','i'): + return mov_metadata_loci(c, pb, atom.size); } if (c->itunes_metadata && atom.size > 8) {