gpmf-parser: decoding the telemetry GoPro cameras bury in MP4
Parser for GPMF™ formatted telemetry data used within GoPro® cameras.
At a glance
- What is it?
- gpmf-parser is a C library for decoding GPMF, the GoPro Metadata Format, a compact Key Length Value structure that action cameras use to store accelerometer, gyroscope, magnetometer and GPS streams inside a video file. It ships a demo that pulls the payload out of an MP4, a Docker image, and a reference API for walking nested structures.
- Who is it for?
- Adopt gpmf-parser if you are working with action camera footage and need the sensor data that is already in the file rather than a separate logger, particularly if your pipeline is C or can link a C library. Do not adopt it if you need the raw payload extracted from the container, because the library decodes GPMF only and the extraction of the raw GPMF from a video or image file is not covered by this tool, so you need the demo's MP4 reader or your own.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 65 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why cameras needed their own metadata format
The GPMF introduction in the readme explains the design constraints before it explains the format, and the constraints are what make the format interesting.
The GPMF structured storage format was originally proposed to store high-frequency periodic sensor data within a video file like an MP4. Action cameras, and GoPro is the example given, have limited computing resources beyond what is needed to store video and audio, so any telemetry storage needed to be lightweight in computation, memory usage and storage bandwidth.
That constraint is why JSON and XML were initially considered and then rejected: the burden on the embedded camera system was too great, so something simpler was needed.
The result is a modified Key, Length, Value solution with a 32-bit aligned payload that is compact, extensible and somewhat human readable in a hex editor. The list of problems it solves is specific. The contents of new keys can be parsed without prior knowledge. Nested structures can be defined without a key dictionary. The structure prevents naming collisions between multiple sources. Nested structures allow metadata such as scale, units and data ranges to be communicated. It is somewhat human, engineer readable, hex-editor friendly. And timing and indexing reuse the methods already stored within the wrapping MP4 or similar container.
The standalone use case is acknowledged but not the point: the intended implementation uses an additional time-indexed track within an MP4, along with an application marker within JPEG images. GPMF is optimized as a storage format for the collection of sensor data as it happens.
KLV with a FourCC key, and the reserved vocabulary
The data model is small and the definitions section of the readme sets it out.
A Track is an MP4 container element used for storing video, audio or sub-titling over time. A FourCC is the four character key that marks a segment of data. The Key is the FourCC, and it is the first element in the Key Length Value triple. The Length field describes the data that follows, including the basic type, structural hints and sample counts. The Value is the raw data, stored in Big Endian. All data is Big Endian, which is stated as a property of the KLV design rather than an option.
Above the key level there is a device and stream hierarchy. A Device is a metadata source, and the readme makes the distinction concrete: a camera is one device and a connected Bluetooth sensor would be a separate device. A Stream is a unit of sensor data within a device, so a camera device could have GPS, accelerometer and gyro streams.
The reserved keys are what you program against. DEVC is the unique device source for metadata, and only DEVC is required at the beginning of any GPMF payload, with each connected device starting with its own DEVC for nested metadata to follow. DVID is an auto-generated unique ID for managing a large number of connected devices. DVNM is the device name, a display name like Karma 1.0 that is meant to be informative because it is communicated to the user. STRM is the nested signal stream of metadata, with each metadata stream nested with STRM, and STNM is the stream name.
The naming rule matters for third party work. The FourCC is a 7-bit ASCII key created for readability, all uppercase FourCCs are reserved keys, and mixed case is for any third party ingested data. So a custom payload is identifiable by case alone.
The API is a stream walk with a switch on the key
The library is C, and the API is a stream cursor you initialise, walk and read. GPMF_parser.c and GPMF_parser.h provide a payload decoder for any raw stream stored in compliant GPMF.
The reference pattern in the readme initialises a stream against a buffer, then loops over GPMF_Key and switches on the FourCC. GPMF_Repeat gives the sample count, GPMF_ScaledData returns values already scaled by the metadata in the payload, and GPMF_FormattedData returns the raw formatted data unscaled. The loop condition advances with GPMF_Next at GPMF_RECURSE_LEVELS, which is what makes the walk descend into nested structures rather than only across the top level.
The default case in the reference code carries a comment that states the design goal: if you do not know the key you can skip to the next. That is the direct consequence of the no prior knowledge property of the format, and it is why a parser can be written before the producer of the data exists.
When you want one specific thing rather than a walk, there is a separate search path. GPMF_FindNext locates a key at a given recursion level, and then GPMF_Key, GPMF_Type, GPMF_Repeat and GPMF_RawData pull out the metadata and the untouched bytes, leaving the byte swapping and the interpretation to you.
The repository layout shows the split between the parser and everything around it. GPMF_parser.c and GPMF_parser.h are the core, with GPMF_utils.c and GPMF_utils.h and GPMF_bitstream.h and GPMF_common.h alongside. Then there is a demo directory with GPMF_demo.c, GPMF_mp4reader.c and GPMF_mp4reader.h, and GPMF_print.c. The mp4reader is the piece that is not part of the library.
The demo, the container and the boundary of the library
What the repository contains is listed plainly: the complete source to a GPMF parser library, demo code for using the GPMF parser with extraction of GPMF from MP4 or MOV files, and CMake support for building the demo project.
That distinction between the library and the demo is the important one, and the sample code section states it directly: GPMF-parser.c and .h provide a payload decoder for any raw stream stored in compliant GPMF, and extraction of the RAW GPMF from a video or image file is not covered by this tool.
So if you have an MP4, you need the demo's GPMF_mp4reader to find the GPMF track and hand you the buffer, and then the library decodes it. The demo is not a toy, it is the part that does the container work, and the library is the part you would link into your own tool.
The quickest way to see it working is the container image:
docker run runsascoded/gpmf-parser samples/hero8.mp4The Dockerfile behind it is minimal. It builds on a gcc 10.1.0 image, copies the source into a gpmf-parser directory, runs make in the demo subdirectory, and sets the entry point to the run.sh script.
Building from source is three commands in the demo directory:
cd gpmf-parser/demo/
make
./gpmfdemo ../samples/Fusion.mp4That gives a brief overview of what metadata is stored in the given video file. The following command shows the first few samples of the recorded payload, which is where the accelerometer, gyroscope, magnetometer and GPS data appears:
./gpmfdemo ../samples/Fusion.mp4 -gThere is a samples directory in the repository with the demo footage the readme refers to, and the test matrix in the readme is old but specific: macOS High Sierra with Xcode 8 and 9, Windows 10 with Visual Studio 2015 and 2017, and Ubuntu 16.04 with gcc 5.4.
Dual licensed, and the writing path is a separate project
The licence arrangement is unusually generous for a vendor adjacent project, and it is stated in the readme as a choice at your option.
GPMF-parser is licensed under either the Apache License, Version 2.0, with the LICENSE-APACHE file, or the MIT license with the LICENSE-MIT file, at your option. The contribution terms follow the same pattern: unless you explicitly state otherwise, any contribution intentionally submitted for inclusion, as defined in the Apache-2.0 license, shall be dual licensed as above without any additional terms or conditions.
That matters in practice because the library is a small C dependency that most teams would rather link than rewrite, and a choice of two permissive licences removes a whole category of procurement conversation.
The other structural point is that writing is not in this repository. A separate open source repository exists for the purpose, GPMF-Write, and the readme points at it directly. So the parser is the read path and the writer is elsewhere, which is a sensible division for a format where the producer is the camera firmware.
The project metadata records the licence as Apache-2.0, with the primary language as C, and the repository carries a GPDeps directory, a gpmf-parser.pc.in pkg-config template, a CMakeLists.txt and a run.sh at the root. The recent release tags are v2.2.1 from 2021-04-12, a cleanup of the MP4 reader and utils, v2.1 from 2020-10-14 for improved datatype tolerance, and v2.0.2 from 2020-08-26 with security fixes.
That release history is the thing to weigh. The most recent tagged release is more than five years old at the time of the last push on 2026-08-18, so the code is being touched but the versioned artefacts are old, and the datatype tolerance improvement in v2.1 is a reminder that parsing real camera files has sharp edges that get fixed over time.
Editorial conclusion
Adopt gpmf-parser if you are working with action camera footage and need the sensor data that is already in the file rather than a separate logger, particularly if your pipeline is C or can link a C library. Do not adopt it if you need the raw payload extracted from the container, because the library decodes GPMF only and the extraction of the raw GPMF from a video or image file is not covered by this tool, so you need the demo's MP4 reader or your own. Before you commit, check that the FourCC keys you need are reserved uppercase ones or documented, and plan for the fact that the newest tagged release is v2.2.1 from 2021.
Frequently asked questions
What is GPMF?
GPMF, the GoPro Metadata Format, is a modified Key Length Value format with a 32-bit aligned payload, designed to store high-frequency periodic sensor data inside a video file. It is big endian, uses four character codes as keys, and is optimized as a time of capture storage format for collecting sensor data as it happens.
What does gpmf-parser include?
The complete source to a GPMF parser library, demo code for extracting GPMF from MP4 or MOV files, and CMake support for building the demo. The library itself decodes any raw GPMF stream, while extraction of the raw GPMF from a video or image file is not covered by the library and is handled by the demo's MP4 reader.
How do I run the gpmf-parser demo?
Build the demo with make in the demo directory and run it against a sample, or use the Docker image with docker run runsascoded/gpmf-parser samples/hero8.mp4. Adding the -g flag to gpmfdemo shows the first few samples of the recorded payload such as accelerometer, gyroscope, magnetometer and GPS data.
What licence is gpmf-parser under?
It is dual licensed at your option, either the Apache License Version 2.0 or the MIT license. Contributions are dual licensed the same way unless you explicitly state otherwise.
What are the reserved GPMF FourCC keys?
DEVC is the unique device source and is required at the beginning of any GPMF payload, DVID is the auto-generated device ID, DVNM the device name, STRM a nested signal stream and STNM the stream name. All uppercase FourCCs are reserved, and mixed case is for third party ingested data.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/gopro-gpmf-parser)Was this useful?