Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion mapillary_tools/exiftool_read_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,12 @@ def _aggregate_epoch_times(
or []
)
]
if len(gps_epoch_times) != expected_length:
if len(gps_epoch_times) == 1 and expected_length > 1:
# Some cameras (e.g. GoPro MAX) store a single GPSDateTime per sample
# shared across all the GPS coordinates in that sample. Broadcast the
# single epoch time to every coordinate to match the native parser.
gps_epoch_times = gps_epoch_times * expected_length
elif len(gps_epoch_times) != expected_length:
LOG.warning(
"Found different number of GPS epoch times %d and coordinates %d",
len(gps_epoch_times),
Expand Down
31 changes: 30 additions & 1 deletion tests/unit/test_exiftool_read_video.py
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,33 @@ def test_ground_speed_tag(self):
assert len(track) == 1
assert track[0].ground_speed == pytest.approx(52.7561)

def test_single_gps_time_tag_is_broadcast_to_all_points(self):
# Some cameras (e.g. GoPro MAX) store a single GPSDateTime per sample
# shared across all the GPS coordinates in that sample. The single epoch
# time should be broadcast to every coordinate.
texts = {
expand_tag("QuickTime:GPSLongitude"): ["28.0", "29.0"],
expand_tag("QuickTime:GPSLatitude"): ["37.0", "38.0"],
expand_tag("QuickTime:GPSDateTime"): [
"2019:09:02 10:00:00Z",
"2019:09:02 10:00:01Z",
],
expand_tag("QuickTime:GPSTimeStamp"): [
"2019:09:02 10:00:10Z",
],
}
track = _aggregate_gps_track(
texts,
time_tag="QuickTime:GPSDateTime",
lon_tag="QuickTime:GPSLongitude",
lat_tag="QuickTime:GPSLatitude",
gps_time_tag="QuickTime:GPSTimeStamp",
)
assert len(track) == 2
# 2019:09:02 10:00:10Z broadcast to both points
for p in track:
assert p.epoch_time == pytest.approx(1567418410.0)

def test_gps_time_tag_length_mismatch_falls_back_to_none(self):
texts = {
expand_tag("QuickTime:GPSLongitude"): ["28.0", "29.0"],
Expand All @@ -526,6 +553,8 @@ def test_gps_time_tag_length_mismatch_falls_back_to_none(self):
],
expand_tag("QuickTime:GPSTimeStamp"): [
"2019:09:02 10:00:10Z",
"2019:09:02 10:00:11Z",
"2019:09:02 10:00:12Z",
],
}
track = _aggregate_gps_track(
Expand All @@ -536,7 +565,7 @@ def test_gps_time_tag_length_mismatch_falls_back_to_none(self):
gps_time_tag="QuickTime:GPSTimeStamp",
)
assert len(track) == 2
# Mismatch in gps_time_tag length: epoch_time falls back to None
# Genuine mismatch (3 vs 2) in gps_time_tag length: epoch_time falls back to None
for p in track:
assert p.epoch_time is None

Expand Down
Loading