PR #25579 opened by Zhao Zhili (quink)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25579
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25579.patch

# Summary of changes

DJI cameras store flight and gimbal data in djmd and dbgi metadata
tracks: a 20-byte sample entry, a child box of the same name in gmhd,
and the meta handler named "CAM meta" or "CAM dbgi".

**DJI doesn't registered the fourcc at https://mp4ra.org/search, so as GoPro 
gpmd**



>From 6d69eafd2208fb08b3825a93dd710b812d5d142f Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
Date: Thu, 29 Oct 2026 13:20:13 +0800
Subject: [PATCH 1/2] avformat/mov: demux DJI djmd and dbgi tracks as bin_data

DJI cameras write flight and gimbal data into djmd and dbgi tracks
whose sample entries use a private fourcc under the meta handler.
Map them to bin_data, as is already done for the GoPro gpmd track.

Signed-off-by: Zhao Zhili <[email protected]>
---
 libavformat/isom.c | 2 ++
 libavformat/isom.h | 3 +++
 2 files changed, 5 insertions(+)

diff --git a/libavformat/isom.c b/libavformat/isom.c
index 0a2f93d762f..09be63aa193 100644
--- a/libavformat/isom.c
+++ b/libavformat/isom.c
@@ -81,6 +81,8 @@ const AVCodecTag ff_codec_movsubtitle_tags[] = {
 
 const AVCodecTag ff_codec_movdata_tags[] = {
     { AV_CODEC_ID_BIN_DATA, MKTAG('g', 'p', 'm', 'd') },
+    { AV_CODEC_ID_BIN_DATA, MOV_MP4_DJMD_TAG },
+    { AV_CODEC_ID_BIN_DATA, MOV_MP4_DBGI_TAG },
     { AV_CODEC_ID_ITUT_T35, MKTAG('i', 't', '3', '5') },
     { AV_CODEC_ID_NONE, 0 },
 };
diff --git a/libavformat/isom.h b/libavformat/isom.h
index 18c2fe41b9a..6230218e37f 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -507,6 +507,9 @@ static inline enum AVCodecID ff_mov_get_lpcm_codec_id(int 
bps, int flags)
 #define MOV_MP4_FPCM_TAG  MKTAG('f', 'p', 'c', 'm')
 #define MOV_MP4_IPCM_TAG  MKTAG('i', 'p', 'c', 'm')
 
+#define MOV_MP4_DJMD_TAG  MKTAG('d', 'j', 'm', 'd')
+#define MOV_MP4_DBGI_TAG  MKTAG('d', 'b', 'g', 'i')
+
 struct MP4TrackKindValueMapping {
     int         disposition;
     const char *value;
-- 
2.54.0


>From 6ab132f5b44849ebe35d9db662c36af483887271 Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
Date: Thu, 29 Oct 2026 15:24:48 +0800
Subject: [PATCH 2/2] avformat/movenc: add DJI djmd and dbgi metadata support

DJI cameras store flight and gimbal data in djmd and dbgi metadata
tracks: a 20-byte sample entry, a child box of the same name in gmhd,
and the meta handler named "CAM meta" or "CAM dbgi".

Signed-off-by: Zhao Zhili <[email protected]>
---
 libavformat/movenc.c | 34 +++++++++++++++++++++++++++++++++-
 1 file changed, 33 insertions(+), 1 deletion(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index debe1acb7e0..d6b6a87688f 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3244,6 +3244,18 @@ static int mov_write_gpmd_tag(AVIOContext *pb, const 
MOVTrack *track)
     return update_size(pb, pos);
 }
 
+static int mov_write_dji_tag(AVIOContext *pb, const MOVTrack *track, uint32_t 
tag)
+{
+    avio_wb32(pb, 20);
+    avio_wl32(pb, tag);
+    avio_wb32(pb, 0); /* Reserved */
+    avio_wb16(pb, 0); /* Reserved */
+    avio_wb16(pb, 1); /* Data-reference index */
+    avio_wb32(pb, 0); /* Reserved */
+
+    return 0;
+}
+
 static int mov_write_stsd_tag(AVFormatContext *s, AVIOContext *pb, 
MOVMuxContext *mov, MOVTrack *track)
 {
     int64_t pos = avio_tell(pb);
@@ -3269,6 +3281,9 @@ static int mov_write_stsd_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContext
         ret = mov_write_tmcd_tag(pb, track);
     else if (track->par->codec_tag == MKTAG('g','p','m','d'))
         ret = mov_write_gpmd_tag(pb, track);
+    else if (track->par->codec_tag == MOV_MP4_DJMD_TAG ||
+             track->par->codec_tag == MOV_MP4_DBGI_TAG)
+        ret = mov_write_dji_tag(pb, track, track->par->codec_tag);
 
     if (ret < 0)
         return ret;
@@ -3615,6 +3630,13 @@ static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack 
*track)
         ffio_wfourcc(pb, "gpmd");
         avio_wb32(pb, 0); /* version */
         update_size(pb, gpmd_pos);
+    } else if (track->par->codec_tag == MOV_MP4_DBGI_TAG) {
+        avio_wb32(pb, 12);
+        avio_wl32(pb, MOV_MP4_DBGI_TAG);
+        avio_wb32(pb, 0);
+    } else if (track->par->codec_tag == MOV_MP4_DJMD_TAG) {
+        avio_wb32(pb, 8);
+        avio_wl32(pb, MOV_MP4_DJMD_TAG);
     }
     return update_size(pb, pos);
 }
@@ -3707,6 +3729,12 @@ static int mov_write_hdlr_tag(AVFormatContext *s, 
AVIOContext *pb, MOVTrack *tra
         } else if (track->par->codec_tag == MKTAG('g','p','m','d')) {
             hdlr_type = "meta";
             descr = "GoPro MET"; // GoPro Metadata
+        } else if (track->par->codec_tag == MOV_MP4_DJMD_TAG) {
+            hdlr_type = "meta";
+            descr = "CAM meta";
+        } else if (track->par->codec_tag == MOV_MP4_DBGI_TAG) {
+            hdlr_type = "meta";
+            descr = "CAM dbgi";
         } else {
             av_log(s, AV_LOG_WARNING,
                    "Unknown hdlr_type for %s, writing dummy values\n",
@@ -3956,7 +3984,9 @@ static int mov_write_minf_tag(AVFormatContext *s, 
AVIOContext *pb, MOVMuxContext
             mov_write_nmhd_tag(pb);
         else
             mov_write_gmhd_tag(pb, track);
-    } else if (track->tag == MKTAG('g','p','m','d')) {
+    } else if (track->tag == MKTAG('g','p','m','d') ||
+               track->tag == MOV_MP4_DJMD_TAG ||
+               track->tag == MOV_MP4_DBGI_TAG) {
         mov_write_gmhd_tag(pb, track);
     }
     if (track->mode == MODE_MOV) /* ISO 14496-12 8.4.3.1 specifies hdlr only 
within mdia or meta boxes */
@@ -9492,6 +9522,8 @@ static const AVCodecTag codec_mp4_tags[] = {
     { AV_CODEC_ID_DVD_SUBTITLE,    MKTAG('m', 'p', '4', 's') },
     { AV_CODEC_ID_MOV_TEXT,        MKTAG('t', 'x', '3', 'g') },
     { AV_CODEC_ID_BIN_DATA,        MKTAG('g', 'p', 'm', 'd') },
+    { AV_CODEC_ID_BIN_DATA,        MOV_MP4_DJMD_TAG          },
+    { AV_CODEC_ID_BIN_DATA,        MOV_MP4_DBGI_TAG          },
     { AV_CODEC_ID_MPEGH_3D_AUDIO,  MKTAG('m', 'h', 'm', '1') },
     { AV_CODEC_ID_TTML,            MOV_MP4_TTML_TAG          },
     { AV_CODEC_ID_TTML,            MOV_ISMV_TTML_TAG         },
-- 
2.54.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to