Use "master_display" key/value pair to specify mastering metadata in a similar formatting as accepted by libx265 (unless there is some other generic way to add side data to a stream from command line). Currently, the packet side data propagates from an input file to output file if it is transmuxed (mkv -> mkv). Perhaps we want to also use this same metadata key in matroskadec to also allow for the metadata to propagate during transcoding.
From b30d80f6ba4b09811039f64af3e7f709d86df5fe Mon Sep 17 00:00:00 2001 From: Neil Birkbeck <neil.birkb...@gmail.com> Date: Fri, 1 Apr 2016 17:02:42 -0700 Subject: [PATCH] lavf/matroskaenc.c: use metadata key/value to set mastering metadata
Add key/value metadata interface to allow command line setting of AVMasteringDisplayMetadata. The formatting is the same as the option in libx265. Signed-off-by: Neil Birkbeck <neil.birkb...@gmail.com> --- libavformat/matroskaenc.c | 51 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 0546686..30ff714 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -732,10 +732,54 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, } static int mkv_write_video_color(AVIOContext *pb, AVCodecContext *codec, AVStream *st) { + AVDictionaryEntry *tag; int side_data_size = 0; - const uint8_t *side_data = av_stream_get_side_data( + 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); + AVMasteringDisplayMetadata *metadata = + (side_data_size == sizeof(AVMasteringDisplayMetadata)) ? + (AVMasteringDisplayMetadata*)side_data : NULL; + + // If key-value pair metadata is specified, override the packet side data + // Accept a format similar to the command line argument in x265: + // G(x,y)B(x,y)R(x,y)WP(x,y),L(max,min) + if (tag = av_dict_get(st->metadata, "master_display", NULL, 0)) { + int primaries[4][2]; + int luma[2]; + int num_read = sscanf(tag->value, + "G(%d,%d)B(%d,%d)R(%d,%d)WP(%d,%d)L(%d,%d)", + primaries[1], primaries[1] + 1, + primaries[2], primaries[2] + 1, + primaries[0], primaries[0] + 1, + primaries[3], primaries[3] + 1, + luma + 1, luma + 0); + if (num_read >= 8) { + const float chroma_denom = 50000.f; + const float luma_denom = 10000.f; + int i, j; + if (!metadata) { + metadata = (AVMasteringDisplayMetadata*) av_stream_new_side_data( + st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + sizeof(AVMasteringDisplayMetadata)); + memset(metadata, 0, sizeof(AVMasteringDisplayMetadata)); + } + for (i = 0; i < 3; ++i) { + for (j = 0; j < 2; ++j) { + metadata->display_primaries[i][j] = + av_make_q(primaries[i][j], chroma_denom); + } + } + metadata->white_point[0] = av_make_q(primaries[3][0], chroma_denom); + metadata->white_point[1] = av_make_q(primaries[3][1], chroma_denom); + metadata->has_primaries = 1; + if (num_read == 10) { + metadata->min_luminance = av_make_q(luma[0], luma_denom); + metadata->max_luminance = av_make_q(luma[1], luma_denom); + metadata->has_luminance = 1; + } + } + } if (codec->color_trc != AVCOL_TRC_UNSPECIFIED && codec->color_trc < AVCOL_TRC_NB) { @@ -754,11 +798,9 @@ static int mkv_write_video_color(AVIOContext *pb, AVCodecContext *codec, AVStrea codec->color_range < AVCOL_RANGE_NB) { put_ebml_uint(pb, MATROSKA_ID_VIDEOCOLORRANGE, codec->color_range); } - if (side_data_size == sizeof(AVMasteringDisplayMetadata)) { + if (metadata) { 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])); @@ -1278,6 +1320,7 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme av_strcasecmp(t->key, "stereo_mode") && av_strcasecmp(t->key, "creation_time") && av_strcasecmp(t->key, "encoding_tool") && + av_strcasecmp(t->key, "master_display") && (elementid != MATROSKA_ID_TAGTARGETS_TRACKUID || av_strcasecmp(t->key, "language"))) { ret = mkv_write_simpletag(s->pb, t); -- 2.8.0.rc3.226.g39d4020
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel