From patchwork Sat Dec 4 01:09:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: quietvoid X-Patchwork-Id: 31951 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:cd86:0:0:0:0:0 with SMTP id d128csp1426886iog; Fri, 3 Dec 2021 17:09:50 -0800 (PST) X-Google-Smtp-Source: ABdhPJxSNLQpkpuF68Wx4SiPMQ4em6c9uf8zZQgSVJ6mLd96wmnqI/ugPMUBYwkQHa86BQ88CN3G X-Received: by 2002:a17:906:c111:: with SMTP id do17mr27612453ejc.284.1638580190094; Fri, 03 Dec 2021 17:09:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1638580190; cv=none; d=google.com; s=arc-20160816; b=jSq5TQ7tskAMYlJ2r009DrSetGZEvY3q5cEt7Q2B8zqriyd7hFFnEuhx+TRkI90bBO P855R5gFlpm76hAyF0PzIIaA214Eu+HIWGO6qWIyROtWtX001aCckYCOl7++xltteQ6G QVrqNGOFQJ/Ky0SZ+cLLvGUvnJ1TYeAJJNtD6nemQHkQCMFK8DDAM6r5b9u8eUmtucJE BZB7SlIU5J5FD2a6gONx9UgfhEjZntLx48xlBpSKhHb49mr7P9I7nM60/h4UHD76VXst zCxzpU99os9/tyCTyOsTpjg/0b1zW2aEpo8BmqWMCMW3SmEP5aoFqgSl87M6TWM9Acvt 3uDA== 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=tqLxIELlIvyxzUYgOcpQ4z7dD5G1DDA5+aSAHJuGlF0=; b=m3Jy+t7BBhD4a6PJRjx1ZjBqTOpo0naPkwucxbXapSVrsOeEqf1AqoaJHMxzymoUdS YezBuNUqJ1YIMmqYhej7Ued6HvbN4emSrFHcyf9ppYcXvgPzwl6ZhzxvbQpUM6/Sxx25 5XhoqE7v2H/Xd+HF2Lc8lek5DD/LD42x0nm9/yuRymS0OXPuLnNDfYgmON5Ix3eflJO2 Xa5fwwZKee6D7YE8XpZezZnodcA6bSxxa1nsqiySczKJLDL88TiTx1FtBfem8z+LynM8 TX8jJdo9tKyE/cyAl3j3uJzajjtt+nJfVutcA8iCYLJSlRAg9sEhJZ9COK/ebzx6OlKu pXUQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b=loDkVORP; 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 lr12si5461849ejb.296.2021.12.03.17.09.49; Fri, 03 Dec 2021 17:09:50 -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=loDkVORP; 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 7411C680967; Sat, 4 Dec 2021 03:09:29 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 43AB668A774 for ; Sat, 4 Dec 2021 03:09:20 +0200 (EET) Received: by mail-wm1-f41.google.com with SMTP id p18so3699530wmq.5 for ; Fri, 03 Dec 2021 17:09:20 -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=wOkO7xKwIGlNeJLCVcgkNL8izZEnf2xshssKGJuj/pc=; b=loDkVORP7bloDnKzJF9P90+Dy0dtJCkfkx8v+zJ8BeyAoUvVTPJRZvSB5LpvsRWfHq ZBgOWTe90h00K5uy+nVjY5CU7lJbWVgO++tOwL7fhhgROQhGrr7AMjGZ9Ot6HjhK/aui 0Yik5MIojpXdfgJi1juX2X432mcYlTC4CUK5zsBKK6fgveB1u8qCLf7QVVoHek1Y6UNI t/wSJSbe1iQZ4zDoosFVfysAYQ0ShCn3dvCERlTfpZeAYLyGk/Oc1WCd7Z5oAP6reb+f fX7v5M/of9fX5BfBxFCndwKT7s8zAF7HG0iYo/oZt5sqyQiu2hMZzAzWezDvsyO39CA4 MOkg== 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=wOkO7xKwIGlNeJLCVcgkNL8izZEnf2xshssKGJuj/pc=; b=yDNT/zgj2yFZwTRnmMJp3Uc1jE6x8bCNI9e8FuEDcBVzpHwN5J/bAWqUBCzCqkD1t1 lcK5lHiwkEP4mkZwMaOPucc4X8Df1wSwbZCdh0l/k8MofHABEBbozqc5VjjFcUYY+6NU MRjqgoVzE9zqEl7dPVNmgoENY0A5c2AM1hwhECjvjr3IU/EiQdDgW44aRTO114U771tR JNEq739sHZYI45keXUHKV/RDGHi3FMnm/YlNdb//1M1pvdoMSgLmNGu57z2iPyEcNmGM zVds7MCutVY5neM+lgA7RBMAQrIledaS6Vc5K74l1JDzotiXuJluT1MGDPgjdROahA/r dpXA== X-Gm-Message-State: AOAM531wtTx7oywworMWXXyjuKhPpoRou3CCs0t8VQF087UX5h3LKww7 uu1gPgx0EAysbXRZk8xQ4eu5qmB7iVIWIw== X-Received: by 2002:a05:600c:4113:: with SMTP id j19mr19759767wmi.48.1638580159541; Fri, 03 Dec 2021 17:09:19 -0800 (PST) Received: from localhost.localdomain ([2a01:4f8:162:73cc::2]) by smtp.gmail.com with ESMTPSA id d8sm3873739wrm.76.2021.12.03.17.09.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Dec 2021 17:09:19 -0800 (PST) From: quietvoid X-Google-Original-From: quietvoid To: ffmpeg-devel@ffmpeg.org Date: Sat, 4 Dec 2021 02:09:02 +0100 Message-Id: <20211204010905.2258652-3-tcChlisop0@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211204010905.2258652-1-tcChlisop0@gmail.com> References: <20211204010905.2258652-1-tcChlisop0@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v8 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: yTvt16a4ZF6o From: quietvoid 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 | 45 ++++++++++++++++++++++++++++++ 4 files changed, 112 insertions(+), 4 deletions(-) diff --git a/libavformat/Makefile b/libavformat/Makefile index 2b5caf9d33..bd12562a24 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -314,11 +314,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..6fca0e3cb9 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,44 @@ static int mkv_write_stereo_mode(AVFormatContext *s, AVIOContext *pb, return 0; } +static int mkv_write_dovi(AVFormatContext *s, AVIOContext *pb, AVStream *st) +{ + int ret; + AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *) + av_stream_get_side_data(st, AV_PKT_DATA_DOVI_CONF, NULL); + + if (dovi) { + ebml_master mapping; + uint8_t buf[ISOM_DVCC_DVVC_SIZE]; + uint32_t type; + + uint64_t size; + 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'); + } + + if ((ret = ff_isom_put_dvcc_dvvc(s, buf, sizeof(buf), dovi)) < 0) + return ret; + + size = ret; + + 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, size); + + end_ebml_master(pb, mapping); + } + + return 0; +} + static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, AVStream *st, mkv_track *track, AVIOContext *pb, int is_default) @@ -1319,6 +1358,12 @@ 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) { + if ((ret = mkv_write_dovi(s, pb, st)) < 0) + return ret; + } + break; case AVMEDIA_TYPE_AUDIO: