~/blog / hello-recap360

What lives inside a 360 movie file?

My curiosity began with these captured files that wouldn’t play in QuickTime Player on their own. So what was inside them that made them tricky?

HVC1 Video Tracks

Every DJI and GoPro file contains two HVC1/H.265 video tracks; one for the ‘front’ lens and one for the ‘back’, roughly.

But the way the different cameras lay out the contents of the video is quite varied; let’s use Recap360’s “debug flat view”Debug Flat View is a debugging-only view, and doesn’t ship in the App Store version. Quite useful during development though. to see them.

DJI Osmo 360 video tracks are classic fisheye camera images, straight off the CMOS sensor:

DJI Osmo 360 front and back frames in Recap360's debug flat view
The circles, lines, and text are overlays from Recap360, not in the video itself. The horizontal dashed magenta lines are rolling shutter boundaries. More on those in another post.

GoPro MAX is doing something very different. Clearly they’re doing a lot of processing before writing these to the microSD card:

GoPro MAX front and back frames in Recap360's debug flat view
These GoPro tracks are like orange peels; it's hard to see how they fit together. I imagine two "C"-shaped peels, one wrapping vertically and one horizontally.

The big picture: all the tracks

Let’s use AtomicBrowser, a utility app I made, to peer into the innards of these files. You can see the separate video tracks, as well as audio & a surprising amount of metadata.

The structure of the DJI Osmo 360 file. Two djmd tracks, and two dbgi tracks? Interesting.
The structure of the GoPro MAX file. Audio, video, `meta/gpmd`, and other tracks.

Let’s take a look at these in detail. Where is the GPS data? What all is in there?

GoPro Metadata: Well documented and rich

Some fascinating tidbits in there, most notably that gpmd track! Kudos to GoPro, they’ve gone to the trouble to document it, and even make gpmf-parser a utility to extract data from it.

So naturally I had to extend AtomicBrowser to show it all to us. And it is some rich data! Raw Accelerometer & Gyro data, GPS location, as well as synthesized CORI (Camera Orientation) & IORI (Image Orientation); pre- and post-stabilization information. Sweet!

Some GPS data in the `gpmd` track in a GoPro .360 file.

DJI Metadata: Also rich, but not officially documented

The DJI Osmo 360 is friendlier in one way: their single dual-fisheye track is easy to understand. But weirder in another: the IMU samples are in separate, undocumented data tracks.

Fortunately, their data stream turns out to be Protobuf based, which is a well known standard and relatively easy to make sense of.

Camera orientation data; 33 samples per video frame? That seemed like unusually dense data... More on that in a future post. Hint: there are 32 rolling shutter bands in the video tracks.

What’s next

Over the next few posts we’ll cover:

  • How to decode dual-track .360 on a single AVSampleBufferDisplayLayer
  • The math that turns gyro quaternions into a stable camera orientation

If you’ve poked at this stuff before, I’d love to compare notes.

Thanks to those who have plumbed these depths

  • Paul Bourke for writing up his findings about the GoPro MAX video layout here. I agree with him; the custom layout seems like a lot of unnecessary trouble to go to, both for encoders & decoders. EAC or raw fisheye is much simpler to encode and decode.
  • Phil Harvey for building and maintaining exiftool, and the DJI information page at ExifTool - DJI Tag names. With some luck I’ll be able to contribute some of our findings there.

— David

© 2026 Mindful Bear Apps · recap360.app · Privacy