]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/matroskaenc.c
avformat: support shorten in nistshpere demuxer
[ffmpeg] / libavformat / matroskaenc.c
index f42434b59ca7cf06a2c24260a7a32d4a1f933fd0..0546686d8e87836401139655f758242764e71755 100644 (file)
@@ -41,6 +41,7 @@
 #include "libavutil/intfloat.h"
 #include "libavutil/intreadwrite.h"
 #include "libavutil/lfg.h"
+#include "libavutil/mastering_display_metadata.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/opt.h"
 #include "libavutil/random_seed.h"
@@ -730,6 +731,64 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb,
     return ret;
 }
 
+static int mkv_write_video_color(AVIOContext *pb, AVCodecContext *codec, AVStream *st) {
+    int side_data_size = 0;
+    const uint8_t *side_data = av_stream_get_side_data(
+        st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, &side_data_size);
+    ebml_master colorinfo = start_ebml_master(pb, MATROSKA_ID_VIDEOCOLOR, 0);
+
+    if (codec->color_trc != AVCOL_TRC_UNSPECIFIED &&
+        codec->color_trc < AVCOL_TRC_NB) {
+        put_ebml_uint(pb, MATROSKA_ID_VIDEOCOLORTRANSFERCHARACTERISTICS,
+                      codec->color_trc);
+    }
+    if (codec->colorspace != AVCOL_SPC_UNSPECIFIED &&
+        codec->colorspace < AVCOL_SPC_NB) {
+        put_ebml_uint(pb, MATROSKA_ID_VIDEOCOLORMATRIXCOEFF, codec->colorspace);
+    }
+    if (codec->color_primaries != AVCOL_PRI_UNSPECIFIED &&
+        codec->color_primaries < AVCOL_PRI_NB) {
+        put_ebml_uint(pb, MATROSKA_ID_VIDEOCOLORPRIMARIES, codec->color_primaries);
+    }
+    if (codec->color_range != AVCOL_RANGE_UNSPECIFIED &&
+        codec->color_range < AVCOL_RANGE_NB) {
+        put_ebml_uint(pb, MATROSKA_ID_VIDEOCOLORRANGE, codec->color_range);
+    }
+    if (side_data_size == sizeof(AVMasteringDisplayMetadata)) {
+        ebml_master meta_element = start_ebml_master(
+            pb, MATROSKA_ID_VIDEOCOLORMASTERINGMETA, 0);
+        const AVMasteringDisplayMetadata *metadata =
+            (const AVMasteringDisplayMetadata*)side_data;
+        if (metadata->has_primaries) {
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_RX,
+                           av_q2d(metadata->display_primaries[0][0]));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_RY,
+                           av_q2d(metadata->display_primaries[0][1]));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_GX,
+                           av_q2d(metadata->display_primaries[1][0]));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_GY,
+                           av_q2d(metadata->display_primaries[1][1]));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_BX,
+                           av_q2d(metadata->display_primaries[2][0]));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_BY,
+                           av_q2d(metadata->display_primaries[2][1]));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_WHITEX,
+                           av_q2d(metadata->white_point[0]));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_WHITEY,
+                           av_q2d(metadata->white_point[1]));
+        }
+        if (metadata->has_luminance) {
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_LUMINANCEMAX,
+                           av_q2d(metadata->max_luminance));
+            put_ebml_float(pb, MATROSKA_ID_VIDEOCOLOR_LUMINANCEMIN,
+                           av_q2d(metadata->min_luminance));
+        }
+        end_ebml_master(pb, meta_element);
+    }
+    end_ebml_master(pb, colorinfo);
+    return 0;
+}
+
 
 static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb,
                                  AVStream *st, int mode, int *h_width, int *h_height)
@@ -850,8 +909,12 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
         return 0;
     }
 
-    if (!bit_depth && codec->codec_id != AV_CODEC_ID_ADPCM_G726)
-        bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3;
+    if (!bit_depth && codec->codec_id != AV_CODEC_ID_ADPCM_G726) {
+        if (codec->bits_per_raw_sample)
+            bit_depth = codec->bits_per_raw_sample;
+        else
+            bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3;
+    }
     if (!bit_depth)
         bit_depth = codec->bits_per_coded_sample;
 
@@ -1015,7 +1078,9 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv,
             uint32_t color_space = av_le2ne32(codec->codec_tag);
             put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space));
         }
-
+        if (s->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) {
+            mkv_write_video_color(pb, codec, st);
+        }
         end_ebml_master(pb, subinfo);
         break;
 
@@ -2118,9 +2183,12 @@ static int mkv_check_bitstream(struct AVFormatContext *s, const AVPacket *pkt)
     int ret = 1;
     AVStream *st = s->streams[pkt->stream_index];
 
-    if (st->codec->codec_id == AV_CODEC_ID_AAC)
+    if (st->codec->codec_id == AV_CODEC_ID_AAC) {
         if (pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0)
             ret = ff_stream_add_bitstream_filter(st, "aac_adtstoasc", NULL);
+    } else if (st->codec->codec_id == AV_CODEC_ID_VP9) {
+        ret = ff_stream_add_bitstream_filter(st, "vp9_superframe", NULL);
+    }
 
     return ret;
 }