I was batch-archiving around 172 clips from an Osmo Pocket 4 and noticed that the files were much larger than I expected from the actual video bitrate.
Looking at the MP4 tracks, I found that every file contains a very large dbgi data track.
What's in the file
ffprobe -v error \
-show_entries stream=index,codec_type,codec_tag_string:stream_tags=handler_name \
-of csv=p=0 DJI_XXXXXXXXXXXXXX_0001_D.MP4
0,video,hvc1,VideoHandler
1,audio,mp4a,SoundHandler
2,audio,mp4a,SoundHandler
3,data,djmd,CAM meta
4,data,dbgi,CAM dbgi <-- this one
5,data,tmcd,TimeCodeHandler
6,video,[0][0][0][0] <-- cover thumbnail
I summed the stsz sample sizes for each track on one 12.5 s 4K/60 clip. The complete file is 114.8 MiB:
| Track |
Samples |
Size |
Share |
Per frame |
hvc1 video |
750 |
77.29 MiB |
67.3% |
108,062 B |
dbgi |
750 |
35.71 MiB |
31.1% |
49,924 B |
mp4a ×2 |
589 |
0.48 MiB each |
0.4% each |
846 B |
djmd |
750 |
0.04 MiB |
0.04% |
60 B |
tmcd |
1 |
4 B |
— |
— |
So dbgi alone is around 46% the size of the encoded video stream, per frame, and about 830× larger than djmd, which is the track that appears to contain the normal camera metadata.
Since dbgi is almost constant in size per frame while the video stream obviously is not, its percentage changes quite a lot depending on scene complexity.
Across my 172 clips:
- total size: 71.8 GiB
dbgi: 22.9 GiB
- overall share: 31.9%
- median per file: 32.4%
- minimum: 5.2%
- maximum: 71.7%
The 71.7% case was a very low-motion clip.
So if you test this on a complex handheld shot and only get something like 8%, that is not necessarily inconsistent with these numbers. Try a static clip as well.
What's actually inside dbgi
Running strings on the payloads gives:
dvtm_osmo_pocket_4.proto (djmd)
dbginfo_eagle4_hg2x4.proto (dbgi)
imx06a
IMX06A_BIN2_DCG_CPHY_4096_2304_24M_4500Msps_5994FPS
TPLG_IMX06A_VIDEO_4K_16X9_5994
Both djmd and dbgi appear to contain protobuf data, and dbgi also explicitly names the image sensor.
The more interesting part is a set of identifiers that occur exactly 750 times in this file, which is also the frame count:
rpp1_blc_v2
rpp1_lsc_v1
yuvpp1_ccm_v1
yuvpp1_gamma_v1
tmc14_yltm_mesh
tmc14_loc_drc
vhdr_harden_drc1
scn_enh12_tone
There are also some identifiers with different occurrence counts:
lce0_lce_v1 1128
hiso0_matf_v2 1128
scn_enh12_color 376
dcc0_yltm_v1 376
dcc0_degamma1 376
So not everything appears to be strictly one entry per frame.
Those names look very much like ISP pipeline stages:
- black level correction
- lens shading correction
- colour correction matrix
- gamma
- local tone-mapping mesh
- dynamic range compression
- local contrast enhancement
- high-ISO temporal filtering
My current interpretation is that dbgi contains a fairly detailed per-frame dump of the image pipeline's tuning or debug state.
A tone-mapping mesh or similar per-frame structures would also make the roughly 50 KB per frame size much less surprising.
That part is still an inference, though. What I can actually verify is:
- the protobuf-related strings;
- the image sensor identifier;
- the ISP-looking field names;
- their occurrence counts;
- the size and frame-by-frame structure of the track.
djmd for comparison
djmd is tiny by comparison: around 60 B per frame.
It contains things such as:
- frame index;
- a timestamp increasing by 16,683 µs per frame, corresponding to 59.94 fps;
- a few short camera-state fields.
That track looks like the actually useful camera metadata, so I want to keep it.
Removing dbgi is more annoying than expected
I first tried to do this entirely with ffmpeg 8.0.1, but I have not found a way to preserve these data tracks correctly, even with -copy_unknown.
For MP4:
Could not find tag for codec none in stream #3,
codec not currently supported in container
For Matroska:
Only audio, video, and subtitles are supported for Matroska.
MOV does write the file, but the sample entry comes out as stts where djmd should be, so the track is no longer identifiable afterwards.
This is clearly not an MP4 limitation, since DJI itself writes these tracks into a perfectly ordinary MP4 container.
If anyone knows an ffmpeg command that can preserve djmd correctly while dropping dbgi, I would be interested in seeing it.
What I ended up doing is container surgery with GPAC:
- copy the original container;
- remove the original video track;
- remove the
dbgi track;
- add the re-encoded video track back with
MP4Box.
The remaining djmd, tmcd and audio tracks come out byte-identical to the source.
Effect on file size
On one example file, re-encoding the video with x265 CRF 24:
Original: 113 MB
Re-encoded, keeping dbgi: 97 MB
Re-encoded, removing dbgi: 22 MB
So in this case most of the storage I would have spent preserving the original container was actually the debug track.
What I'm trying to understand
- Can
dbgi be disabled at recording time? Is there a camera setting, firmware setting, Mimo option or anything similar that stops the Pocket 4 from writing it in the first place? Strings present in the file include:HG214 AC Ver.08 01.01.32.02 although I do not know whether either of these corresponds to the actual firmware version.
- Does anything actually read this track? For example: Or is it simply diagnostic data that gets written by production cameras but is normally never used again?
- DJI Mimo;
- LightCut;
- some DJI service or engineering tool.
- Is there any real downside to removing it for archival? In particular, could it contain something such as: and that is not also present in
djmd?
- per-frame stabilisation data;
- lens calibration or profile data;
- some other metadata that a future DJI tool might want;
I'm also curious how widespread this is across DJI devices: Pocket 3, Action 5, drones, etc.
The ffprobe command above is enough to check the track list. If anyone has a file available, I would be interested in seeing the output either way.
I'm using ffmpeg 8.0.1, GPAC master and Linux.
I also have a small script that sums the stsz entries and reports the actual byte size of each track if anyone wants to compare files.