From patchwork Tue Mar 30 08:23:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Jan_Ekstr=C3=B6m?= X-Patchwork-Id: 26652 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 8DD8E44A116 for ; Tue, 30 Mar 2021 11:50:46 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6ED8E688152; Tue, 30 Mar 2021 11:50:46 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f179.google.com (mail-lj1-f179.google.com [209.85.208.179]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4059C680506 for ; Tue, 30 Mar 2021 11:50:40 +0300 (EEST) Received: by mail-lj1-f179.google.com with SMTP id r20so19029489ljk.4 for ; Tue, 30 Mar 2021 01:50:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=HfbHFdud78Lu3zbQBkpl90wCwbTbOCjMHYMQl5ACnUs=; b=ILgMyqR7pJ4953pZwOa9un8vhXiFnUHNLT2A9WsSmritFEj0RWmeQdviyyp33WfhEX QBQAE75BpcrNAZuhaojCnQcmYIp0doTWenCJeyUswiQPJ4mMB7nVD17rJ4q7Ko48Zk22 6xXG9SMxi+8GIyxu1lOfi24J+tsuzvGJCrTWnfhDo07QYrXBQiGALJNSF0CK4tswYj47 yfUbZ4en3J/HfTRZ4QNmfsu9UJtTBsYHsg5+2fmMFSWxVREhz+gMuH1PBmUjZbQjrKiO 3UzdrdWfr2eWNfXXnGYQuZifttwZdzrW5X/6BY2qIo6ZPJXbX02ThPJV0oB4Wjr1mJCC hYzQ== 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=HfbHFdud78Lu3zbQBkpl90wCwbTbOCjMHYMQl5ACnUs=; b=g1CZtNMyudMD0jJAWxpjIvUE5hCeBLhekJQCXqC9bwXJ3oKeSUO2i5Z4CmEbH7cFSq L/t22i6PhUoO7AIQxeTLV0OqcnqBaJZk7sSxpuLP6ckS5ebjS24DMGJdmOuNuASycx7x jbPprOw2MkHphP9FijzpGvHYOMPa/y5NngXMqrngPLfMH3AFZ3+29Io7Ufk8MbENWEpS g5F1Q7nmyjs1y5KLXkfVxk06ShkE0Rg4cFto28eQXn/8oEfAbyW+65S0fAkel803GPD7 dINdG3B5ISdTDJTUUHRe+uzJOIJ5KJ1iYKtbTmWq7uSBiejERW/WxEXH0U9+A5GPBjQ+ DB3w== X-Gm-Message-State: AOAM530y2lH3xO8/6qZVoTchHwqmTVeOCwA/KigYNRwmKyYh/re/VL8a uQ9K1H5caArG4NkbPeCICthQ0qRMO4Q= X-Google-Smtp-Source: ABdhPJyp/Z2AxRsCdifGdAn4QMfsg3ZxymYA0xAJX4+zB5Exag3vG2UEV0Hssv2gaPzCZqhsoDQpZQ== X-Received: by 2002:a2e:9310:: with SMTP id e16mr20419156ljh.226.1617092630884; Tue, 30 Mar 2021 01:23:50 -0700 (PDT) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id d34sm2089414lfv.102.2021.03.30.01.23.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Mar 2021 01:23:50 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Tue, 30 Mar 2021 11:23:44 +0300 Message-Id: <20210330082346.8404-3-jeebjp@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210330082346.8404-1-jeebjp@gmail.com> References: <20210330082346.8404-1-jeebjp@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH 2/4] avformat/ttmlenc: enable writing out additional header values 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" From: Jan Ekström This way the encoder may pass on the following values to the muxer: 1) Additional root "tt" element attributes, such as the subtitle canvas reference size. 2) Anything before the body element of the document, such as regions in the head element, which can configure styles. Signed-off-by: Jan Ekström --- libavcodec/ttmlenc.h | 5 +++ libavformat/ttmlenc.c | 78 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/libavcodec/ttmlenc.h b/libavcodec/ttmlenc.h index c1dd5ec990..c3bb11478d 100644 --- a/libavcodec/ttmlenc.h +++ b/libavcodec/ttmlenc.h @@ -25,4 +25,9 @@ #define TTMLENC_EXTRADATA_SIGNATURE "lavc-ttmlenc" #define TTMLENC_EXTRADATA_SIGNATURE_SIZE (sizeof(TTMLENC_EXTRADATA_SIGNATURE) - 1) +static const char ttml_default_namespacing[] = +" xmlns=\"http://www.w3.org/ns/ttml\"\n" +" xmlns:ttm=\"http://www.w3.org/ns/ttml#metadata\"\n" +" xmlns:tts=\"http://www.w3.org/ns/ttml#styling\"\n"; + #endif /* AVCODEC_TTMLENC_H */ diff --git a/libavformat/ttmlenc.c b/libavformat/ttmlenc.c index 940f8bbd4e..5d9ad6b756 100644 --- a/libavformat/ttmlenc.c +++ b/libavformat/ttmlenc.c @@ -37,18 +37,23 @@ enum TTMLPacketType { PACKET_TYPE_DOCUMENT, }; +struct TTMLHeaderParameters { + char *tt_element_params; + char *pre_body_elements; +}; + typedef struct TTMLMuxContext { enum TTMLPacketType input_type; unsigned int document_written; + struct TTMLHeaderParameters header_params; } TTMLMuxContext; static const char ttml_header_text[] = "\n" "\n" +"%s" " \n" "
\n"; @@ -72,6 +77,47 @@ static void ttml_write_time(AVIOContext *pb, const char tag[], tag, hour, min, sec, millisec); } +static int ttml_set_header_values_from_extradata( + AVCodecParameters *par, struct TTMLHeaderParameters *header_params) +{ + size_t additional_data_size = + par->extradata_size - TTMLENC_EXTRADATA_SIGNATURE_SIZE; + + if (!additional_data_size) { + header_params->tt_element_params = + av_strndup(ttml_default_namespacing, + sizeof(ttml_default_namespacing) - 1); + header_params->pre_body_elements = av_strndup("", 1); + + if (!header_params->tt_element_params || + !header_params->pre_body_elements) + return AVERROR(ENOMEM); + + return 0; + } + + { + char *value = + (char *)par->extradata + TTMLENC_EXTRADATA_SIGNATURE_SIZE; + size_t value_size = av_strnlen(value, additional_data_size); + + if (!(header_params->tt_element_params = av_strndup(value, value_size))) + return AVERROR(ENOMEM); + + additional_data_size -= value_size + 1; + value += value_size + 1; + if (additional_data_size <= 0) + return AVERROR_INVALIDDATA; + + value_size = av_strnlen(value, additional_data_size); + + if (!(header_params->pre_body_elements = av_strndup(value, value_size))) + return AVERROR(ENOMEM); + + return 0; + } +} + static int ttml_write_header(AVFormatContext *ctx) { TTMLMuxContext *ttml_ctx = ctx->priv_data; @@ -103,8 +149,21 @@ static int ttml_write_header(AVFormatContext *ctx) avpriv_set_pts_info(st, 64, 1, 1000); - if (ttml_ctx->input_type == PACKET_TYPE_PARAGRAPH) - avio_printf(pb, ttml_header_text, printed_lang); + if (ttml_ctx->input_type == PACKET_TYPE_PARAGRAPH) { + int ret = ttml_set_header_values_from_extradata( + st->codecpar, &ttml_ctx->header_params); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, + "Failed to parse TTML header values from extradata: " + "%s!\n", av_err2str(ret)); + return ret; + } + + avio_printf(pb, ttml_header_text, + ttml_ctx->header_params.tt_element_params, + printed_lang, + ttml_ctx->header_params.pre_body_elements); + } } return 0; @@ -159,6 +218,14 @@ static int ttml_write_trailer(AVFormatContext *ctx) return 0; } +static void ttml_free(AVFormatContext *ctx) +{ + TTMLMuxContext *ttml_ctx = ctx->priv_data; + + av_freep(&(ttml_ctx->header_params.tt_element_params)); + av_freep(&(ttml_ctx->header_params.pre_body_elements)); +} + AVOutputFormat ff_ttml_muxer = { .name = "ttml", .long_name = NULL_IF_CONFIG_SMALL("TTML subtitle"), @@ -171,4 +238,5 @@ AVOutputFormat ff_ttml_muxer = { .write_header = ttml_write_header, .write_packet = ttml_write_packet, .write_trailer = ttml_write_trailer, + .deinit = ttml_free, };