3 releases

0.1.2 Mar 25, 2023
0.1.1 Mar 25, 2023
0.1.0 Mar 22, 2023

#4 in #hero

46 downloads per month

MIT/Apache

44KB
561 lines

gpmf

Parser and Writer for GoPro Metadata Format (GPMF)

WIP: Currently successfully parses all raw test data and logs the results.

Design Goals

  • Linux Philosophy, each tool does one thing and does it well
  • Can be integrated in other tools, and in other languages than Rust
  • Focus on clean, easy to understand code (no macros)
  • Performant (but not at the expense of the previous item)
  • Easy to read detailed log in order to be able to debug problems
  • Memory safe parser
  • Zero security vulnerabilities. Avoid problems found in other tools e.g.: GoPro GPMF-parser Vulnerabilities
  • Never generate exceptions, i.e.: Should never panic.
  • Should pass fuzz tests i.e.: handle corrupt or junk data
  • Should avoid DOS attacks. Possibly Add max buffer lengths.
  • Gracefully recover from errors
  • Handle unknown tags
  • Roundtrip sensor data (without loss of precision or changing data type)

Reporting Issues

If you have a file that is not handled please submit an issue, attaching the raw metadata file

Feature Roadmap

  • Parser (WIP) at present just prints out data
  • Create a structure to hold data
  • Handle Scale
  • Handle multiple sensor data 'mp4 boxes/atoms', as contained in mp4 file
  • Return data in chronological order using Iterator and Tournament Tree
  • Extract metadata from Live Stream via WiFi and Rtmp Url in realtime
  • Handle exif data in images
  • Writer
  • Roundtrip sensor data

Example

use std::path::Path;
use gpmf::byteorder_gpmf::parse_gpmf;

fn main() -> anyhow::Result<()> {
    let path = Path::new("samples/karma.raw");
    let text = std::fs::read(path)?;
    let res=parse_gpmf(text.as_slice())?;
    println!("{:?}",res);
    Ok(())
}

Example with Logging

use std::path::Path;
use gpmf::byteorder_gpmf::parse_gpmf;
use tracing::Level;
use tracing_subscriber::FmtSubscriber;

fn main() -> anyhow::Result<()> {
    let subscriber = FmtSubscriber::builder()
        .with_max_level(Level::DEBUG)
        .finish();
    tracing::subscriber::set_global_default(subscriber)?;

    let path = Path::new("samples/Fusion.raw");
    let text = std::fs::read(path)?;
    let res=parse_gpmf(text.as_slice())?;
    println!("{:?}",res);
    Ok(())
}

License: MIT OR Apache-2.0

Dependencies

~6–13MB
~136K SLoC