mirror of https://git.ffmpeg.org/ffmpeg.git
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@martin.st>
This commit is contained in:
parent
d816e125fe
commit
e7d6d0bf3c
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue