[SCM] libav/experimental: mov: Export geotag metadata fields

siretart at users.alioth.debian.org siretart at users.alioth.debian.org
Sun Aug 10 16:03:24 UTC 2014


The following commit has been merged in the experimental branch:
commit e7d6d0bf3c5cc1bc048b0ddbc169a91862568e0c
Author: Martin Storsjö <martin at martin.st>
Date:   Tue Jun 3 14:48:19 2014 +0300

    mov: Export geotag metadata fields
    
    The '?xyz' form is used by android devices (and according to apple
    mailing list archives, also by older iOS devices). The 'loci' field
    (defined in 3GPP 26.244) is used by recent iOS devices.
    
    Even though the loci field can contain an altitude, it was plain
    0 in my sample. Just export longitude and latitude, in a string
    format matching the one used by the '?xyz' metadata field.
    
    Signed-off-by: Martin Storsjö <martin at martin.st>

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 7a40d05..4832623 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) {

-- 
Libav/FFmpeg packaging



More information about the pkg-multimedia-commits mailing list