[FFmpeg-devel] [PATCH 6/6] libavformat/movenc: add dnxhr compatibility for apple players

Mark Reid mindmark at gmail.com
Tue Jul 5 04:07:02 EEST 2016


---
 libavformat/movenc.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index d614933..e97fb74 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -32,6 +32,7 @@
 #include "isom.h"
 #include "avc.h"
 #include "libavcodec/ac3_parser.h"
+#include "libavcodec/dnxhddata.h"
 #include "libavcodec/get_bits.h"
 #include "libavcodec/put_bits.h"
 #include "libavcodec/vc1_common.h"
@@ -1070,20 +1071,16 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
     int cid;
 
     if (track->vos_data && track->vos_len > 0x29) {
-        if (track->vos_data[0] == 0x00 &&
-            track->vos_data[1] == 0x00 &&
-            track->vos_data[2] == 0x02 &&
-            track->vos_data[3] == 0x80 &&
-            (track->vos_data[4] == 0x01 || track->vos_data[4] == 0x02)) {
+        if (avpriv_dnxhd_parse_header_prefix(track->vos_data) != 0) {
             /* looks like a DNxHD bit stream */
             interlaced = (track->vos_data[5] & 2);
             cid = AV_RB32(track->vos_data + 0x28);
         } else {
-            av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream in vos_data\n");
+            av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD/HR bit stream in vos_data\n");
             return 0;
         }
     } else {
-        av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD bit stream, vos_data too small\n");
+        av_log(NULL, AV_LOG_WARNING, "Could not locate DNxHD/HR bit stream, vos_data too small\n");
         return 0;
     }
 
@@ -1099,6 +1096,17 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
     }
     avio_wb32(pb, 0); /* unknown */
 
+    if (track->par->codec_id == AV_CODEC_ID_DNXHR) {
+        avio_wb32(pb, 32);
+        ffio_wfourcc(pb, "ADHR");
+        ffio_wfourcc(pb, "0001");
+        avio_wb32(pb, cid);
+        avio_wb32(pb, 0); /* unknown */
+        avio_wb32(pb, 1); /* unknown */
+        avio_wb32(pb, 0); /* unknown */
+        avio_wb32(pb, 0); /* unknown */
+        return 0;
+    }
     avio_wb32(pb, 24); /* size */
     ffio_wfourcc(pb, "APRG");
     ffio_wfourcc(pb, "APRG");
@@ -1112,6 +1120,7 @@ static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track)
     ffio_wfourcc(pb, "0001");
     avio_wb32(pb, cid); /* dnxhd cid, some id ? */
     avio_wb32(pb, track->par->width);
+
     /* values below are based on samples created with quicktime and avid codecs */
     if (interlaced) {
         avio_wb32(pb, track->par->height / 2);
@@ -1763,7 +1772,7 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr
             track->par->codec_id == AV_CODEC_ID_SVQ3) {
         mov_write_extradata_tag(pb, track);
         avio_wb32(pb, 0);
-    } else if (track->par->codec_id == AV_CODEC_ID_DNXHD) {
+    } else if (track->par->codec_id == AV_CODEC_ID_DNXHD || track->par->codec_id == AV_CODEC_ID_DNXHR) {
         mov_write_avid_tag(pb, track);
         avid = 1;
     } else if (track->par->codec_id == AV_CODEC_ID_HEVC)
@@ -1788,7 +1797,8 @@ static int mov_write_video_tag(AVIOContext *pb, MOVMuxContext *mov, MOVTrack *tr
 
     if (track->par->codec_id != AV_CODEC_ID_H264 &&
         track->par->codec_id != AV_CODEC_ID_MPEG4 &&
-        track->par->codec_id != AV_CODEC_ID_DNXHD) {
+        track->par->codec_id != AV_CODEC_ID_DNXHD &&
+        track->par->codec_id != AV_CODEC_ID_DNXHR) {
         int field_order = track->par->field_order;
 
 #if FF_API_LAVF_AVCTX
@@ -4666,7 +4676,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     /* copy extradata if it exists */
     if (trk->vos_len == 0 && par->extradata_size > 0 &&
         !TAG_IS_AVCI(trk->tag) &&
-        (par->codec_id != AV_CODEC_ID_DNXHD)) {
+        (par->codec_id != AV_CODEC_ID_DNXHD || par->codec_id != AV_CODEC_ID_DNXHR)) {
         trk->vos_len  = par->extradata_size;
         trk->vos_data = av_malloc(trk->vos_len);
         if (!trk->vos_data) {
@@ -4740,6 +4750,7 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
     }
 
     if ((par->codec_id == AV_CODEC_ID_DNXHD ||
+         par->codec_id == AV_CODEC_ID_DNXHR ||
          par->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) {
         /* copy frame to create needed atoms */
         trk->vos_len  = size;
@@ -5626,7 +5637,8 @@ static int mov_write_header(AVFormatContext *s)
         if (st->codecpar->extradata_size) {
             if (st->codecpar->codec_id == AV_CODEC_ID_DVD_SUBTITLE)
                 mov_create_dvd_sub_decoder_specific_info(track, st);
-            else if (!TAG_IS_AVCI(track->tag) && st->codecpar->codec_id != AV_CODEC_ID_DNXHD) {
+            else if (!TAG_IS_AVCI(track->tag) && (st->codecpar->codec_id != AV_CODEC_ID_DNXHD ||
+                                                  st->codecpar->codec_id != AV_CODEC_ID_DNXHR)) {
                 track->vos_len  = st->codecpar->extradata_size;
                 track->vos_data = av_malloc(track->vos_len);
                 if (!track->vos_data) {
-- 
2.7.3



More information about the ffmpeg-devel mailing list