AXIOM Beta/Raw Recording

From apertus wiki
Revision as of 14:27, 21 March 2024 by Sebastian (talk | contribs) (→‎4096 Pixel Width Raw Mode)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

1 Overview

Simplified: The AXIOM Recorder is a small computer connected to the AXIOM Beta via HDMI, we use the HDMI video stream to transport our own custom raw image data from the camera. This stream needs to be repacked or post processed on the AXIOM Recorder to acquire the actual raw image sequence (RAW12 sequence). First software prototypes did this after recording, newer versions do it on-the-fly while recording.

Technical: On the AXIOM Beta we utilize a Full HD (1920 x 1080) HDMI output stream with twice the frame-rate to store 4 pixels (12 bit each) from the image sensor (sensels) in 2 RGB pixels (24 bit each) in the HDMI stream. After recording this data through a HDMI capture device like the Magewell HDMI USB3 Gen 2 on a PC, Laptop or Single Board Computer (SBC) the data needs to be post processed to obtain the original raw data from the image sensor again. The two HDMI images from a single raw image are called A-Frame and B-Frame.

2 Recording Principle

Axiom recorder raw recording principle.png

3 Pixel Packing V3 Structure

Traditional HDMI signal:

Hdmi output signal.png

AXIOM Beta raw mode output:

Axiom raw hdmi output signal.png

Essentially from a 2x2 sensel block on the image sensor R, G1 go into the A frame and G2, B into the B frame of a HDMI stream.

Images from the HDMI stream look like this then:

Axiom raw hdmi a-frame.jpg Axiom raw hdmi b-frame.jpg.jpg

4 Post Processing Principle

Version 1 Prototype:

Axiom beta raw recording principle.png


  • Content of single *.rgb file and *.frame sequence should - if everything worked correctly - be 100% bit identical. So *.rgb file could be deleted after *.frame sequence extraction.

5 Recorder Hardware

Basically any PC with USB3 and a fast solid state memory should work fine. So far we have tested 3 devices. The goals are in general to have an as small as possible form factor, as low as possible power consumption (as we will be operating on batteries often) but enough speed/performance to reliably capture footage (also for longer durations) and process / playback the image sequences smoothly. Obviously any recent laptop/notebook or desktop PC will work well but here we want to focus on the much smaller form factors.

5.1 Raspberry Pi 5

The Raspberry Pi 5 is a rather powerful but still cheap widely available single board computer. It provides 2 MIPI interfaces and a PCIe interface through flex PCB connectors.

With the Geekworm C790 Raspberry Pi HDMI CSI CSI-2 Adapter we can connect two HDMI Input interfaces to the raspberry pi and with an NVME SSD shield attach fast solid state memory to the system. We succesfully tested with the Geekworm X1002 PCIe M.2 NVMe SSD PIP PCIe Peripherie Bottom Board for Raspberry Pi 5.

We tested with Rasperry Pi OS (64bit).

5.1.1 Configuration

In /boot/firmware/config.txt

dtparam=pciex1_gen=3 # to run NVMe SSD with Gen3 PCIe

5.2 Intel NUC


recommended for AXIOM Recorder use: Yes
Tested an Intel NUC NUC7i5BNK, that's a 2017 model for around 400€
CPU: i5-7260U (Passmark 3868, TDP: 15 W)
Dimensions: approximately 4 × 4 inches (101.6 × 101.6 mm)
M.2 slot with PCIe x4 lanes

5.3 Rockpi 4 Model C


recommended for AXIOM Recorder use: No
4GB RAM (soldered)
CPU: Rockchip RK3399
Dimensions: 85 × 54mm (the smallest of the 3)
M.2 PCIe slot for SSD with four lanes PCIe 2.0
Unfortunately we could not get the M.2 SSD to perform fast enough for our purposes on the Rockpi 4 - maybe the PCIe 2.0 is the bottleneck.
Retail price: 60$

5.4 Lattepanda Alpha 864s


recommended for AXIOM Recorder use: Yes
CPU: Intel 8th m3--8100y (~4000 passmark claimed by manufacturer, TDP 15W)
8GB RAM (soldered)
Dimensions: 115 × 78 × 14 mm (2nd most compact of the 3 devices)
active cooling option is very silent, entirely passive cooling available from manufacturer
has onboard 64GB flash memory for operating system
Retail price: ~400€

5.5 LattePanda 3 Delta

Similar form factor as Lattepanda Alpha 864s and similar performance but slightly cheaper.
Dimensions: 125 x 78 x 16mm
1x M.2 M Key, PCIe 3.0 2x, Supports NVMe SSD
Retail price: $279.00
Intel® Celeron® N5105
recommended for AXIOM Recorder use: needs to be be tested.

5.6 Rock 5 Model B

Supports PCle 3.0 x4 NVMe SSD
HDMI in support up to 4K@60FPS - does this make the magewell obsolete? -> needs to be tested!
Dimensions: 100 x 72mm
Retail price: starting at ~200€ for 8GB RAM version
recommended for AXIOM Recorder use: needs to be be tested.

5.7 Magewell USB HDMI Gen 2

Magewell hdmi usb3.png

The exact model we use is called “Magewell USB Capture HDMI Gen 2” Part number: 32060. It retails for around 350-400€ and can be bought used for around 250€, we discovered offers as low as 100$ on ebay.

Note: there are clones (eg. on Amazon) that look almost exactly like the Magewell device and promise similar features:

Magewell clone.png

We were curious and bought one. Unfortunately the electronics inside are totally different and we could not even get the device to display a HDMI signal from the AXIOM Beta so we can not recommend those.

6 Requirements and Introduction

In addition to the AXIOM Beta with 1 or 2 HDMI plugin modules you need a USB Capture HDMI Gen 2 device from Magewell: connected to the HDMI output of the AXIOM Beta.

A PC/laptop/SBC connected to the AXIOM Beta is also required (see Recorder Hardware above), all instructions here assume this PC/laptop/SBC is running Linux - other operating systems are not supported by this guide - they might work - we have not tested them.

Commands to be run on the Linux PC are indicated like:

$ command

Commands to be run on the AXIOM Beta are indicated like:

[root@beta ~]# command

6.1 AXIOM Beta firmware flashing

For a full guide about firmware flashing/backup see: Firmware Flashing

6.2 Determine Magewell Video Device ID

Install v4l2-ctl:

$ sudo apt install v4l2-ctl

Run the tool:

$ v4l2-ctl --list-devices

This should output a list, in this case telling you that the magewell device is /dev/video2 and /dev/video3 (the internal webcam is /dev/video0 and /dev/video1):

USB Capture HDMI: USB Capture H (usb-0000:00:14.0-2):

Integrated Camera: Integrated C (usb-0000:00:1a.0-1.6):

6.3 Download, Install & Run Magewell Setup Tool

This raw recording method relies on a USB HDMI capture device like the one produced by Magewell that can capture 1920x1080 at 60 FPS without any compression or image manipulation. .

download setup tool from magewell website:


$ sudo usbcaptureutility

under video set:

  • input color format: RGB
  • input quantization: full-range
  • capture color format: RGB
  • capture quantization: full-range
  • capture saturation: full-range
  • Specific Effect: Flip

under advanced set:

  • color format: only leave RGB24 on the left, move all other options to the right
  • frame rate: only leave 60.00 on the left, move all other options to the right
  • resolution, only leave 1920x1080 on the left, move all other options to the right

Magewell setup tool.png

click “save to device”, disconnect and reconnect device

Settings will be stored in the device even when you disconnect it so these steps only need to be completed once.

6.4 Check Transmission Data Integrity (optional)

To test if the magewell device is receiving data from the AXIOM Beta in a reliable way (good cables are essential for example) the following method can be used:

assuming the magewell input is /dev/videoX:

using Firmware 1.0:

init raw mode on AXIOM Beta

[root@beta ~]# ./

stop the acquisition with:

[root@beta ~]# fil_reg 15 0

then load a gradient overlay:

[root@beta ~]# ./mimg -T4

disable overlay:

[root@beta ~]# ./mimg -O -P0

Reset gamma and color matrix settings:

[root@beta ~]# ./ 1
# ./ 1

on magewell connected pc run (assuming the magewell input is /dev/videoX):

$ ffmpeg -report -i /dev/videoX -map 0 -f framehash -hash md5 - 2>/dev/null

this should output many lines containing the hash:


then let it run for 15 minutes with (assuming the magewell input is /dev/videoX):

$ ffmpeg -report -i /dev/videoX -map 0 -f framehash -hash md5 - 2>/dev/null | grep -v ddbfb96e4b8d5191bb274885ccc0264d

no hashes should be reported, if hashes are reported this could mean a bad cable/bad connection

while the hash test is running on the camera depending on the HDMI plugin module being connected to the top plugin module slot set:

[root@beta ~]# scn_reg 31 0x5000

and then:

[root@beta ~]# scn_reg 31 0x4000

no different hashes should be reported still or the bottom plugin module slot:

[root@beta ~]# scn_reg 30 0x5000

and then:

[root@beta ~]# scn_reg 30 0x4000

no different hashes should be reported still

now stop the hash comparing line.

7 Usage Instructions

7.1 Initialize Raw Mode on AXIOM Beta

Firmware 1.0:

[root@beta ~]# ./

Firmware 2.0:

[root@beta ~]# raw

7.2 Clear Overlay

Firmware 1.0:

[root@beta ~]# ./mimg -a -o -P 0

Firmware 2.0:

[root@beta ~]# axiom_mimg -a -o -P 0

7.3 Check HDMI Stream

assuming the magewell input is /dev/videoX:

$ ffplay /dev/videoX

7.4 Frame-rate Verification

on AXIOM Beta run the performance tool: Firmware 1.0:

[root@beta ~]# ./cmv_perf3

Firmware 2.0:

[root@beta ~]# axiom_perf

For 30 FPS this should output something similar to:

mapped 0x60000000+0x00400000 to 0x60000000.
mapped 0x80000000+0x00400000 to 0x80000000.
hdmi: 60.27 FPS     cseq: 29.97 FPS

If the reported FPS are lower you need to reduce the exposure time (run performance tool again afterwards to check if the changes had the desired effect):

Firmware 1.0:

[root@beta ~]# ./cmv_snap3 -e 11ms -z

Firmware 2.0:

[root@beta ~]# axiom_snap -e 11ms -z

7.5 Raw HDMI Related Commands

The first parameter of scn_reg defines which plugin module/shield slot is affected:

31 - top (North) HDMI plugin module 
30 - bottom (South) HDMI plugin module 
29 - HDMI Shield

set bottom HDMI plugin module to: live view:

Firmware 1.0:

[root@beta ~]# scn_reg 30 0x0000

Firmware 2.0:

[root@beta ~]# axiom_scn_reg 30 0x0000

set bottom HDMI plugin module to: A channel / A frames:

Firmware 1.0:

[root@beta ~]# scn_reg 30 0x5000

Firmware 2.0:

[root@beta ~]# axiom_scn_reg 30 0x5000

set bottom HDMI plugin module to: B channel / B frames:

Firmware 1.0:

[root@beta ~]# scn_reg 30 0x6000

Firmware 2.0:

[root@beta ~]# axiom_scn_reg 30 0x6000

set bottom HDMI plugin module to: A/B frames alternating:

Firmware 1.0:

[root@beta ~]# scn_reg 30 0x7000

Firmware 2.0:

[root@beta ~]# axiom_scn_reg 30 0x7000

activates the four corner markers (all 4 corner pixels are identical):

Firmware 1.0:

[root@beta ~]# ./

Firmware 2.0:

[root@beta ~]#

  • red channel: contains 8 bit frame counter to identify A-frames (even) and B-frames (odd) and verify that no frames were dropped during transfer/capture
  • green channel: wrsel buffer information (write select and read select buffers - 4 bit total) wrsel <= wbuf_sel & rbuf_sel (VHDL) split with upper/lower nibble
  • blue channel: 0x55 / 85 (A-frame) and 0xAA / 170 (B-frame)

Note: Activating the corner markers is essential for post processing the captured files later so do not forget to do this.

set corner marker frame counter max to 256:

Note: This is essential for post processing the captured files later so do not forget to do this.

Firmware 1.0:

[root@beta ~]# scn_reg 2 0x100

Firmware 2.0:

[root@beta ~]# axiom_scn_reg 2 0x100

7.6 Record Raw Video with ffmpeg

$ ffmpeg -i /dev/videoX -map 0 -pix_fmt rgb24 recording.rgb

7.7 Extract Image Sequence

To extract the individual frames from a single *.rgb file after recording do:

$ split recording.rgb recording_frame_ --additional-suffix=.frame -d -b 6220800 --verbose --suffix-length=5

6220800 here corresponds to the file size in bytes of one frame (1920 x 1080 x 24bit / 8)

7.8 Corner Markers

There are 4 corner markers in a *.frame:

  • red channel: contains 8 bit frame counter to identify A-frames (even) and B-frames (odd) and see if no frames were dropped during transfer/capture
  • green channel: wrsel buffer information
  • blue channel: 0x55 / 85 (A-frame) and 0xAA / 170 (B-frame)

Read corner marker pixel value from a *.frame file:

$ head -c 3 recording_frame_00001.frame | od -t x1

Note the order (of the hexadecimal values):

0000000 43 04 AA 
        R  G  B

AA = indicates this is a B-frame in blue channel
43 = frame counter in red channel

7.9 Recover raw12 from A+B frames

We created a small tool for this called frame-merge, prerequisite, compile & install from source:

Usage to convert one A+B frame pair to a raw12:

$ frame-merge a-frame.frame b-frame.frame output.raw12

7.10 Convert raw12 to DNG

prerequisite, compile & install from source:

Convert a raw12 to DNG:

$ raw2dng output.raw12 --width=3840 --height=2160 --bayer-order=2

7.11 Identify skipped/double frames in raw recording

There can be several reasons for skipped frames:

  • bad HDMI/USB cable
  • recording media too slow
  • Recorder CPU at full load or doing other stuff on the side (depends on CPU and system of course)

We created a script that can be used to show framecounter (and that way identify missing/double frames) and A/B Frame identification of all files in a folder:

Usage example:

$ python3 -i myfolder/

Example output:

*.frame files found in folder: 698

filename              framecounter      A/B frame
test_frame_00077.bgr        142            A-Frame
test_frame_00078.bgr        143            B-Frame
test_frame_00079.bgr        144            A-Frame
test_frame_00080.bgr        145            B-Frame
test_frame_00081.bgr        145            B-Frame     framecounter missmatch
test_frame_00082.bgr        146            A-Frame
test_frame_00083.bgr        147            B-Frame
test_frame_00084.bgr        148            A-Frame
test_frame_00085.bgr        149            B-Frame

8 4096 Pixel Width Raw Mode

The HDMI signal can go up to 2048 width so with reconstructing raw data we can achieve 4096 original image sensor width that way.

This allows to get the 8 pixels black coloumns into the recorded frame and enables advanced noise compensation, make sure to enable the black coloumns first though (cmv_snap3 / axiom_snap)

In the Magewell Setup Tool (usbcaptureutility) set 2048x1080 as only resolution on the left column, then save to device and reconnect device.

On the AXIOM Beta run:

Firmware 2.0:

sudo su
memtool -1 -F 0x0 0x18000000 0x8000000 raw 2048x1080p50 or 2048x1080p60 0
axiom_scn_reg 30 0x7000
axiom_scn_reg 2 0x100

Then enable the black coloumns:

Firmware 2.0:

axiom_snap -E -b -z

To view the HDMI signal on the connected magewell run:

$ffplay -video_size 2048x1080 /dev/videoX

9 raw12 Image Viewer

Raw12 viewer.png

We created a python based GUI ( that can load and display raw12 preview image rather quickly. The focus here is not accurate color representation or high quality conversion but rather to quickly be able to see the content of an image. For high grade processing & conversion use the raw2dng utility ( instead.

Set up filetype association see Raw12_viewer

10 raw12 Sequence Playback


sudo apt install cmake
git clone
cd axiom-recorder
cargo build --release --all


cargo run --release  ! RawDirectoryReader --file-pattern '/path/to/your/*.raw12' --bit-depth 12 --height 2160 --width 3840 --first-red-x true --first-red-y false --fps 30 ! GpuBitDepthConverter ! Debayer ! Display

11 Output Latency Tests

Tests were conducted in 24 fps mode.

Test 1: Direct HDMI output from the AXIOM Beta:
Delay is 2 frames (1 from camera internal buffering, 1 from the Monitor)

Test 2: Color HDMI output through Magewell USB3 device on Lattepanda Alpha 864S, displayed with ffplay:
Delay: 5 frames

Test 3: Raw HDMI output through Magewell USB3 device on Lattepanda Alpha 864S, displayed with live debayering in axiom-recorder software
Delay: 7 - 16 frames: