Skip to content

Commit 65ca1ec

Browse files
authored
feat: Support GoPRO GPS as a separate CAMM sample entry (#710)
* support GoPro GPS and CAMM GPS sample entries separately * fix types * type
1 parent bb74b3d commit 65ca1ec

5 files changed

Lines changed: 596 additions & 176 deletions

File tree

mapillary_tools/camm/camm_builder.py

Lines changed: 14 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import io
22
import typing as T
33

4-
from .. import geo, telemetry, types
4+
from .. import geo, types
55
from ..mp4 import (
66
construct_mp4_parser as cparser,
77
mp4_sample_parser as sample_parser,
@@ -11,62 +11,11 @@
1111
from . import camm_parser
1212

1313

14-
TelemetryMeasurement = T.Union[
15-
geo.Point,
16-
telemetry.TelemetryMeasurement,
17-
]
18-
19-
20-
def _build_camm_sample(measurement: TelemetryMeasurement) -> bytes:
21-
if isinstance(measurement, geo.Point):
22-
return camm_parser.CAMMSampleData.build(
23-
{
24-
"type": camm_parser.CAMMType.MIN_GPS.value,
25-
"data": [
26-
measurement.lat,
27-
measurement.lon,
28-
-1.0 if measurement.alt is None else measurement.alt,
29-
],
30-
}
31-
)
32-
elif isinstance(measurement, telemetry.AccelerationData):
33-
# Accelerometer reading in meters/second^2 along XYZ axes of the camera.
34-
return camm_parser.CAMMSampleData.build(
35-
{
36-
"type": camm_parser.CAMMType.ACCELERATION.value,
37-
"data": [
38-
measurement.x,
39-
measurement.y,
40-
measurement.z,
41-
],
42-
}
43-
)
44-
elif isinstance(measurement, telemetry.GyroscopeData):
45-
# Gyroscope signal in radians/seconds around XYZ axes of the camera. Rotation is positive in the counterclockwise direction.
46-
return camm_parser.CAMMSampleData.build(
47-
{
48-
"type": camm_parser.CAMMType.GYRO.value,
49-
"data": [
50-
measurement.x,
51-
measurement.y,
52-
measurement.z,
53-
],
54-
}
55-
)
56-
elif isinstance(measurement, telemetry.MagnetometerData):
57-
# Ambient magnetic field.
58-
return camm_parser.CAMMSampleData.build(
59-
{
60-
"type": camm_parser.CAMMType.MAGNETIC_FIELD.value,
61-
"data": [
62-
measurement.x,
63-
measurement.y,
64-
measurement.z,
65-
],
66-
}
67-
)
68-
else:
69-
raise ValueError(f"unexpected measurement type {type(measurement)}")
14+
def _build_camm_sample(measurement: camm_parser.TelemetryMeasurement) -> bytes:
15+
for sample_entry_cls in camm_parser.SAMPLE_ENTRY_CLS_BY_CAMM_TYPE.values():
16+
if sample_entry_cls.serializable(measurement):
17+
return sample_entry_cls.serialize(measurement)
18+
raise ValueError(f"Unsupported measurement type {type(measurement)}")
7019

7120

7221
def _create_edit_list_from_points(
@@ -121,16 +70,19 @@ def _create_edit_list_from_points(
12170

12271
def _multiplex(
12372
points: T.Sequence[geo.Point],
124-
measurements: T.Optional[T.List[telemetry.TelemetryMeasurement]] = None,
125-
) -> T.List[TelemetryMeasurement]:
126-
mutiplexed: T.List[TelemetryMeasurement] = [*points, *(measurements or [])]
73+
measurements: T.Optional[T.List[camm_parser.TelemetryMeasurement]] = None,
74+
) -> T.List[camm_parser.TelemetryMeasurement]:
75+
mutiplexed: T.List[camm_parser.TelemetryMeasurement] = [
76+
*points,
77+
*(measurements or []),
78+
]
12779
mutiplexed.sort(key=lambda m: m.time)
12880

12981
return mutiplexed
13082

13183

13284
def convert_telemetry_to_raw_samples(
133-
measurements: T.Sequence[TelemetryMeasurement],
85+
measurements: T.Sequence[camm_parser.TelemetryMeasurement],
13486
timescale: int,
13587
) -> T.Generator[sample_parser.RawSample, None, None]:
13688
for idx, measurement in enumerate(measurements):
@@ -283,7 +235,7 @@ def create_camm_trak(
283235

284236
def camm_sample_generator2(
285237
video_metadata: types.VideoMetadata,
286-
telemetry_measurements: T.Optional[T.List[telemetry.TelemetryMeasurement]] = None,
238+
telemetry_measurements: T.Optional[T.List[camm_parser.TelemetryMeasurement]] = None,
287239
):
288240
def _f(
289241
fp: T.BinaryIO,

0 commit comments

Comments
 (0)