From patchwork Tue Mar 21 17:06:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Almer X-Patchwork-Id: 40768 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a05:6a20:d046:b0:cd:afd7:272c with SMTP id hv6csp2759357pzb; Tue, 21 Mar 2023 10:07:57 -0700 (PDT) X-Google-Smtp-Source: AK7set8aahTTuw7FnZk43DkB/j7BdrZbASLD9ejxjZA/TiVaPNh11FXbpsfBwH0kZLJ+Wn5nK39e X-Received: by 2002:a17:906:b309:b0:933:c052:a277 with SMTP id n9-20020a170906b30900b00933c052a277mr3695194ejz.12.1679418477127; Tue, 21 Mar 2023 10:07:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1679418477; cv=none; d=google.com; s=arc-20160816; b=RPAQzhSWdAwLIiI2Lwd68WKuVNg7NICDQBhIdkgdrvImEzT2HjJaA789muvMqUAPfx Wmv/qXFQpYLYDN6g4lOK/nu/YtET6jGjsMQzIxVrOwATIeha2L5YbOI4qpAuhWp90QTp o4SVSVw8jm/ckFNzb7yoamdBKBqNhM1NYqZ3P9TrSo1i7nCojCsjLXgNRHQXroyaaqAE auqTkuzyKPiJuDe3pqOCW5LbqIwMyTjJ98IGGZxVirpWIizPPr7MUmf5B4f6ufXFJ++7 l4rPbqzzW/B0iH9NSswH/PJ5NHzFJF3F3EGlEAoGorPyG+mRrrmRZ3Q3JHfinv4tEpRu vpiA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding: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=SS0q7dk2dOYpjzUg0Vq13qDoezjhf9gvGGhTSo2LYcI=; b=Iv0VlTuZddTuAFYk8UVd/Ou58urqySDGekbmJkvBJMJ0BekFgMPFHRYFVy/eFz+k6o FRaT3VryY82wRFu8TE27Xi70RuZl24UTbpx7ETYniUlBp+zrESEmbWQ6BaN57dN/B+ts ya6lNWctJSwbSJnoPoAN+oLh6fmnp8mg6oEf0WgFc7n+QE7VcdGijgqbIMsRlzuMMYyN Vc7zY43mnt0CyyoizNRX9RwWDJ1jkXeaegyN+OiXfj3Zds2vj/JP0ynYWHtqPgO+AS/U R3g+G5QB3nE6ZWarZNP5maKv/epLj7IpAqhnY5sw7YLggqcNJRG9yBrb4OWcMdaQUINh gMqw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b="cI/sT7Gj"; 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 vq8-20020a170907a4c800b00933489ce7a6si8461427ejc.444.2023.03.21.10.07.56; Tue, 21 Mar 2023 10:07:57 -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; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20210112 header.b="cI/sT7Gj"; 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 7F90968C3A7; Tue, 21 Mar 2023 19:07:06 +0200 (EET) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-oi1-f180.google.com (mail-oi1-f180.google.com [209.85.167.180]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6F92468BE68 for ; Tue, 21 Mar 2023 19:06:59 +0200 (EET) Received: by mail-oi1-f180.google.com with SMTP id v17so1852386oic.5 for ; Tue, 21 Mar 2023 10:06:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; t=1679418418; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=dVay7/vtB0WW3nxEYctfx7pAIoGFlmKvbHSRvL26uJc=; b=cI/sT7Gj3kFhnWUtmnsowwnnBlgVpDul1D+1a7C2jkTy6CTKTFrqN7Bc1u7QaN+1l/ kzvWgWX33mSwQ2SYPO8q9yyJCBqqXxXjK4KRZpEOgoUBM6HvRf21Gn82D+5e/Q5oU+BG tqD4pzg0lf+C4MmVYL3Lc8tz3zdsALQifmRGv87MaRzBlWe17UTStcmydjQv8NrlUds7 G++TzTaCz716t+CHLBolfgY0tHUZhyZhrQjs9vOKvKeU3CC1SQ9APooS0IOHx45Z6WFI B/TbceGIvfxVlfYA/5X55zfjAu6nQFIwVcVm1Mt86n7Mbekr6Nh3i7mKjtC5LclwSl5x ZAcA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; t=1679418418; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dVay7/vtB0WW3nxEYctfx7pAIoGFlmKvbHSRvL26uJc=; b=EITZgyN11lpvYxkA6Okx6yjzTukeNN67aV5P2cZYqCdro/+nl5g2Zvr0BNtJFOC+yG I8zNEWfLWMmxDl+JgIQu8YT5cE3z8+gR0aKfPFEr65HUt7QC34vdcEvGfQm+YQfkQmOd ENvgk8kDJZ/BjIPEYesz0657baokLhYSZIS3X4gHKjHgV5hcp1cRzHUJ6y0eg/ZV2W9/ +4TiUDKWVKc0a+CpaNJM3ytIZI2AKbBnXAB6ErPOYVmRmLXfZ6EpL7Erh/1DXWpsKfaE Bi5spS/ACMlaAsGuhgSVDEgYpoe8m5N+aoiR6m1l/XGA29gih9QDBUG08gTH9WcY8A04 TRhQ== X-Gm-Message-State: AO0yUKW0+g6Y2AK8dTUpJs01Fo09Ln5Tm9IO1opgmfAL6sB5jzLdQHB7 fpdqKTP1GVM048g/ce4PemLgbAV9Ung= X-Received: by 2002:aca:1202:0:b0:383:f380:868e with SMTP id 2-20020aca1202000000b00383f380868emr1279352ois.34.1679418417640; Tue, 21 Mar 2023 10:06:57 -0700 (PDT) Received: from localhost.localdomain (host197.190-225-105.telecom.net.ar. [190.225.105.197]) by smtp.gmail.com with ESMTPSA id b11-20020aca1b0b000000b003872148d322sm845876oib.22.2023.03.21.10.06.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Mar 2023 10:06:57 -0700 (PDT) From: James Almer To: ffmpeg-devel@ffmpeg.org Date: Tue, 21 Mar 2023 14:06:36 -0300 Message-Id: <20230321170637.10907-6-jamrial@gmail.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230321170637.10907-1-jamrial@gmail.com> References: <20230321170637.10907-1-jamrial@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 6/7] avformat/matroskaenc: support writing Dynamic HDR10+ packet side data 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 Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" X-TUID: Uj8S1UOnUQC2 Signed-off-by: James Almer --- libavformat/matroskaenc.c | 90 +++++++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 0687d9c32e..b0d088cef5 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -44,6 +44,7 @@ #include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "libavutil/dict.h" +#include "libavutil/hdr_dynamic_metadata.h" #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" #include "libavutil/lfg.h" @@ -1612,6 +1613,10 @@ static void mkv_write_blockadditionmapping(AVFormatContext *s, MatroskaMuxContex // we either write the default value here, or a void element. Either of them will // be overwritten when finishing the track. put_ebml_uint(mkv->track.bc, MATROSKA_ID_TRACKMAXBLKADDID, 0); + // Similarly, reserve space for an eventual HDR10+ ITU T.35 metadata BlockAdditionMapping. + put_ebml_void(pb, 3 /* BlockAdditionMapping */ + + 4 /* BlockAddIDValue */ + + 4 /* BlockAddIDType */); } if (dovi && dovi->dv_profile <= 10) { @@ -2618,17 +2623,34 @@ static int webm_reformat_vtt(MatroskaMuxContext *mkv, AVIOContext *pb, return 0; } +static void mkv_write_blockadditional(EbmlWriter *writer, const uint8_t *buf, + size_t size, enum AVPacketSideDataType type, + uint64_t additional_id) +{ + size_t offset = 0; + + if (type == AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL) + offset = 8; + + ebml_writer_open_master(writer, MATROSKA_ID_BLOCKMORE); + ebml_writer_add_uint(writer, MATROSKA_ID_BLOCKADDID, additional_id); + ebml_writer_add_bin (writer, MATROSKA_ID_BLOCKADDITIONAL, + buf + offset, size - offset); + ebml_writer_close_master(writer); +} + static int mkv_write_block(void *logctx, MatroskaMuxContext *mkv, AVIOContext *pb, const AVCodecParameters *par, mkv_track *track, const AVPacket *pkt, int keyframe, int64_t ts, uint64_t duration, int force_blockgroup, int64_t relative_packet_pos) { - uint8_t *side_data; + uint8_t *side_data, *buf = NULL; size_t side_data_size; - uint64_t additional_id; + uint64_t additional_id, max_blockaddid = 0; unsigned track_number = track->track_num; - EBML_WRITER(9); + int ret; + EBML_WRITER(13); mkv->cur_block.track = track; mkv->cur_block.pkt = pkt; @@ -2670,17 +2692,50 @@ static int mkv_write_block(void *logctx, MatroskaMuxContext *mkv, // Only the Codec-specific BlockMore (id == 1) is currently supported. (additional_id = AV_RB64(side_data)) == 1) { ebml_writer_open_master(&writer, MATROSKA_ID_BLOCKADDITIONS); - ebml_writer_open_master(&writer, MATROSKA_ID_BLOCKMORE); - /* Until dbc50f8a our demuxer used a wrong default value - * of BlockAddID, so we write it unconditionally. */ - ebml_writer_add_uint(&writer, MATROSKA_ID_BLOCKADDID, additional_id); - ebml_writer_add_bin (&writer, MATROSKA_ID_BLOCKADDITIONAL, - side_data + 8, side_data_size - 8); - ebml_writer_close_master(&writer); - ebml_writer_close_master(&writer); - track->max_blockaddid = additional_id; + mkv_write_blockadditional(&writer, side_data, side_data_size, + AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, + additional_id); + max_blockaddid = track->max_blockaddid = FFMAX(track->max_blockaddid, + additional_id); + } + + side_data = av_packet_get_side_data(pkt, + AV_PKT_DATA_DYNAMIC_HDR10_PLUS, + &side_data_size); + if (side_data_size) { + uint8_t *payload; + size_t payload_size, buf_size; + int ret = av_dynamic_hdr_plus_to_t35((AVDynamicHDRPlus *)side_data, &payload, + &payload_size); + if (ret < 0) + return ret; + + buf_size = payload_size + 6; + buf = av_malloc(buf_size); + if (!buf) { + av_free(payload); + return AVERROR(ENOMEM); + } + + AV_WB8 (buf + 0, 0xB5); // country_code + AV_WB16(buf + 1, 0x3C); // provider_code + AV_WB16(buf + 3, 0x01); // provider_oriented_code + AV_WB8 (buf + 5, 0x04); // application_identifier + memcpy(buf + 6, payload, payload_size); + + if (!max_blockaddid) + ebml_writer_open_master(&writer, MATROSKA_ID_BLOCKADDITIONS); + mkv_write_blockadditional(&writer, buf, buf_size, + AV_PKT_DATA_DYNAMIC_HDR10_PLUS, + 4); + track->max_blockaddid = FFMAX(track->max_blockaddid, 4); + + av_free(payload); } + if (max_blockaddid) + ebml_writer_close_master(&writer); + if (!force_blockgroup && writer.nb_elements == 2) { /* Nothing except the BlockGroup + Block. Can use a SimpleBlock. */ writer.elements++; // Skip the BlockGroup. @@ -2693,7 +2748,10 @@ static int mkv_write_block(void *logctx, MatroskaMuxContext *mkv, ebml_writer_add_sint(&writer, MATROSKA_ID_BLOCKREFERENCE, track->last_timestamp - ts); - return ebml_writer_write(&writer, pb); + ret = ebml_writer_write(&writer, pb); + av_free(buf); + + return ret; } static int mkv_end_cluster(AVFormatContext *s) @@ -3095,6 +3153,12 @@ after_cues: avio_seek(mkv->track.bc, track->blockadditionmapping_offset, SEEK_SET); put_ebml_uint(mkv->track.bc, MATROSKA_ID_TRACKMAXBLKADDID, track->max_blockaddid); + if (track->max_blockaddid == 4) { // HDR10+ + ebml_master mapping_master = start_ebml_master(mkv->track.bc, MATROSKA_ID_TRACKBLKADDMAPPING, 8); + put_ebml_uint(mkv->track.bc, MATROSKA_ID_BLKADDIDTYPE, MATROSKA_BLOCK_ADD_ID_TYPE_ITU_T_T35); + put_ebml_uint(mkv->track.bc, MATROSKA_ID_BLKADDIDVALUE, 4); + end_ebml_master(mkv->track.bc, mapping_master); + } } avio_seek(mkv->track.bc, end, SEEK_SET);