I am investigating a reproducible GPS placement issue when using mapillary_tools sample_video with GoPro TimeWarp footage recorded at approximately 29.97 fps.
Images sampled near the end of a recording can receive a GPS position that is progressively ahead of the actual image location. The embedded GPS route itself is valid and passes normal speed and continuity checks. The apparent issue is the association between the selected video frame and the corresponding point on the internal GoPro GPMF timeline.
The same GoPro workflow with tested 25 fps TimeWarp recordings does not show this progressive displacement.
Mapillary Tools supports GoPro GPMF video and uses distance-based sampling to extract video frames and geotag them from the video telemetry. FFmpeg is used for video processing and frame extraction within that pipeline.
Mapillary Tools: 0.14.7
FFmpeg: 8.1.2
Camera: GoPro MAX 2
Recording mode: TimeWarp 5X
Processed video rate: 29.970030 fps
Video frames: 21,233
GPMF packets: 21,234
Valid GPS9 packets: 21,231
Video duration: approximately 708.47 seconds
Sampling command: mapillary_tools sample_video
Sampling distance: 5 metres
Sampled images: 9,816
Observed issue
A sampled JPEG near the end of the sequence visibly shows the camera immediately before a bridge.
The GPS marker written to that JPEG is located after the bridge, approximately 68 metres ahead of the visible camera position.
The GPS track itself is smooth:
GPS format: GPS9
Fix: 3
DOP near the test location: approximately 1.4
No implausible jumps
No duplicate timestamps
No backwards timestamps
Maximum validated speed: approximately 93 km/h
Because the route remains physically plausible, ordinary GPS quality checks do not detect the image-to-position mismatch.
Independent frame comparison
I visually matched the sampled JPEG against frames from the exact processed video.
JPEG name:GS010726_TEST_5xTW_0_009574.jpg
Best matching video frame:20,700
Corresponding equal-index GPMF packet: 20,700
The existing timestamp-based association pointed to approximately:
GPMF packet: 20,726
The difference was 26 packets.
Using GPS9 from packet 20,700 placed the image correctly before the bridge. Using the position associated with approximately packet 20,726 placed the image after the bridge.
The geographic difference between those two GPS positions was approximately 67.7 metres
Timing observation
The video and GPMF tracks contain almost the same number of samples:
Video frames: 21,233
GPMF packets: 21,234
The GPMF packet timestamps progress at a slightly different cadence. The difference is small per frame but grows over the duration of the recording.
This appears to create a situation where video frame n and GPMF packet selected by nearest timestamp are no longer the same near the end of the file. The displacement is progressive rather than a fixed start offset.
Comparison with 25 fps TimeWarp
I also tested GoPro TimeWarp recordings at 25 fps from both MAX generations.
For the tested 25 fps material video frame n ≈ GPMF packet n.
No comparable progressive GPS displacement was observed.
The issue currently appears associated with the approximately 29.97 fps TimeWarp timing family, although I do not yet have enough camera models and firmware versions to claim that every 29.97 fps GoPro file is affected.
Why the current workarounds are insufficient
Reassigning GPS from JPEG timestamps
The JPEG timestamps already appear to reflect the problematic video-to-GPMF time association. Using those timestamps to look up GPS again reproduces nearly the same incorrect position.
Globally rescaling the GPS timeline
A global affine rescale can align the start and end durations, but it does not prove that each extracted JPEG is associated with the correct original video frame.
Applying a fixed frame correction
A fixed correction such as minus 26 frames would only be correct near the tested bridge. The error grows progressively, so a fixed offset is not reliable.
Reimplementing distance sampling externally
A simple external sampler that accumulated distance between every consecutive GPMF position selected 13,644 images instead of Mapillary Tools’ 9,816 images. GPS jitter and differences in the internal sampling algorithm make that approach unsuitable as a direct replacement.
Workaround for now, change the regional setting to 50 Hz (PAL), the TW recording will be in 25 fps and can be used without any issues.