Skip to content

1.6.0 — Cinema RAW: ARRIRAW, RED, X-OCN, CRM/CRL + per-frame metadata

Choose a tag to compare

@aagedal aagedal released this 02 May 19:12
· 86 commits to main since this release

Added

  • ARRIRAW (MXF) — full slate / lens / camera / medium / frameline / LUT JSON harvest. ARRI cameras (ALEXA 35, ALEXA Mini LF, AMIRA, …) carry production-side metadata as a set of JSON documents wrapped in MXF KLV metadata sets (tag 0x807A MIME, 0x807B JSON payload, 0x807C schema URL). New ARRIJSONParser.swift decodes the six well-known schemas — slate_info, camera_device, lens_device, recording_medium, frameline, custom_lut3d_design — and surfaces them via CameraMetadata.userMeta*. MXFReader routes ALEXA-codec MXF clips through this path; FormatDetector reports arriraw so consumers can distinguish ARRI MXFs from generic broadcast MXF.
  • Sony X-OCN (MXF + NRT AcquisitionRecord) — VENICE / BURANO / F55 / F65 cinema RAW. Format detection routes .mxf clips with the X-OCN essence descriptor through a deep harvest of the embedded NonRealTimeMeta XML (camera attributes, ISO, shutter angle, gamma, gamut, monitoring transform, ASC CDL, roll/tilt sensor metadata). Surfaces alongside ARRIRAW under FileFormat = XOCN. Tested against VENICE 8K samples (8664×5784, ISO 3200, ShutterAngle 173°, full ASC CDL).
  • Canon Cinema RAW Light (.CRM / .CRL) — clip + per-frame CTMD metadata. New CRMReader.swift recognises the Canon-flavored ISOBMFF (brand crx + Canon UUID), exposes FileFormat = CRM, and decodes the CTMD timed-metadata sample groups for ISO, shutter time, focal length, aperture, white balance, and per-frame lens metadata across both the CRAW master format and the proxy CRL.
  • RED RAW (.R3D) — REDCODE clip metadata. New R3DReader.swift parses the RED2 atom and decodes OBKM / RDLG metadata (lens model, slate, sensor, codec). Verified against KOMODO Chroma Key and V-RAPTOR LUT samples.
  • Nikon RAW Video (.R3D, codec NR3D) — N-RAW detection. Nikon Z8 / Z9 N-RAW recordings happen to use the .R3D extension but are an ISOBMFF derivative (ftyp niko, codec NR3D), not REDCODE. Format dispatch sniffs the magic bytes to pick the right reader; misnamed files in "RED RAW" folders no longer get misclassified.
  • Sony RTMD per-frame attributes + IMU export. RTMDReader already surfaced clip-level summaries; the new rtmd-frames CLI subcommand walks every rtmd sample and emits one of three CSV streams — attributes (frame-level ISO, exposure, F-number, focal length, white balance, GPS, date-time, serial), gyroscope (timestamp + pitch/roll/yaw), or accelerometer (timestamp + xyz). Verified against Sony A1 / FX3 / FX30 footage at 2 kHz IMU sampling.

Changed

  • MP4Parser.swift decomposed (no behavior change). The 3,277-line monolith is now split along its existing MARK: boundaries into five files held together by extension MP4Parser:
    • MP4Parser.swift (477 lines) — top-level dispatch, mvhd, format detection
    • MP4UserData.swift (775) — udta/meta/ilst, GPS ©xyz, XMP/NRT uuid, BRAW per-frame bmdf header
    • MP4VisualSampleEntry.swift (557) — stsd visual entry, codec configs (avcC/hvcC/av1C/vvcC/dvcC/dvvC), HDR side-data (mdcv/clli), ProRes/APV FourCC defaults
    • MP4AudioSampleEntry.swift (290) — stsd audio entry, chan, esds
    • MP4TrackParser.swift (881) — trak walking, tkhd/mdhd/edts, timecode-track decoding
    • MP4Chapters.swift (364) — Nero chpl, QuickTime tref→chap, sample-table helpers shared with RTMDReader/BRAWFrameReader
      6.9× reduction in the main file. Verified by diffing the JSON read sweep over 332 mixed video / image files in the local corpus before and after — output is byte-identical.

Fixed

  • Linux cross-compile broken by the ARRIRAW commit. CFNumberIsFloatType is CoreFoundation, Apple-only — swift-corelibs-foundation doesn't ship it, so the static-musl Linux builds failed at the ARRI JSON slate stringifier added in af31434. Replaced with a Swift cast-order check (as? Int64 first; otherwise format as %g), preserving observable output on both platforms.
  • Phase26 --map test asserted lowercase XMP-dc:title / :description while ExifTool-conventional capitalization (XMP-dc:Title / :Description) had already landed in 3374496. Test now asserts the canonical form.

Tests

1478 tests, 0 failures (26 skipped). Verified end-to-end across the local corpus:

  • 47 images (jpg / arw / cr3 / heic / jxl) read sweep — 0 errors
  • 64 videos (8 X-OCN, 12 MXF, 2 ARRIRAW, 2 RED, 1 Nikon RAW, 3 BRAW, 2 CRM, 18 MP4, 11 MOV, …) — 0 errors
  • 3/3 BRAW clips × 821 per-frame rows
  • 7/7 RTMD-bearing clips × ~27k attribute rows + ~1.1M IMU samples each
  • MCA labels match the bmx labels.txt ground truth byte-for-byte
  • macOS arm64 + Linux aarch64 + Linux x86_64 binaries all return identical metadata for image / X-OCN / BRAW spot checks

Binaries

This release ships three CLI binaries:

  • swift-exif-macos-arm64 (5.7 MB, Mach-O arm64, -O+WMO)
  • swift-exif-linux-aarch64 (24 MB, static ELF musl aarch64, -Onone)
  • swift-exif-linux-x86_64 (26 MB, static ELF musl x86_64, -Onone)

Linux binaries tested on alpine:3.20 for both arches.