From patchwork Wed Sep 9 14:56:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Harry Mallon X-Patchwork-Id: 22231 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 789F044A031 for ; Wed, 9 Sep 2020 18:03:19 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 4C85968B8BD; Wed, 9 Sep 2020 18:03:19 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f65.google.com (mail-wr1-f65.google.com [209.85.221.65]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id E978168B7CB for ; Wed, 9 Sep 2020 18:03:12 +0300 (EEST) Received: by mail-wr1-f65.google.com with SMTP id m6so3363904wrn.0 for ; Wed, 09 Sep 2020 08:03:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codex.online; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=+2SIYZVKZbvPSqdh8vb3d5eZR3m5+WY0jqF5rvluFwU=; b=G7EgcI+47Iidxn2hTtGqiDUQH4cGZ93mjPMC0RJTNGik92pl/HwPjBQf5dhyD5dBN3 uai/asVUdXBd51RF36bsgWqUAiyWrN82ARnyDOb2YRcvQ3o7fZGhuGFx2L+3qIP45QSj 0AB8nEhwafMrxzOMMUq8/xJHDOYrsmaHV2q3Y= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+2SIYZVKZbvPSqdh8vb3d5eZR3m5+WY0jqF5rvluFwU=; b=sBDkWg3gE/mzvzEWOPbBzXpXtDsw2Fj4Uz3pio2jU2Bo8JV0yoT8BBKCmA6Fnv6cWJ wRXRzDLnNsk9ov4fQ/yd3wENi7fuxnCdXlSU2db+vGbznxWKOCKNMwTIl48Bae2QEB9X iUhTuBwUmyOZKnq08QXWWvYgxwaXVg4WX8vJ/2R6LQvgR/heKfua8CDDiru9iVLMony6 weute90xuRUEl6wKgkIXMFOj+qLt20EFpmvAN3nI0EB62R2JQ5T5mtiqp07qxkA7K+OP b39/5p/e+rbyNIXujZUtzjyq2p7nYKOaDtDHlYE30C3+5T1g3n4z1KXrJZ7HWft+Kt+O LpZw== X-Gm-Message-State: AOAM532k3e+doW4gc4D/1pKhQHxoMVuHImR4IcxWb05vyXjv0uuDHUs3 d/H9FtVJgZhpYIkduSwyfNgb+Qi9FgG3oykP X-Google-Smtp-Source: ABdhPJwk47e73M9a22v1TKUIy/qRSkrb+TlMzygyaNykD6AVaTIVDtIQajjwXfmzaO3wrzKCSMeZbA== X-Received: by 2002:adf:f101:: with SMTP id r1mr4273733wro.314.1599663402633; Wed, 09 Sep 2020 07:56:42 -0700 (PDT) Received: from localhost ([2a01:4b00:8571:3800:9b7:7612:40c6:2653]) by smtp.gmail.com with ESMTPSA id 8sm5046786wrl.7.2020.09.09.07.56.41 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 09 Sep 2020 07:56:41 -0700 (PDT) From: Harry Mallon To: ffmpeg-devel@ffmpeg.org Date: Wed, 9 Sep 2020 15:56:37 +0100 Message-Id: <20200909145639.14922-1-harry.mallon@codex.online> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200831190756.80515-1-harry.mallon@codex.online> References: <20200831190756.80515-1-harry.mallon@codex.online> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/3] avformat/mxfdec: Read Mastering Display Colour Volume from MXF X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Described in Annex B SMPTE ST 2067-21:2020 Signed-off-by: Harry Mallon --- libavformat/mxf.c | 11 ++++++++++ libavformat/mxf.h | 11 ++++++++++ libavformat/mxfdec.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ libavformat/mxfenc.c | 5 ----- 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/libavformat/mxf.c b/libavformat/mxf.c index e51fc48a84..88f69ebcfb 100644 --- a/libavformat/mxf.c +++ b/libavformat/mxf.c @@ -22,6 +22,17 @@ #include "libavutil/common.h" #include "mxf.h" +const uint8_t ff_mxf_mastering_display_prefix[13] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01 }; + +/* be careful to update references to this array if reordering */ +/* local tags are dynamic and must not clash with others in mxfenc.c */ +const MXFLocalTagPair ff_mxf_mastering_display_local_tags[4] = { + { 0x8301, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x01,0x00,0x00 }}, /* Mastering Display Primaries */ + { 0x8302, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x02,0x00,0x00 }}, /* Mastering Display White Point Chromaticity */ + { 0x8303, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x03,0x00,0x00 }}, /* Mastering Display Maximum Luminance */ + { 0x8304, { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x20,0x04,0x01,0x01,0x04,0x00,0x00 }} /* Mastering Display Minimum Luminance */ +}; + /** * SMPTE RP224 http://www.smpte-ra.org/mdd/index.html */ diff --git a/libavformat/mxf.h b/libavformat/mxf.h index fc587f19f0..7fa10bcca1 100644 --- a/libavformat/mxf.h +++ b/libavformat/mxf.h @@ -78,6 +78,17 @@ typedef enum { RawVWrap } MXFWrappingIndicatorType; +typedef struct MXFLocalTagPair { + int local_tag; + UID uid; +} MXFLocalTagPair; + +extern const uint8_t ff_mxf_mastering_display_prefix[13]; +extern const MXFLocalTagPair ff_mxf_mastering_display_local_tags[4]; + +#define FF_MXF_MASTERING_CHROMA_DEN 50000 +#define FF_MXF_MASTERING_LUMA_DEN 10000 + typedef struct MXFCodecUL { UID uid; unsigned matching_len; diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 6f6e8d586c..8d315620bc 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -28,6 +28,7 @@ * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container + * SMPTE 2067-21 Interoperable Master Format — Application #2E * * Principle * Search for Track numbers which will identify essence element KLV packets. @@ -47,6 +48,7 @@ #include "libavutil/aes.h" #include "libavutil/avassert.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/mathematics.h" #include "libavcodec/bytestream.h" #include "libavutil/intreadwrite.h" @@ -213,6 +215,7 @@ typedef struct MXFDescriptor { UID color_primaries_ul; UID color_trc_ul; UID color_space_ul; + AVMasteringDisplayMetadata *mastering; } MXFDescriptor; typedef struct MXFIndexTableSegment { @@ -337,6 +340,7 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) switch ((*ctx)->type) { case Descriptor: av_freep(&((MXFDescriptor *)*ctx)->extradata); + av_freep(&((MXFDescriptor *)*ctx)->mastering); break; case MultipleDescriptor: av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); @@ -1272,6 +1276,42 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int rsiz == FF_PROFILE_JPEG2000_DCINEMA_4K) descriptor->pix_fmt = AV_PIX_FMT_XYZ12; } + if (IS_KLV_KEY(uid, ff_mxf_mastering_display_prefix)) { + if (!descriptor->mastering) { + descriptor->mastering = av_mastering_display_metadata_alloc(); + if (!descriptor->mastering) + return AVERROR(ENOMEM); + } + if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[0].uid)) { + for (int i = 0; i < 3; i++) { + /* Order: large x, large y, other (i.e. RGB) */ + descriptor->mastering->display_primaries[i][0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + descriptor->mastering->display_primaries[i][1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + } + /* Check we have seen mxf_mastering_display_white_point_chromaticity */ + if (descriptor->mastering->white_point[0].den != 0) + descriptor->mastering->has_primaries = 1; + } + if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[1].uid)) { + descriptor->mastering->white_point[0] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + descriptor->mastering->white_point[1] = av_make_q(avio_rb16(pb), FF_MXF_MASTERING_CHROMA_DEN); + /* Check we have seen mxf_mastering_display_primaries */ + if (descriptor->mastering->display_primaries[0][0].den != 0) + descriptor->mastering->has_primaries = 1; + } + if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[2].uid)) { + descriptor->mastering->max_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN); + /* Check we have seen mxf_mastering_display_minimum_luminance */ + if (descriptor->mastering->min_luminance.den != 0) + descriptor->mastering->has_luminance = 1; + } + if (IS_KLV_KEY(uid, ff_mxf_mastering_display_local_tags[3].uid)) { + descriptor->mastering->min_luminance = av_make_q(avio_rb32(pb), FF_MXF_MASTERING_LUMA_DEN); + /* Check we have seen mxf_mastering_display_maximum_luminance */ + if (descriptor->mastering->max_luminance.den != 0) + descriptor->mastering->has_luminance = 1; + } + } break; } return 0; @@ -2532,6 +2572,14 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codecpar->color_primaries = mxf_get_codec_ul(ff_mxf_color_primaries_uls, &descriptor->color_primaries_ul)->id; st->codecpar->color_trc = mxf_get_codec_ul(ff_mxf_color_trc_uls, &descriptor->color_trc_ul)->id; st->codecpar->color_space = mxf_get_codec_ul(ff_mxf_color_space_uls, &descriptor->color_space_ul)->id; + if (descriptor->mastering) { + ret = av_stream_add_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, + (uint8_t *)descriptor->mastering, + sizeof(*descriptor->mastering)); + if (ret < 0) + goto fail_and_free; + descriptor->mastering = NULL; + } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul); /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */ diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index e495b5ba0e..733c747a9a 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -65,11 +65,6 @@ extern AVOutputFormat ff_mxf_opatom_muxer; #define EDIT_UNITS_PER_BODY 250 #define KAG_SIZE 512 -typedef struct MXFLocalTagPair { - int local_tag; - UID uid; -} MXFLocalTagPair; - typedef struct MXFIndexEntry { uint64_t offset; unsigned slice_offset; ///< offset of audio slice From patchwork Wed Sep 9 14:56:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Mallon X-Patchwork-Id: 22233 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id C250244A89F for ; Wed, 9 Sep 2020 19:05:26 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 9F63A68B8E5; Wed, 9 Sep 2020 19:05:26 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f182.google.com (mail-lj1-f182.google.com [209.85.208.182]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id DC68568B8C1 for ; Wed, 9 Sep 2020 19:05:19 +0300 (EEST) Received: by mail-lj1-f182.google.com with SMTP id b19so4229253lji.11 for ; Wed, 09 Sep 2020 09:05:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codex.online; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=iOKQ9y7iYbmRH0hXpzWnnRNxNomA2WEIjK6DY0GM5is=; b=CxtIeM6kcl+KCOx1LkfpdKGtgi8wGMomltJ5qEyP7Qa2NNxKaI4sm1Ec3UiX+YHy30 1h9EiLxSND7QtWKN4/OEmZooqM7SgpcyclrPaseEp5a80IBq5rAKbq527jvZDP6f6qlL ZVThlZ2gMDSvLbGbuJ6ProzUvFhKbGI0GfOEM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iOKQ9y7iYbmRH0hXpzWnnRNxNomA2WEIjK6DY0GM5is=; b=BXMXJVWNotJX8YzX1pKzIMe1LcUV6mY9xpgxNGCHCVdvI3oqendFkBOmE+/3GmUq3V YUGtlbSBO/jpuyZBjClF6JpEb9+oexAjG8jwaOMP21ER4qEk7KrXQodEy7/MjF8MYrie y4zCX3+6KpvAeg+g07HDEn4b4XJq7RooxsLupaPtJ2HJOrA4JGa900Xdtiyk9cU9yG1k njBcGDKtCkYg7/Yngwt3NELvBlU5q+E7T9J0EtQzJ9piD1b/cSo8kI1/6FKiEusc8zH+ aCrSNGmtZKcWMbtANHETX4fdehexxZfB7L21XzUqfG48aKgZTJm+OhY94Ni16zOHCiU5 w0gQ== X-Gm-Message-State: AOAM533SAPlLPT2f/KWjoChEJpLo+FjJRjknEMUPtQSnM5s8YgRJwpeg TeC9PZe5a3QiDwDPuGfSAZXDu60uYUCTcBNj X-Google-Smtp-Source: ABdhPJxMwZeKgBXfOdvmfzbtQvaAY0KuDYQzRhBcxvXd5RXGjaKncJSNm2X+5TRZSNuQNL0KXTz2Cw== X-Received: by 2002:a5d:458e:: with SMTP id p14mr4340166wrq.61.1599663403766; Wed, 09 Sep 2020 07:56:43 -0700 (PDT) Received: from localhost ([2a01:4b00:8571:3800:9b7:7612:40c6:2653]) by smtp.gmail.com with ESMTPSA id k22sm4613898wrd.29.2020.09.09.07.56.43 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 09 Sep 2020 07:56:43 -0700 (PDT) From: Harry Mallon To: ffmpeg-devel@ffmpeg.org Date: Wed, 9 Sep 2020 15:56:38 +0100 Message-Id: <20200909145639.14922-2-harry.mallon@codex.online> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200909145639.14922-1-harry.mallon@codex.online> References: <20200831190756.80515-1-harry.mallon@codex.online> <20200909145639.14922-1-harry.mallon@codex.online> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 2/3] avformat/mxfenc: Write Mastering Display Colour Volume to MXF X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Described in Annex B SMPTE ST 2067-21:2020 Signed-off-by: Harry Mallon --- libavformat/mxfenc.c | 50 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index 733c747a9a..cbb0fc5a6a 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -44,6 +44,7 @@ #include "libavutil/random_seed.h" #include "libavutil/timecode.h" #include "libavutil/avassert.h" +#include "libavutil/mastering_display_metadata.h" #include "libavutil/pixdesc.h" #include "libavutil/time_internal.h" #include "libavcodec/bytestream.h" @@ -505,6 +506,7 @@ static void mxf_write_primer_pack(AVFormatContext *s) AVIOContext *pb = s->pb; int local_tag_number, i = 0; int avc_tags_count = 0; + int mastering_tags_count = 0; local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch); local_tag_number += mxf->store_user_comments * FF_ARRAY_ELEMS(mxf_user_comments_local_tag); @@ -513,10 +515,15 @@ static void mxf_write_primer_pack(AVFormatContext *s) MXFStreamContext *sc = s->streams[i]->priv_data; if (s->streams[i]->codecpar->codec_id == AV_CODEC_ID_H264 && !sc->avc_intra) { avc_tags_count = FF_ARRAY_ELEMS(mxf_avc_subdescriptor_local_tags); - local_tag_number += avc_tags_count; + } + if (av_stream_get_side_data(s->streams[i], AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL)) { + mastering_tags_count = FF_ARRAY_ELEMS(ff_mxf_mastering_display_local_tags); } } + local_tag_number += avc_tags_count; + local_tag_number += mastering_tags_count; + avio_write(pb, primer_pack_key, 16); klv_encode_ber_length(pb, local_tag_number * 18 + 8); @@ -534,6 +541,8 @@ static void mxf_write_primer_pack(AVFormatContext *s) } if (avc_tags_count > 0) mxf_write_local_tags(pb, mxf_avc_subdescriptor_local_tags, avc_tags_count); + if (mastering_tags_count > 0) + mxf_write_local_tags(pb, ff_mxf_mastering_display_local_tags, mastering_tags_count); } static void mxf_write_local_tag(AVIOContext *pb, int size, int tag) @@ -1043,6 +1052,16 @@ static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0 static const UID mxf_avc_subdescriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6E,0x00 }; +static inline uint16_t rescale_mastering_chroma(AVRational q) +{ + return av_clip_uint16(av_rescale(q.num, FF_MXF_MASTERING_CHROMA_DEN, q.den)); +} + +static inline uint32_t rescale_mastering_luma(AVRational q) +{ + return av_rescale(q.num, FF_MXF_MASTERING_LUMA_DEN, q.den); +} + static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key) { MXFStreamContext *sc = st->priv_data; @@ -1055,6 +1074,7 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID const MXFCodecUL *color_trc_ul; const MXFCodecUL *color_space_ul; int64_t pos = mxf_write_generic_desc(s, st, key); + uint8_t *side_data; color_primaries_ul = mxf_get_codec_ul_by_id(ff_mxf_color_primaries_uls, st->codecpar->color_primaries); color_trc_ul = mxf_get_codec_ul_by_id(ff_mxf_color_trc_uls, st->codecpar->color_trc); @@ -1223,6 +1243,34 @@ static int64_t mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID mxf_write_local_tag(pb, 16, 0x3201); avio_write(pb, *sc->codec_ul, 16); + // Mastering Display metadata + side_data = av_stream_get_side_data(st, AV_PKT_DATA_MASTERING_DISPLAY_METADATA, NULL); + if (side_data) { + const AVMasteringDisplayMetadata *metadata = (const AVMasteringDisplayMetadata*)side_data; + if (metadata->has_primaries) { + mxf_write_local_tag(pb, 12, ff_mxf_mastering_display_local_tags[0].local_tag); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[0][0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[0][1])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[1][0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[1][1])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[2][0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->display_primaries[2][1])); + mxf_write_local_tag(pb, 4, ff_mxf_mastering_display_local_tags[1].local_tag); + avio_wb16(pb, rescale_mastering_chroma(metadata->white_point[0])); + avio_wb16(pb, rescale_mastering_chroma(metadata->white_point[1])); + } else { + av_log(NULL, AV_LOG_VERBOSE, "Not writing mastering display primaries. Missing data.\n"); + } + if (metadata->has_luminance) { + mxf_write_local_tag(pb, 4, ff_mxf_mastering_display_local_tags[2].local_tag); + avio_wb32(pb, rescale_mastering_luma(metadata->max_luminance)); + mxf_write_local_tag(pb, 4, ff_mxf_mastering_display_local_tags[3].local_tag); + avio_wb32(pb, rescale_mastering_luma(metadata->min_luminance)); + } else { + av_log(NULL, AV_LOG_VERBOSE, "Not writing mastering display luminances. Missing data.\n"); + } + } + if (sc->interlaced && sc->field_dominance) { mxf_write_local_tag(pb, 1, 0x3212); avio_w8(pb, sc->field_dominance); From patchwork Wed Sep 9 14:56:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harry Mallon X-Patchwork-Id: 22232 Return-Path: X-Original-To: patchwork@ffaux-bg.ffmpeg.org Delivered-To: patchwork@ffaux-bg.ffmpeg.org Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by ffaux.localdomain (Postfix) with ESMTP id 8537D44A98D for ; Wed, 9 Sep 2020 18:05:02 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6679768B8D4; Wed, 9 Sep 2020 18:05:02 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 8A69168B84B for ; Wed, 9 Sep 2020 18:04:56 +0300 (EEST) Received: by mail-wr1-f44.google.com with SMTP id z4so3361524wrr.4 for ; Wed, 09 Sep 2020 08:04:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=codex.online; s=google; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=w6spgYWbcEwJXUYrhaJpHOsAggjPtcU/KuwtEUri+Bs=; b=Hl3yjZ9iblrKDU92inktkuH1zsVhn3MwpnBwtTzSIPlJOTJbaZPTBF3aiO0APGY0J7 p1VCTOPjXdyw7m4qcmkHiU1nXbIR6QxJsvCTiiqpSpeRHkNetWIXKh2NJbZrvuuwNFY5 jN38e9NyRgPDhQL1HaeglkVUZDqBNastdHu8E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=w6spgYWbcEwJXUYrhaJpHOsAggjPtcU/KuwtEUri+Bs=; b=m8lGzA7/AYZs1uqluPLEr7avXjDDvEcMbvuF6Bnmsfc4DdsAYw7aiEBmYFOzbU55qZ r6ZfpckqH1ZTcKNwmHDzmaKCPF7A7UeSBxOvo5ytMrLavKNOBhbsRd89nRFG4WaHPj5q qRn4OTKORpxSC2cQYeiXAst5NCIel+xgaBEwlQH4wQ5IOV1DPpzpwo/F+vtd5XVh+yhK pSri/KaWSmjGh8YhWZAjDWmJrMmtV78ITwrsHRws+IFcfd/lTZfT5O3xkDO7FKGeNAbI Zz4mkKgYwZACZdVfiZEcg/vWWuhT8G0SBBJHwvH3x67OdlaWQ/AvYc63XKP5Wc1vwRJ0 hy0Q== X-Gm-Message-State: AOAM530NCvM68l1dlvPvYdElaftWAWmgAl+TxfLVbd5m1ZKdtyxhg0rk xNd0gl8f8Y4SQH7pLyJKj4qAjIP2oDbuJpcU X-Google-Smtp-Source: ABdhPJwvmto1Jc/rQb4LCdWduPu/r4WPFgcmLodf9Im6fICRkGUKJ0Qm/hc0+izKuODEtbLKQ1LGUQ== X-Received: by 2002:adf:fa52:: with SMTP id y18mr4470549wrr.264.1599663404885; Wed, 09 Sep 2020 07:56:44 -0700 (PDT) Received: from localhost ([2a01:4b00:8571:3800:9b7:7612:40c6:2653]) by smtp.gmail.com with ESMTPSA id z83sm4324228wmb.4.2020.09.09.07.56.44 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 09 Sep 2020 07:56:44 -0700 (PDT) From: Harry Mallon To: ffmpeg-devel@ffmpeg.org Date: Wed, 9 Sep 2020 15:56:39 +0100 Message-Id: <20200909145639.14922-3-harry.mallon@codex.online> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200909145639.14922-1-harry.mallon@codex.online> References: <20200831190756.80515-1-harry.mallon@codex.online> <20200909145639.14922-1-harry.mallon@codex.online> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 3/3] avformat/mxfdec: Read Apple private Content Light Level from MXF X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" * As embedded by Apple Compressor Signed-off-by: Harry Mallon --- libavformat/mxfdec.c | 27 +++++ tests/fate/mxf.mak | 4 + tests/ref/fate/mxf-probe-applehdr10 | 169 ++++++++++++++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 tests/ref/fate/mxf-probe-applehdr10 diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 8d315620bc..d16a7af0df 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -216,6 +216,8 @@ typedef struct MXFDescriptor { UID color_trc_ul; UID color_space_ul; AVMasteringDisplayMetadata *mastering; + AVContentLightMetadata *coll; + size_t coll_size; } MXFDescriptor; typedef struct MXFIndexTableSegment { @@ -321,6 +323,7 @@ static const uint8_t mxf_canopus_essence_element_key[] = { 0x06,0x0e,0x2b,0x static const uint8_t mxf_system_item_key_cp[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x03,0x01,0x04 }; static const uint8_t mxf_system_item_key_gc[] = { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x03,0x01,0x14 }; static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; +static const uint8_t mxf_apple_coll_prefix[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01 }; /* complete keys to match */ static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 }; static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; @@ -331,6 +334,8 @@ static const uint8_t mxf_avid_project_name[] = { 0xa5,0xfb,0x7b,0x static const uint8_t mxf_jp2k_rsiz[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; static const uint8_t mxf_indirect_value_utf16le[] = { 0x4c,0x00,0x02,0x10,0x01,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 }; static const uint8_t mxf_indirect_value_utf16be[] = { 0x42,0x01,0x10,0x02,0x00,0x00,0x00,0x00,0x00,0x06,0x0e,0x2b,0x34,0x01,0x04,0x01,0x01 }; +static const uint8_t mxf_apple_coll_max_cll[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x01 }; +static const uint8_t mxf_apple_coll_max_fall[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x0e,0x20,0x04,0x01,0x05,0x03,0x01,0x02 }; #define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) @@ -341,6 +346,7 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) case Descriptor: av_freep(&((MXFDescriptor *)*ctx)->extradata); av_freep(&((MXFDescriptor *)*ctx)->mastering); + av_freep(&((MXFDescriptor *)*ctx)->coll); break; case MultipleDescriptor: av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); @@ -1312,6 +1318,19 @@ static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int descriptor->mastering->has_luminance = 1; } } + if (IS_KLV_KEY(uid, mxf_apple_coll_prefix)) { + if (!descriptor->coll) { + descriptor->coll = av_content_light_metadata_alloc(&descriptor->coll_size); + if (!descriptor->coll) + return AVERROR(ENOMEM); + } + if (IS_KLV_KEY(uid, mxf_apple_coll_max_cll)) { + descriptor->coll->MaxCLL = avio_rb16(pb); + } + if (IS_KLV_KEY(uid, mxf_apple_coll_max_fall)) { + descriptor->coll->MaxFALL = avio_rb16(pb); + } + } break; } return 0; @@ -2580,6 +2599,14 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) goto fail_and_free; descriptor->mastering = NULL; } + if (descriptor->coll) { + ret = av_stream_add_side_data(st, AV_PKT_DATA_CONTENT_LIGHT_LEVEL, + (uint8_t *)descriptor->coll, + descriptor->coll_size); + if (ret < 0) + goto fail_and_free; + descriptor->coll = NULL; + } } else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) { container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul); /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */ diff --git a/tests/fate/mxf.mak b/tests/fate/mxf.mak index 4aafc1f578..3adef939dc 100644 --- a/tests/fate/mxf.mak +++ b/tests/fate/mxf.mak @@ -33,6 +33,10 @@ FATE_MXF_PROBE-$(call ENCDEC2, DVVIDEO, PCM_S16LE, MXF) += fate-mxf-probe-dv25 fate-mxf-probe-dv25: SRC = $(TARGET_SAMPLES)/mxf/Avid-00005.mxf fate-mxf-probe-dv25: CMD = run $(PROBE_FORMAT_STREAMS_COMMAND) -i "$(SRC)" +FATE_MXF_PROBE-$(call ENCDEC2, PRORES, PCM_S24LE, MXF) += fate-mxf-probe-applehdr10 +fate-mxf-probe-applehdr10: SRC = $(TARGET_SAMPLES)/mxf/Meridian-Apple_ProResProxy-HDR10.mxf +fate-mxf-probe-applehdr10: CMD = run $(PROBE_FORMAT_STREAMS_COMMAND) -i "$(SRC)" + FATE_MXF_REEL_NAME-$(call ENCDEC2, MPEG2VIDEO, PCM_S16LE, MXF) += fate-mxf-reel_name fate-mxf-reel_name: $(SAMPLES)/mxf/Sony-00001.mxf fate-mxf-reel_name: CMD = md5 -y -i $(TARGET_SAMPLES)/mxf/Sony-00001.mxf -c copy -timecode 00:00:00:00 -metadata "reel_name=test_reel" -fflags +bitexact -f mxf diff --git a/tests/ref/fate/mxf-probe-applehdr10 b/tests/ref/fate/mxf-probe-applehdr10 new file mode 100644 index 0000000000..3430670c52 --- /dev/null +++ b/tests/ref/fate/mxf-probe-applehdr10 @@ -0,0 +1,169 @@ +[STREAM] +index=0 +codec_name=prores +profile=0 +codec_type=video +codec_time_base=0/1 +codec_tag_string=apco +codec_tag=0x6f637061 +width=1280 +height=720 +coded_width=1280 +coded_height=720 +closed_captions=0 +has_b_frames=0 +sample_aspect_ratio=1:1 +display_aspect_ratio=16:9 +pix_fmt=yuv422p10le +level=-99 +color_range=tv +color_space=bt2020nc +color_transfer=smpte2084 +color_primaries=bt2020 +chroma_location=unspecified +field_order=progressive +timecode=N/A +refs=1 +id=N/A +r_frame_rate=60000/1001 +avg_frame_rate=0/0 +time_base=1001/60000 +start_pts=0 +start_time=0.000000 +duration_ts=5 +duration=0.083417 +bit_rate=N/A +max_bit_rate=N/A +bits_per_raw_sample=10 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[SIDE_DATA] +side_data_type=Mastering display metadata +red_x=34000/50000 +red_y=16000/50000 +green_x=13250/50000 +green_y=34500/50000 +blue_x=7500/50000 +blue_y=3000/50000 +white_point_x=15635/50000 +white_point_y=16450/50000 +min_luminance=0/10000 +max_luminance=10000000/10000 +[/SIDE_DATA] +[SIDE_DATA] +side_data_type=Content light level metadata +max_content=1000 +max_average=100 +[/SIDE_DATA] +[/STREAM] +[STREAM] +index=1 +codec_name=pcm_s24le +profile=unknown +codec_type=audio +codec_time_base=1/48000 +codec_tag_string=[0][0][0][0] +codec_tag=0x0000 +sample_fmt=s32 +sample_rate=48000 +channels=1 +channel_layout=unknown +bits_per_sample=24 +id=N/A +r_frame_rate=0/0 +avg_frame_rate=0/0 +time_base=1/48000 +start_pts=0 +start_time=0.000000 +duration_ts=4004 +duration=0.083417 +bit_rate=1152000 +max_bit_rate=N/A +bits_per_raw_sample=24 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[/STREAM] +[STREAM] +index=2 +codec_name=pcm_s24le +profile=unknown +codec_type=audio +codec_time_base=1/48000 +codec_tag_string=[0][0][0][0] +codec_tag=0x0000 +sample_fmt=s32 +sample_rate=48000 +channels=1 +channel_layout=unknown +bits_per_sample=24 +id=N/A +r_frame_rate=0/0 +avg_frame_rate=0/0 +time_base=1/48000 +start_pts=0 +start_time=0.000000 +duration_ts=4004 +duration=0.083417 +bit_rate=1152000 +max_bit_rate=N/A +bits_per_raw_sample=24 +nb_frames=N/A +nb_read_frames=N/A +nb_read_packets=N/A +DISPOSITION:default=0 +DISPOSITION:dub=0 +DISPOSITION:original=0 +DISPOSITION:comment=0 +DISPOSITION:lyrics=0 +DISPOSITION:karaoke=0 +DISPOSITION:forced=0 +DISPOSITION:hearing_impaired=0 +DISPOSITION:visual_impaired=0 +DISPOSITION:clean_effects=0 +DISPOSITION:attached_pic=0 +DISPOSITION:timed_thumbnails=0 +TAG:file_package_umid=0x060A2B340101010501010D201300000040ECCE167353449C92D6F2693A9F1D75 +[/STREAM] +[FORMAT] +format_name=mxf +duration=0.083417 +bit_rate=30913698 +TAG:operational_pattern_ul=060e2b34.04010101.0d010201.01010900 +TAG:uid=0002475a-49e3-430b-85d9-3b35d180e3b5 +TAG:generation_uid=240f15ec-50ee-4285-83bf-7c17122fac0c +TAG:company_name=Apple Inc. +TAG:product_name=Compressor +TAG:product_version=4.4.7 (4.4.7) +TAG:product_uid=00000000-0000-0000-0000-000000000000 +TAG:modification_date=2020-09-08T16:18:57.036000Z +TAG:material_package_umid=0x060A2B340101010501010D201300000045843C9FE69D4B8FA90DDAAA1602A2E8 +TAG:timecode=00:01:15;26 +[/FORMAT]