From patchwork Sat Jul 30 16:42:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Niedermayer X-Patchwork-Id: 37043 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a21:1649:b0:8b:613a:194d with SMTP id no9csp1551243pzb; Sat, 30 Jul 2022 09:42:22 -0700 (PDT) X-Google-Smtp-Source: AA6agR5uSACqCMcyuPNi+9qHxXJ6OxVQTaS1TjmN7ZsCDgRRwLwU7blZony0QUN8IHNIgIkTDdCd X-Received: by 2002:a50:cd1c:0:b0:43d:4821:88a8 with SMTP id z28-20020a50cd1c000000b0043d482188a8mr3624616edi.396.1659199342552; Sat, 30 Jul 2022 09:42:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1659199342; cv=none; d=google.com; s=arc-20160816; b=oOwTvuqxh9OrnD51YKd6jw6H6BUqaTW/lND4Fu8guUoup1dOQ/go43RXMILtCe1F7k nZzf4weBnzjVcocbTQSp897anpH8WZ8uTTB8CAxAoh6HRHyrFM19Ii4QVQumiWrPm74b cv6Z+XNNes0iMcEkT4o2HhR11xMB9VxoVaUoGuTOMBXs59ySWCdkM+M59VmliXNo/Fyw sQaxYog1Pzoi7/kO7AskW3Uz8a+7hd6C8Tb8NmUdr0j1owzXmcez+1j4Kn2yX+YXvIYV Ed8eowBOPrKAXjklzFQcgywzgxvzdVL+3NMlcHdTUScE3WcL32eHFHUckUDkPTzYREbO Q+Lw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:message-id:date:to:from:delivered-to; bh=UKgcD9TfheQwgdaNQyuCL9BsC0S9rpsMNSNg/w3sJfE=; b=gIqW2mmzA63fBYE2bePzy2IXsbBCxbk2OzFh6s2EUvaev5csSeg8Ss8G3SQ+bYck6z celGmtDqCQ1Q0j9dxuCrBY9WlTdyQjO+ViSpLvwSFQnpKAqtyOphKrqArfxNPuGmrYx0 ZkamN+4ZZSDL5elnvbbGe7+vMn4KDtiIOKaVW5G0ufaLVJ6L8rIqMOtP57C0bWvS0xzt SRWBMxZPnSFGFTHmJZwbdoz+o4jeidOm4jIX0iCyRpKEJ7bRH+n4LiPWIpnPblNRhhR9 +N03S53a2ru8kYbBMaWe0hvEa9WU9ExEAc6AWtpkdfHXCcnxBlVyxPqPZKRzDdWW6b9t eV+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id us6-20020a170906bfc600b00711dc674239si1757551ejb.726.2022.07.30.09.42.21; Sat, 30 Jul 2022 09:42:22 -0700 (PDT) Received-SPF: pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) client-ip=79.124.17.100; Authentication-Results: mx.google.com; spf=pass (google.com: domain of ffmpeg-devel-bounces@ffmpeg.org designates 79.124.17.100 as permitted sender) smtp.mailfrom=ffmpeg-devel-bounces@ffmpeg.org Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 2FD5668BA4F; Sat, 30 Jul 2022 19:42:18 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from vie01a-dmta-at03-2.mx.upcmail.net (vie01a-dmta-at03-2.mx.upcmail.net [62.179.121.152]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 648C468B95F for ; Sat, 30 Jul 2022 19:42:11 +0300 (EEST) Received: from [172.31.216.235] (helo=vie01a-pemc-psmtp-pe12.mail.upcmail.net) by vie01a-dmta-at03.mx.upcmail.net with esmtp (Exim 4.92) (envelope-from ) id 1oHpXW-009IYG-3u for ffmpeg-devel@ffmpeg.org; Sat, 30 Jul 2022 18:42:10 +0200 Received: from ren-mail-psmtp-mg02. ([80.109.253.241]) by vie01a-pemc-psmtp-pe12.mail.upcmail.net with ESMTP id HpVToV6IJ8s8UHpXVoXM3F; Sat, 30 Jul 2022 18:42:09 +0200 Received: from localhost ([213.47.68.29]) by ren-mail-psmtp-mg02. with ESMTP id HpXUo2UKK8eSWHpXUoPDNa; Sat, 30 Jul 2022 18:42:09 +0200 X-Env-Mailfrom: michael@niedermayer.cc X-Env-Rcptto: ffmpeg-devel@ffmpeg.org X-SourceIP: 213.47.68.29 X-CNFS-Analysis: v=2.4 cv=KKE5sHJo c=1 sm=1 tr=0 ts=62e55f61 a=2hcxjKEKjp0CzLx6oWAm4g==:117 a=2hcxjKEKjp0CzLx6oWAm4g==:17 a=MKtGQD3n3ToA:10 a=1oJP67jkp3AA:10 a=GEAsPZ9sns4A:10 a=gLMPntu71_fRXHl87QEA:9 From: Michael Niedermayer To: FFmpeg development discussions and patches Date: Sat, 30 Jul 2022 18:42:08 +0200 Message-Id: <20220730164208.5522-1-michael@niedermayer.cc> X-Mailer: git-send-email 2.17.1 X-CMAE-Envelope: MS4wfDtm2ra60qnrxnqaNqn2UuvxPE5rdTudidxR/mFEOBUeHLLphrXr8VsW/SdkLK70Gxv+lQJI0Nn1+pCvr1M+gQZFLQxCWslTod0yF9MkKNXZ/1zHA4iY GLSlHI3JKkFkeRabNBlZhxDxdLZcykPZ9HiURW6SylxCEjhgk1BR1fNWtsCbByei/8lHeYF2rPK6YQ== Subject: [FFmpeg-devel] [PATCH v2] avformat/mxfdec: SMPTE RDD 48:2018 Amd 1:2022 support X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 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 MIME-Version: 1.0 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: JfUwu1uY1pQS Signed-off-by: Michael Niedermayer --- libavformat/mxf.c | 3 +++ libavformat/mxf.h | 1 + libavformat/mxfdec.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/libavformat/mxf.c b/libavformat/mxf.c index 36d662b58c..8ef928b8fc 100644 --- a/libavformat/mxf.c +++ b/libavformat/mxf.c @@ -66,6 +66,9 @@ const MXFCodecUL ff_mxf_codec_uls[] = { { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x01 }, 16, AV_CODEC_ID_V210 }, /* V210 */ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0E,0x04,0x02,0x01,0x02,0x11,0x00,0x00 }, 14, AV_CODEC_ID_PRORES }, /* Avid MC7 ProRes */ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x03,0x06,0x00,0x00 }, 14, AV_CODEC_ID_PRORES }, /* Apple ProRes */ + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x03,0x09,0x01,0x00 }, 15, AV_CODEC_ID_FFV1 }, /*FFV1 V0 */ + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x03,0x09,0x02,0x00 }, 15, AV_CODEC_ID_FFV1 }, /*FFV1 V1 */ + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0D,0x04,0x01,0x02,0x02,0x03,0x09,0x04,0x00 }, 15, AV_CODEC_ID_FFV1 }, /*FFV1 V3 */ /* SoundEssenceCompression */ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x03,0x04,0x02,0x02,0x02,0x03,0x03,0x01,0x00 }, 14, AV_CODEC_ID_AAC }, /* MPEG-2 AAC ADTS (legacy) */ { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, AV_CODEC_ID_PCM_S16LE }, /* uncompressed */ diff --git a/libavformat/mxf.h b/libavformat/mxf.h index 4d9f5119a3..2561605ce5 100644 --- a/libavformat/mxf.h +++ b/libavformat/mxf.h @@ -54,6 +54,7 @@ enum MXFMetadataSetType { AudioChannelLabelSubDescriptor, SoundfieldGroupLabelSubDescriptor, GroupOfSoundfieldGroupsLabelSubDescriptor, + FFV1SubDescriptor, }; enum MXFFrameLayout { diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 400941c348..feebff67aa 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -237,6 +237,12 @@ typedef struct MXFMCASubDescriptor { char *language; } MXFMCASubDescriptor; +typedef struct MXFFFV1SubDescriptor { + MXFMetadataSet meta; + uint8_t *extradata; + int extradata_size; +} MXFFFV1SubDescriptor; + typedef struct MXFIndexTableSegment { MXFMetadataSet meta; int edit_unit_byte_count; @@ -337,6 +343,7 @@ static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 }; +static const uint8_t mxf_ffv1_extradata[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0e,0x04,0x01,0x06,0x0c,0x01,0x00,0x00,0x00 }; // FFV1InitializationMetadata static const uint8_t mxf_avid_project_name[] = { 0xa5,0xfb,0x7b,0x25,0xf6,0x15,0x94,0xb9,0x62,0xfc,0x37,0x17,0x49,0x2d,0x42,0xbf }; static const uint8_t mxf_jp2k_rsiz[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x0a,0x04,0x01,0x06,0x03,0x01,0x00,0x00,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 }; @@ -377,6 +384,9 @@ static void mxf_free_metadataset(MXFMetadataSet **ctx, int freectx) av_freep(&((MXFDescriptor *)*ctx)->file_descriptors_refs); av_freep(&((MXFDescriptor *)*ctx)->sub_descriptors_refs); break; + case FFV1SubDescriptor: + av_freep(&((MXFFFV1SubDescriptor *)*ctx)->extradata); + break; case AudioChannelLabelSubDescriptor: case SoundfieldGroupLabelSubDescriptor: case GroupOfSoundfieldGroupsLabelSubDescriptor: @@ -1473,6 +1483,25 @@ static int mxf_read_mca_sub_descriptor(void *arg, AVIOContext *pb, int tag, int return 0; } +static int mxf_read_ffv1_sub_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) +{ + MXFFFV1SubDescriptor *ffv1_sub_descriptor = arg; + + if (IS_KLV_KEY(uid, mxf_ffv1_extradata) && size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE ) { + if (ffv1_sub_descriptor->extradata) + av_log(NULL, AV_LOG_WARNING, "Duplicate ffv1_extradata\n"); + av_free(ffv1_sub_descriptor->extradata); + ffv1_sub_descriptor->extradata_size = 0; + ffv1_sub_descriptor->extradata = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!ffv1_sub_descriptor->extradata) + return AVERROR(ENOMEM); + ffv1_sub_descriptor->extradata_size = size; + avio_read(pb, ffv1_sub_descriptor->extradata, size); + } + + return 0; +} + static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size) { MXFTaggedValue *tagged_value = arg; @@ -1554,6 +1583,7 @@ static const MXFCodecUL mxf_picture_essence_container_uls[] = { { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x1c,0x01,0x00 }, 14, AV_CODEC_ID_PRORES, NULL, 14 }, /* ProRes */ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x02,0x0d,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO, NULL, 15 }, /* MPEG-ES */ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO, NULL, 15, D10D11Wrap }, /* SMPTE D-10 mapping */ + { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0d,0x0d,0x01,0x03,0x01,0x02,0x23,0x01,0x00 }, 14, AV_CODEC_ID_FFV1, NULL, 14 }, { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, AV_CODEC_ID_DVVIDEO, NULL, 15 }, /* DV 625 25mbps */ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14, AV_CODEC_ID_RAWVIDEO, NULL, 15, RawVWrap }, /* uncompressed picture */ { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0a,0x0e,0x0f,0x03,0x01,0x02,0x20,0x01,0x01 }, 15, AV_CODEC_ID_HQ_HQA }, @@ -2444,6 +2474,21 @@ static MXFMCASubDescriptor *find_mca_link_id(MXFContext *mxf, enum MXFMetadataSe return NULL; } +static void parse_ffv1_sub_descriptor(MXFContext *mxf, MXFTrack *source_track, MXFDescriptor *descriptor, AVStream *st) +{ + for (int i = 0; i < descriptor->sub_descriptors_count; i++) { + MXFFFV1SubDescriptor *ffv1_sub_descriptor = mxf_resolve_strong_ref(mxf, &descriptor->sub_descriptors_refs[i], FFV1SubDescriptor); + if (ffv1_sub_descriptor == NULL) + continue; + + descriptor->extradata = ffv1_sub_descriptor->extradata; + descriptor->extradata_size = ffv1_sub_descriptor->extradata_size; + ffv1_sub_descriptor->extradata = NULL; + ffv1_sub_descriptor->extradata_size = 0; + break; + } +} + static int parse_mca_labels(MXFContext *mxf, MXFTrack *source_track, MXFDescriptor *descriptor, AVStream *st) { uint64_t routing[FF_SANE_NB_CHANNELS] = {0}; @@ -2972,6 +3017,8 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codecpar->codec_id = AV_CODEC_ID_EIA_608; } } + if (!descriptor->extradata) + parse_ffv1_sub_descriptor(mxf, source_track, descriptor, st); if (descriptor->extradata) { if (!ff_alloc_extradata(st->codecpar, descriptor->extradata_size)) { memcpy(st->codecpar->extradata, descriptor->extradata, descriptor->extradata_size); @@ -3159,6 +3206,7 @@ static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6b,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), AudioChannelLabelSubDescriptor }, { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6c,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), SoundfieldGroupLabelSubDescriptor }, { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x6d,0x00 }, mxf_read_mca_sub_descriptor, sizeof(MXFMCASubDescriptor), GroupOfSoundfieldGroupsLabelSubDescriptor }, + { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x81,0x03 }, mxf_read_ffv1_sub_descriptor, sizeof(MXFFFV1SubDescriptor), FFV1SubDescriptor }, { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */ { { 0x06,0x0e,0x2b,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent },