From patchwork Sat Jan 1 04:16:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: quietvoid X-Patchwork-Id: 32981 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:cd86:0:0:0:0:0 with SMTP id d128csp14457988iog; Fri, 31 Dec 2021 20:16:55 -0800 (PST) X-Google-Smtp-Source: ABdhPJzcwTlhNiQWzcK5+Mvqva7F+TTcvjckhyFtkEsrXmP8FXUxYDZKHiIRy4iEqkXIv5uhSvw2 X-Received: by 2002:a17:906:5948:: with SMTP id g8mr29820931ejr.4.1641010614875; Fri, 31 Dec 2021 20:16:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1641010614; cv=none; d=google.com; s=arc-20160816; b=A4Pr82xl0ENGP0afo2zFMknJE3x+apJOm90EJ31Z46MAsNvF0OcfnBo0qwtAKEN67i NudQGXgD1BNRwkA2XnyK9DwScYuZiJmKhggGZepsaXcXAdzy7MCzG38ior0K3MEgE0Qo dl92uJ6nPKKV/zw3SH0nQ1R+n6+gCUXbRFs8/OpcEdpB+Na8+0dDgBb5u7IoW5ZEgOMm mq5JKOr6C9Vj3sKC3dawhZo4qJFDyjpBtEELddtmXYBf2p/fJalBWF8khPAVYbPRV/PD eb2bqlLbLgJuibHtrJqZiUNKN3RKaGQnorNnyHOCnJFZ58hp58kW4xT9jXy9+yF6LMs/ o6Ng== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:reply-to :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:subject:mime-version:references:in-reply-to :message-id:date:to:from:dkim-signature:delivered-to; bh=NNUtVPGmLDrF3CaHXSaS4UeGi8/y2YZIjbq//FUk6hg=; b=nLClWKiPrzghI67pd/1wP7LhZfMq1cMEa2kcy/N2vrLK4M5QkddX9kWYhY1f/H7kBv HlvCga9hqXC3iDlf/4dv0sZMbCHEOOKPf7S++6gHTGYbULNFjS3DrYCDU+Tv63zLQith KFqWtyiQRl8lexceUfgb/9JbNgua9bgYEjc7BdGpfXUAE3XKJoWNyYta8/NZtP/Ly+zW I4X2SYgrbdyVJPgCMw1GM3pQto55wDtQJxamBcCyrcHlcaA3gzY2Wblkh50dspMmgGV1 yE/GmVb/ftYVVf1DiG19XHdVoDg441uuXrz3HiWA0mmNRMRjA6xJ443bfQFrOqN7cRJN IgDw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=YENitaec; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org. [79.124.17.100]) by mx.google.com with ESMTP id dn21si16694882ejc.45.2021.12.31.20.16.54; Fri, 31 Dec 2021 20:16:54 -0800 (PST) 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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=YENitaec; 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; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id D94B268B0CC; Sat, 1 Jan 2022 06:16:33 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f52.google.com (mail-ed1-f52.google.com [209.85.208.52]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id C6E1B68B050 for ; Sat, 1 Jan 2022 06:16:25 +0200 (EET) Received: by mail-ed1-f52.google.com with SMTP id w16so114592788edc.11 for ; Fri, 31 Dec 2021 20:16:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=A2ALUKCqqwq20e3+90QAjFlg9e1jmNZL2+5gl8/uVzQ=; b=YENitaecx1d0eGHH7MStFjWHvE9Li+SiZVIEzi8FXISNaxn68lnkarYQyCs1dP4dYs Akt+IdGZKWhrBczpbosgGxVr2EF9svO7iuy4X/GoU9CQoGcagkBGDD39EI+WjCfUIBSx ICPSjNQXzRe0eWq+qutWeJbCsTXHo9OLndBsEs7pyApOrZUMRHVGgZ0FpNlbdsCB+428 x/Iu/dAb04g/KXm39pe+JWeB1O5dAgFLRn3QNDm4oNrvEzMjygjfOSXMFFfq6wA767Ze gVrPPsAKm7wAoFpmgLXmJeiAXAPnHKSs1hoB402L9e50nHH9PGp6d8jB5FzVQ/2rSQHP w6+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=A2ALUKCqqwq20e3+90QAjFlg9e1jmNZL2+5gl8/uVzQ=; b=5GcG/ApeQjnCMyVQL+1jPiGwCc15YjcKWBeQS5rZ38XlFiQs7ytGxKgpznthcX+0we RKhmHCeLHReOZmomVzaV1hb14QNe6JSYSTK5qwxIJxFrsAiEDMoQvhV+tJZvfwBo8g/F TPiYIVcog/ir8bCRsmV2UwGPFWRQ/tF5NNrkqmB2BtACNTFSb1pmB6PZbIUk37qhZ3nX YS1izA5MJ3gJcfchGoTUoDP43ZJK7mQmY00mCe6C6OXFcKQ0vSpDWvMbP0BPc1vgU1Vd OFbr+b8ZvQDkCLLFEbGXHta04aFVz+Gl5ky4ovUl6fJujIIFZBcMeXX3qmwkqnQwSVHc 52eg== X-Gm-Message-State: AOAM533AZrqVq/5JgCRvz7y8Ut5G6MufrAvgciAutTwMXo2PICR3VXQm jytKmPW1k4RfbcU0r64EjMWqQXMUGUM= X-Received: by 2002:a17:906:4918:: with SMTP id b24mr29244737ejq.466.1641010585016; Fri, 31 Dec 2021 20:16:25 -0800 (PST) Received: from nark.. ([2a01:4f8:162:73cc::2]) by smtp.gmail.com with ESMTPSA id z18sm11272075edc.76.2021.12.31.20.16.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 31 Dec 2021 20:16:24 -0800 (PST) From: quietvoid X-Google-Original-From: quietvoid To: ffmpeg-devel@ffmpeg.org Date: Sat, 1 Jan 2022 05:16:18 +0100 Message-Id: <20220101041621.427012-3-tcChlisop0@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220101041621.427012-1-tcChlisop0@gmail.com> References: <20220101041621.427012-1-tcChlisop0@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v11 2/5] avformat/matroska{dec, enc}: Parse BlockAdditionMapping elements 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 Cc: quietvoid Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: BeNRnDXfI9nq Adds handling of dvcC/dvvC block addition mappings. The parsing creates AVDOVIDecoderConfigurationRecord side data. The configuration block is written when muxing into Matroska, if DOVI side data is present for the track. Most of the Matroska element parsing is based on Plex's FFmpeg source code. Signed-off-by: quietvoid --- libavformat/Makefile | 4 +-- libavformat/matroska.h | 9 ++++++ libavformat/matroskadec.c | 58 +++++++++++++++++++++++++++++++++++++-- libavformat/matroskaenc.c | 37 +++++++++++++++++++++++++ 4 files changed, 104 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index e31b248ac0..4464c2b049 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -316,11 +316,11 @@ OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ flac_picture.o isom_tags.o rmsipr.o \ oggparsevorbis.o vorbiscomment.o \ - qtpalette.o replaygain.o + qtpalette.o replaygain.o dovi_isom.o OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ av1.o avc.o hevc.o isom_tags.o \ flacenc_header.o avlanguage.o \ - vorbiscomment.o wv.o + vorbiscomment.o wv.o dovi_isom.o OBJS-$(CONFIG_MCA_DEMUXER) += mca.o OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o OBJS-$(CONFIG_MD5_MUXER) += hashenc.o diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 2d04a6838b..16491aae22 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -111,6 +111,7 @@ #define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 #define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F #define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE +#define MATROSKA_ID_TRACKBLKADDMAPPING 0x41E4 /* IDs in the trackvideo master */ #define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 @@ -189,6 +190,12 @@ #define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 #define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 +/* IDs in the block addition mapping master */ +#define MATROSKA_ID_BLKADDIDVALUE 0x41F0 +#define MATROSKA_ID_BLKADDIDNAME 0x41A4 +#define MATROSKA_ID_BLKADDIDTYPE 0x41E7 +#define MATROSKA_ID_BLKADDIDEXTRADATA 0x41ED + /* ID in the cues master */ #define MATROSKA_ID_POINTENTRY 0xBB @@ -385,4 +392,6 @@ extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_P int ff_mkv_stereo3d_conv(AVStream *st, MatroskaVideoStereoModeType stereo_mode); +#define DVCC_DVVC_BLOCK_TYPE_NAME "Dolby Vision configuration" + #endif /* AVFORMAT_MATROSKA_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index a4bbbe954e..6ce553205d 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -53,6 +53,7 @@ #include "avformat.h" #include "avio_internal.h" +#include "dovi_isom.h" #include "internal.h" #include "isom.h" #include "matroska.h" @@ -239,6 +240,13 @@ typedef struct MatroskaTrackOperation { EbmlList combine_planes; } MatroskaTrackOperation; +typedef struct MatroskaBlockAdditionMapping { + uint64_t value; + char *name; + uint64_t type; + EbmlBin extradata; +} MatroskaBlockAdditionMapping; + typedef struct MatroskaTrack { uint64_t num; uint64_t uid; @@ -269,6 +277,7 @@ typedef struct MatroskaTrack { int ms_compat; int needs_decoding; uint64_t max_block_additional_id; + EbmlList block_addition_mappings; uint32_t palette[AVPALETTE_COUNT]; int has_palette; @@ -419,8 +428,8 @@ typedef struct MatroskaDemuxContext { // incomplete type (6.7.2 in C90, 6.9.2 in C99). // Removing the sizes breaks MSVC. static EbmlSyntax ebml_syntax[3], matroska_segment[9], matroska_track_video_color[15], matroska_track_video[19], - matroska_track[32], matroska_track_encoding[6], matroska_track_encodings[2], - matroska_track_combine_planes[2], matroska_track_operation[2], matroska_tracks[2], + matroska_track[33], matroska_track_encoding[6], matroska_track_encodings[2], + matroska_track_combine_planes[2], matroska_track_operation[2], matroska_block_addition_mapping[5], matroska_tracks[2], matroska_attachments[2], matroska_chapter_entry[9], matroska_chapter[6], matroska_chapters[2], matroska_index_entry[3], matroska_index[2], matroska_tag[3], matroska_tags[2], matroska_seekhead[2], matroska_blockadditions[2], matroska_blockgroup[8], matroska_cluster_parsing[8]; @@ -570,6 +579,14 @@ static EbmlSyntax matroska_track_operation[] = { CHILD_OF(matroska_track) }; +static EbmlSyntax matroska_block_addition_mapping[] = { + { MATROSKA_ID_BLKADDIDVALUE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, value) }, + { MATROSKA_ID_BLKADDIDNAME, EBML_STR, 0, 0, offsetof(MatroskaBlockAdditionMapping, name) }, + { MATROSKA_ID_BLKADDIDTYPE, EBML_UINT, 0, 0, offsetof(MatroskaBlockAdditionMapping, type) }, + { MATROSKA_ID_BLKADDIDEXTRADATA, EBML_BIN, 0, 0, offsetof(MatroskaBlockAdditionMapping, extradata) }, + CHILD_OF(matroska_track) +}; + static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, 0, offsetof(MatroskaTrack, num) }, { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, 0, offsetof(MatroskaTrack, name) }, @@ -593,6 +610,7 @@ static EbmlSyntax matroska_track[] = { { MATROSKA_ID_TRACKOPERATION, EBML_NEST, 0, 0, offsetof(MatroskaTrack, operation), { .n = matroska_track_operation } }, { MATROSKA_ID_TRACKCONTENTENCODINGS, EBML_NEST, 0, 0, 0, { .n = matroska_track_encodings } }, { MATROSKA_ID_TRACKMAXBLKADDID, EBML_UINT, 0, 0, offsetof(MatroskaTrack, max_block_additional_id), { .u = 0 } }, + { MATROSKA_ID_TRACKBLKADDMAPPING, EBML_NEST, 0, sizeof(MatroskaBlockAdditionMapping), offsetof(MatroskaTrack, block_addition_mappings), { .n = matroska_block_addition_mapping } }, { MATROSKA_ID_SEEKPREROLL, EBML_UINT, 0, 0, offsetof(MatroskaTrack, seek_preroll), { .u = 0 } }, { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, @@ -2311,6 +2329,38 @@ static int mkv_parse_video_projection(AVStream *st, const MatroskaTrack *track, return 0; } +static int mkv_parse_dvcc_dvvc(AVFormatContext *s, AVStream *st, const MatroskaTrack *track, + EbmlBin *bin) +{ + return ff_isom_parse_dvcc_dvvc(s, st, bin->data, bin->size); +} + +static int mkv_parse_block_addition_mappings(AVFormatContext *s, AVStream *st, const MatroskaTrack *track) +{ + const EbmlList *mappings_list = &track->block_addition_mappings; + MatroskaBlockAdditionMapping *mappings = mappings_list->elem; + int ret; + + for (int i = 0; i < mappings_list->nb_elem; i++) { + MatroskaBlockAdditionMapping *mapping = &mappings[i]; + + switch (mapping->type) { + case MKBETAG('d','v','c','C'): + case MKBETAG('d','v','v','C'): + if ((ret = mkv_parse_dvcc_dvvc(s, st, track, &mapping->extradata)) < 0) + return ret; + + break; + default: + av_log(s, AV_LOG_DEBUG, + "Unknown block additional mapping type 0x%"PRIx64", value %"PRIu64", name \"%s\"\n", + mapping->type, mapping->value, mapping->name ? mapping->name : ""); + } + } + + return 0; +} + static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID *codec_id) { const AVCodecTag *codec_tags; @@ -2898,6 +2948,10 @@ static int matroska_parse_tracks(AVFormatContext *s) if (track->flag_textdescriptions) st->disposition |= AV_DISPOSITION_DESCRIPTIONS; } + + ret = mkv_parse_block_addition_mappings(s, st, track); + if (ret < 0) + return ret; } return 0; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 8c4cf4024a..5cc59dc9f8 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -27,6 +27,7 @@ #include "avformat.h" #include "avio_internal.h" #include "avlanguage.h" +#include "dovi_isom.h" #include "flacenc.h" #include "internal.h" #include "isom.h" @@ -1120,6 +1121,37 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, return 0; } +static void mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st) +{ + AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *) + av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL); + + if (dovi && dovi->dv_profile <= 10) { + ebml_master mapping; + uint8_t buf[ISOM_DVCC_DVVC_SIZE]; + uint32_t type; + + uint64_t expected_size = (2 + 1 + (sizeof(DVCC_DVVC_BLOCK_TYPE_NAME) - 1)) + + (2 + 1 + 4) + (2 + 1 + ISOM_DVCC_DVVC_SIZE); + + if (dovi->dv_profile > 7) { + type = MKBETAG('d', 'v', 'v', 'C'); + } else { + type = MKBETAG('d', 'v', 'c', 'C'); + } + + ff_isom_put_dvcc_dvvc(s, buf, dovi); + + mapping = start_ebml_master(pb, MATROSKA_ID_TRACKBLKADDMAPPING, expected_size); + + put_ebml_string(pb, MATROSKA_ID_BLKADDIDNAME, DVCC_DVVC_BLOCK_TYPE_NAME); + put_ebml_uint(pb, MATROSKA_ID_BLKADDIDTYPE, type); + put_ebml_binary(pb, MATROSKA_ID_BLKADDIDEXTRADATA, buf, sizeof(buf)); + + end_ebml_master(pb, mapping); + } +} + static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, AVStream *st, mkv_track *track, AVIOContext *pb, int is_default) @@ -1319,6 +1351,11 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, mkv_write_video_projection(s, pb, st); end_ebml_master(pb, subinfo); + + if (mkv->mode != MODE_WEBM) { + mkv_write_dovi(s, pb, st); + } + break; case AVMEDIA_TYPE_AUDIO: