From patchwork Wed Apr 14 06:57:22 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: 26908 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 34C2F44A1CD for ; Wed, 14 Apr 2021 10:27:08 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 0739A68A48F; Wed, 14 Apr 2021 10:27:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f50.google.com (mail-wr1-f50.google.com [209.85.221.50]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id BDA9C68A0BE for ; Wed, 14 Apr 2021 10:27:01 +0300 (EEST) Received: by mail-wr1-f50.google.com with SMTP id 12so18832586wrz.7 for ; Wed, 14 Apr 2021 00:27:01 -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=7ZdffR6VTqK9gxQdmDxFJY8eo35zn1YjPRwkPheLq3w=; b=X1MdhE70FuHp0i0fdynCXSSFDsbopg9t5XKA4IJfk0rcu76h6DAuKhfZPikFuYGknY jpiVdso0howXqyF3GJ2Ti2+zc6ExdbL7Hk2QuKw7tRon6odJsz+XYsBIMpsBP8PcFL0A 1iZqSQSqW6snTNNQlYV4CWauESyieSuxx2uxIk8tc2ff97lNoOdW4NNIbs7U485seySG yVzpMGinlVQrd9x6vNRgyrzfr1/AeK6xsG0qRYF0RwQJj3gx23PCluCQJjziXfM+CRww KieqrtqqaZVwoAS+A6DqvodBoBDXqhGb8LCI4oYo8Gt7ag4a5EI+RVhlIwM9NanRcoK4 VENA== 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=7ZdffR6VTqK9gxQdmDxFJY8eo35zn1YjPRwkPheLq3w=; b=h7R6W+kCu6saxfwEWTpWAqhKDlgmW9NAFQKxPOh3CwnKPrNyhYvMj3++UP8drQmOzv NeZk3eIiKZkitVl/jw61rrL4JXYnfG2KcSn+ZXqtWwEbOJ4gMcD9aJVsARCR9L6Nry0h N2dtH5NGrPSTH6BOGpU7vyU+QtpDOJsDcFprtELtArlOMqphdPxSGXNEkMycF2aIpgh3 ttEYWkZUsY6K/A5NFPGJzdfCcdySB2bVsZrNutkalaoeBU5NkC/CETVlBTyStOlbyaMy LbYorC/iNOCH1Nki7xsU/t9wCcOrWDtQkAL0NVshBf/UX4cGOnzP0DnLpY+YefFFonI+ oVKw== X-Gm-Message-State: AOAM531U7arctx3HQJ3Sh22ordcWmeO2LPG7xts3dujrhDhPqblQDbVk DMq6jU2iGtb7xgxigSeFYJDZWoLBrUs= X-Google-Smtp-Source: ABdhPJxhoWJoO92IHlv3gDuZje8vh4j+SEt6Wza+wfh1I3vPbqLx17f55U6CotATLbZ17dITy17H8g== X-Received: by 2002:a19:5011:: with SMTP id e17mr2209991lfb.536.1618383449110; Tue, 13 Apr 2021 23:57:29 -0700 (PDT) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id w5sm4960167ljo.11.2021.04.13.23.57.28 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 23:57:28 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 14 Apr 2021 09:57:22 +0300 Message-Id: <20210414065725.8828-2-jeebjp@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210414065725.8828-1-jeebjp@gmail.com> References: <20210414065725.8828-1-jeebjp@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 1/4] avcodec/ttmlenc: split header writing into its own function 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 Signed-off-by: Jan Ekström --- libavcodec/ttmlenc.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c index 3972b4368c..e3c155fdd1 100644 --- a/libavcodec/ttmlenc.c +++ b/libavcodec/ttmlenc.c @@ -173,16 +173,8 @@ static av_cold int ttml_encode_close(AVCodecContext *avctx) return 0; } -static av_cold int ttml_encode_init(AVCodecContext *avctx) +static int ttml_write_header_content(AVCodecContext *avctx) { - TTMLContext *s = avctx->priv_data; - - s->avctx = avctx; - - if (!(s->ass_ctx = ff_ass_split(avctx->subtitle_header))) { - return AVERROR_INVALIDDATA; - } - if (!(avctx->extradata = av_mallocz(TTMLENC_EXTRADATA_SIGNATURE_SIZE + 1 + AV_INPUT_BUFFER_PADDING_SIZE))) { return AVERROR(ENOMEM); @@ -192,8 +184,25 @@ static av_cold int ttml_encode_init(AVCodecContext *avctx) memcpy(avctx->extradata, TTMLENC_EXTRADATA_SIGNATURE, TTMLENC_EXTRADATA_SIGNATURE_SIZE); + return 0; +} + +static av_cold int ttml_encode_init(AVCodecContext *avctx) +{ + TTMLContext *s = avctx->priv_data; + int ret = AVERROR_BUG; + s->avctx = avctx; + av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); + if (!(s->ass_ctx = ff_ass_split(avctx->subtitle_header))) { + return AVERROR_INVALIDDATA; + } + + if ((ret = ttml_write_header_content(avctx)) < 0) { + return ret; + } + return 0; } From patchwork Wed Apr 14 06:57:23 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: 26904 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 9DB3944A19D for ; Wed, 14 Apr 2021 10:06:00 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 766A868A761; Wed, 14 Apr 2021 10:06:00 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-wr1-f51.google.com (mail-wr1-f51.google.com [209.85.221.51]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 512C168A71D for ; Wed, 14 Apr 2021 10:05:54 +0300 (EEST) Received: by mail-wr1-f51.google.com with SMTP id j5so17790775wrn.4 for ; Wed, 14 Apr 2021 00:05:54 -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=W2muOHdSrbSS04FtduUOCnHO6V4VHxF9ge7uIw5Jg+8=; b=rI9IM4af2rP3ETyPPCoyq/T4ghNEw6pILkvMNZlXfZzapvzhpDK8huoyw4C5CEBC2/ kLBRtXvxjjF3VwXQFufd91BCvesmvoVu85rBL3jm8DwBiQ6oPcS4hoQ99xF9Sz1LqJ6r uMUnTEGJ7b2Kdu4orcXaTFCIFvJyvuu5HEd2MTubelA8taYqO6ubjYNMGp5JGQCMH9Q1 mceIRwxlRUpiusUHqJOAPkav+4JPlHu1U9k1xn1nM4km4yr2AMqWguN3wpCvZh3JgaOC NPgI0cIWd5LSCdobtZK8yjanf9c5om58ZKCvQTdpzN9kvlM2rZML7MNw4PiTiEmV6hb8 grgA== 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=W2muOHdSrbSS04FtduUOCnHO6V4VHxF9ge7uIw5Jg+8=; b=sCS3lEw0n3raYilgKJ6583chtjkj9yzAwCxkVY8Zz1zl9ZND/BpNFtl0nCilEFceMB NGkmOjz+Nj0dZqKpGjmwJxGF2un4TIhxvN5MgZqUqw0n5IofEcHup4K7gQt2Keaqfd/J LP5USzcC/09kUsoBWPl+enm8A6hKqpuPh1aj3Pe5K5glGUXlbFZAYVjI3nJCIBUy9LMK h82qf4EcRvdC4O2eLmo24qATyrkCsbB2vrkO1Y0lnpcQva5kdpvDPorLdhm8lKL21bb9 NQFvwdBkmMNLDSWmhSuX8Ik7cugQw1kNwPov0hWWEVcnvA7PhWmuz3iTqGtjOkfV9Xxm lWkg== X-Gm-Message-State: AOAM5316I2zfJYJTP4aIkLSeMnpdBOMmXbBoxlrthN64Tzi14K3ao/3W 9ICukaxYE8yMZd461wx08wQ15usWCHY= X-Google-Smtp-Source: ABdhPJy5FKkv+9shvt7iIBB5B73QRocqoj3lMgDBsw5je1M1lQ9iFy8MvbnfClx2czG4iIuBfj9ABg== X-Received: by 2002:a19:3849:: with SMTP id d9mr6410253lfj.388.1618383449802; Tue, 13 Apr 2021 23:57:29 -0700 (PDT) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id w5sm4960167ljo.11.2021.04.13.23.57.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 23:57:29 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 14 Apr 2021 09:57:23 +0300 Message-Id: <20210414065725.8828-3-jeebjp@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210414065725.8828-1-jeebjp@gmail.com> References: <20210414065725.8828-1-jeebjp@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 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 | 70 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 70 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..34a0107a14 100644 --- a/libavformat/ttmlenc.c +++ b/libavformat/ttmlenc.c @@ -37,6 +37,11 @@ enum TTMLPacketType { PACKET_TYPE_DOCUMENT, }; +struct TTMLHeaderParameters { + const char *tt_element_params; + const char *pre_body_elements; +}; + typedef struct TTMLMuxContext { enum TTMLPacketType input_type; unsigned int document_written; @@ -45,10 +50,9 @@ typedef struct TTMLMuxContext { static const char ttml_header_text[] = "\n" "\n" +"%s" " \n" "
\n"; @@ -72,6 +76,48 @@ 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; + char *value = + (char *)par->extradata + TTMLENC_EXTRADATA_SIGNATURE_SIZE; + size_t value_size = av_strnlen(value, additional_data_size); + struct TTMLHeaderParameters local_params = { 0 }; + + if (!additional_data_size) { + // simple case, we don't have to go through local_params and just + // set default fall-back values (for old extradata format). + header_params->tt_element_params = ttml_default_namespacing; + header_params->pre_body_elements = ""; + + return 0; + } + + if (value_size == additional_data_size || + value[value_size] != '\0') + return AVERROR_INVALIDDATA; + + local_params.tt_element_params = value; + + additional_data_size -= value_size + 1; + value += value_size + 1; + if (!additional_data_size) + return AVERROR_INVALIDDATA; + + value_size = av_strnlen(value, additional_data_size); + if (value_size == additional_data_size || + value[value_size] != '\0') + return AVERROR_INVALIDDATA; + + local_params.pre_body_elements = value; + + *header_params = local_params; + + return 0; +} + static int ttml_write_header(AVFormatContext *ctx) { TTMLMuxContext *ttml_ctx = ctx->priv_data; @@ -103,8 +149,22 @@ 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) { + struct TTMLHeaderParameters header_params; + int ret = ttml_set_header_values_from_extradata( + st->codecpar, &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, + header_params.tt_element_params, + printed_lang, + header_params.pre_body_elements); + } } return 0; From patchwork Wed Apr 14 06:57:24 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: 26909 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 70BBA44A1CD for ; Wed, 14 Apr 2021 10:27:37 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 5193968A848; Wed, 14 Apr 2021 10:27:37 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lj1-f172.google.com (mail-lj1-f172.google.com [209.85.208.172]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 6A78A689D24 for ; Wed, 14 Apr 2021 10:27:31 +0300 (EEST) Received: by mail-lj1-f172.google.com with SMTP id l22so14857384ljc.9 for ; Wed, 14 Apr 2021 00:27:31 -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=IgaAJeLyzFTfid9BajkQMpcllUF1M5KyAjay51WfXio=; b=s9Vqqs7R02mSiUYR2dSKGhKqTeAFxKwciifOoMun4msnVzMG/F5YnjF3vAfBW2GUfy GwCPOCOXFiZVxesw3YNfR2yygsWBBSuyy18UkYjMSJ6gvKbvc1loyWY3FNRcnbWh8UCC 4O+W0z3+U6vJr1b4bwueWPfaTM1+HKJjaG/Ur5WYehvFD8a64vQWmnJw5wGZu8jqBLJj GHUQa0k22fXsFwDEwT5aU6UThQzaS9mO8R5bMzBlNf5xLesMiAH4IZRVG4Pm6xiCgSsj rDFaJrBal0pO8mjAUUeIv+TFJsJhAXafxtCE9alfxXVQQMbPN8Oxr17y7RkMIGFqPPYb vBRQ== 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=IgaAJeLyzFTfid9BajkQMpcllUF1M5KyAjay51WfXio=; b=A3tOY9d8Ax6Bd5qNxunLTO3o/ikpDBOJc1vJdIeEUjG83j6TppI2VZwyvh6Idclwai nZI+NcusWrTzh66JIH7CTcuqBAaUJIOcGOIzPQTH4dfgBkUqK8V4Omlz0ToJ8hGqrv0r gTLSN4rsg6SXxw/Wlun0+W81BIOGoA2UV1fvO9Mrw1hz6NIrrhZB/LDuTpqxnsqq4PI3 BNZ3kAbUS0awvw86SrREi4XpaS0wWA3tUa4MvLwX+PMkZ8wAd9rjXJbsjHX22oV7reL2 crn3Iix03KxqAImTzALhS0l+YlpHTveQb3A1nRo6Wv1JuLQbmoKt5k6h6G74S0X1hCfq 0yqQ== X-Gm-Message-State: AOAM531ddw4HmZoJFvOQtbWNnb8YYSrT0WvVIvqYkE2m6YLWnPd+bad3 qCJBzlySI9QS03eNyat99q1X4atJZGs= X-Google-Smtp-Source: ABdhPJxoUn6elmrtHZ7qCM3LeBR2BedPb4k/8ciNvaX+gJITzHLONv4Vzna9nJDYb5h1+MDBGuTICg== X-Received: by 2002:a05:6512:3d20:: with SMTP id d32mr14948663lfv.163.1618383450663; Tue, 13 Apr 2021 23:57:30 -0700 (PDT) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id w5sm4960167ljo.11.2021.04.13.23.57.29 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 23:57:30 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 14 Apr 2021 09:57:24 +0300 Message-Id: <20210414065725.8828-4-jeebjp@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210414065725.8828-1-jeebjp@gmail.com> References: <20210414065725.8828-1-jeebjp@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 3/4] avcodec/ttmlenc: add initial support for regions and styles 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 Attempts to utilize the TTML cell resolution as a mapping to the reference resolution, and maps font size to cell size. Additionally sets the display and text alignment according to the ASS alignment number. Signed-off-by: Jan Ekström --- libavcodec/ttmlenc.c | 210 ++++++++++++++++++++++++++++++++++--- libavcodec/ttmlenc.h | 3 +- tests/ref/fate/sub-ttmlenc | 86 ++++++++------- 3 files changed, 247 insertions(+), 52 deletions(-) diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c index e3c155fdd1..c190356683 100644 --- a/libavcodec/ttmlenc.c +++ b/libavcodec/ttmlenc.c @@ -100,20 +100,33 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf, dialog = ff_ass_split_dialog(s->ass_ctx, ass, 0, &num); for (; dialog && num--; dialog++) { - int ret = ff_ass_split_override_codes(&ttml_callbacks, s, - dialog->text); - int log_level = (ret != AVERROR_INVALIDDATA || - avctx->err_recognition & AV_EF_EXPLODE) ? - AV_LOG_ERROR : AV_LOG_WARNING; + if (dialog->style) { + av_bprintf(&s->buffer, "buffer, dialog->style, NULL, + AV_ESCAPE_MODE_XML, + AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + av_bprintf(&s->buffer, "\">"); + } - if (ret < 0) { - av_log(avctx, log_level, - "Splitting received ASS dialog failed: %s\n", - av_err2str(ret)); + { + int ret = ff_ass_split_override_codes(&ttml_callbacks, s, + dialog->text); + int log_level = (ret != AVERROR_INVALIDDATA || + avctx->err_recognition & AV_EF_EXPLODE) ? + AV_LOG_ERROR : AV_LOG_WARNING; - if (log_level == AV_LOG_ERROR) - return ret; + if (ret < 0) { + av_log(avctx, log_level, + "Splitting received ASS dialog failed: %s\n", + av_err2str(ret)); + + if (log_level == AV_LOG_ERROR) + return ret; + } } + + if (dialog->style) + av_bprintf(&s->buffer, ""); } } else { #endif @@ -121,6 +134,14 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf, if (!dialog) return AVERROR(ENOMEM); + if (dialog->style) { + av_bprintf(&s->buffer, "buffer, dialog->style, NULL, + AV_ESCAPE_MODE_XML, + AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + av_bprintf(&s->buffer, "\">"); + } + { int ret = ff_ass_split_override_codes(&ttml_callbacks, s, dialog->text); @@ -140,6 +161,9 @@ static int ttml_encode_frame(AVCodecContext *avctx, uint8_t *buf, } } + if (dialog->style) + av_bprintf(&s->buffer, ""); + ff_ass_free_dialog(&dialog); } #if FF_API_ASS_TIMING @@ -173,17 +197,175 @@ static av_cold int ttml_encode_close(AVCodecContext *avctx) return 0; } +static const char *ttml_get_display_alignment(int alignment) +{ + switch (alignment) { + case 1: + case 2: + case 3: + return "after"; + case 4: + case 5: + case 6: + return "center"; + case 7: + case 8: + case 9: + return "before"; + default: + return NULL; + } +} + +static const char *ttml_get_text_alignment(int alignment) +{ + switch (alignment) { + case 1: + case 4: + case 7: + return "left"; + case 2: + case 5: + case 8: + return "center"; + case 3: + case 6: + case 9: + return "right"; + default: + return NULL; + } +} + +static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, + ASSStyle *style) +{ + const char *display_alignment = NULL; + const char *text_alignment = NULL; + + if (!style) + return AVERROR_INVALIDDATA; + + if (!style->name) { + av_log(avctx, AV_LOG_ERROR, "Subtitle style name not set!\n"); + return AVERROR_INVALIDDATA; + } + + if (style->font_size < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid font size for TTML: %d!\n", + style->font_size); + return AVERROR_INVALIDDATA; + } + + display_alignment = ttml_get_display_alignment(style->alignment); + text_alignment = ttml_get_text_alignment(style->alignment); + if (!display_alignment || !text_alignment) { + av_log(avctx, AV_LOG_ERROR, + "Failed to convert ASS style alignment %d of style %s to " + "TTML display and text alignment!\n", + style->alignment, + style->name); + return AVERROR_INVALIDDATA; + } + + av_bprintf(buf, " name, NULL, AV_ESCAPE_MODE_XML, + AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + av_bprintf(buf, "\"\n"); + + av_bprintf(buf, " tts:displayAlign=\""); + av_bprint_escape(buf, display_alignment, NULL, AV_ESCAPE_MODE_XML, + AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + av_bprintf(buf, "\"\n"); + + av_bprintf(buf, " tts:textAlign=\""); + av_bprint_escape(buf, text_alignment, NULL, AV_ESCAPE_MODE_XML, + AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + av_bprintf(buf, "\"\n"); + + // if we set cell resolution to our script reference resolution, + // then a single line is a single "point" on our canvas. Thus, by setting + // our font size to font size in cells, we should gain a similar enough + // scale without resorting to explicit pixel based font sizing, which is + // frowned upon in the TTML community. + av_bprintf(buf, " tts:fontSize=\"%dc\"\n", + style->font_size); + + if (style->font_name) { + av_bprintf(buf, " tts:fontFamily=\""); + av_bprint_escape(buf, style->font_name, NULL, AV_ESCAPE_MODE_XML, + AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); + av_bprintf(buf, "\"\n"); + } + + av_bprintf(buf, " tts:overflow=\"visible\" />\n"); + + return 0; +} + static int ttml_write_header_content(AVCodecContext *avctx) { - if (!(avctx->extradata = av_mallocz(TTMLENC_EXTRADATA_SIGNATURE_SIZE + - 1 + AV_INPUT_BUFFER_PADDING_SIZE))) { + TTMLContext *s = avctx->priv_data; + ASS *ass = (ASS *)s->ass_ctx; + ASSScriptInfo script_info = ass->script_info; + const size_t base_extradata_size = TTMLENC_EXTRADATA_SIGNATURE_SIZE + 1 + + AV_INPUT_BUFFER_PADDING_SIZE; + size_t additional_extradata_size = 0; + + if (script_info.play_res_x <= 0 || script_info.play_res_y <= 0) { + av_log(avctx, AV_LOG_ERROR, + "Invalid subtitle reference resolution %dx%d!\n", + script_info.play_res_x, script_info.play_res_y); + return AVERROR_INVALIDDATA; + } + + // write the first string in extradata, attributes in the base "tt" element. + av_bprintf(&s->buffer, ttml_default_namespacing); + // the cell resolution is in character cells, so not exactly 1:1 against + // a pixel based resolution, but as the tts:extent in the root + // "tt" element is frowned upon (and disallowed in the EBU-TT profile), + // we mimic the reference resolution by setting it as the cell resolution. + av_bprintf(&s->buffer, " ttp:cellResolution=\"%d %d\"\n", + script_info.play_res_x, script_info.play_res_y); + av_bprint_chars(&s->buffer, '\0', 1); + + // write the second string in extradata, head element containing the styles + av_bprintf(&s->buffer, " \n"); + av_bprintf(&s->buffer, " \n"); + + for (int i = 0; i < ass->styles_count; i++) { + ASSStyle *style = &ass->styles[i]; + int ret = ttml_write_region(avctx, &s->buffer, style); + if (ret < 0) + return ret; + } + + av_bprintf(&s->buffer, " \n"); + av_bprintf(&s->buffer, " \n"); + av_bprint_chars(&s->buffer, '\0', 1); + + if (!av_bprint_is_complete(&s->buffer)) { return AVERROR(ENOMEM); } - avctx->extradata_size = TTMLENC_EXTRADATA_SIGNATURE_SIZE; + additional_extradata_size = s->buffer.len; + + if (!(avctx->extradata = + av_mallocz(base_extradata_size + additional_extradata_size))) { + return AVERROR(ENOMEM); + } + + avctx->extradata_size = + TTMLENC_EXTRADATA_SIGNATURE_SIZE + additional_extradata_size; memcpy(avctx->extradata, TTMLENC_EXTRADATA_SIGNATURE, TTMLENC_EXTRADATA_SIGNATURE_SIZE); + if (additional_extradata_size) + memcpy(avctx->extradata + TTMLENC_EXTRADATA_SIGNATURE_SIZE, + s->buffer.str, additional_extradata_size); + + av_bprint_clear(&s->buffer); + return 0; } diff --git a/libavcodec/ttmlenc.h b/libavcodec/ttmlenc.h index c3bb11478d..467f35c7a6 100644 --- a/libavcodec/ttmlenc.h +++ b/libavcodec/ttmlenc.h @@ -28,6 +28,7 @@ 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"; +" xmlns:tts=\"http://www.w3.org/ns/ttml#styling\"\n" +" xmlns:ttp=\"http://www.w3.org/ns/ttml#parameter\"\n"; #endif /* AVCODEC_TTMLENC_H */ diff --git a/tests/ref/fate/sub-ttmlenc b/tests/ref/fate/sub-ttmlenc index 51eab97817..6d0a8067fc 100644 --- a/tests/ref/fate/sub-ttmlenc +++ b/tests/ref/fate/sub-ttmlenc @@ -3,120 +3,132 @@ xmlns="http://www.w3.org/ns/ttml" xmlns:ttm="http://www.w3.org/ns/ttml#metadata" xmlns:tts="http://www.w3.org/ns/ttml#styling" + xmlns:ttp="http://www.w3.org/ns/ttml#parameter" + ttp:cellResolution="384 288" xml:lang=""> + + + + +

Don't show this text it may be used to insert hidden data

+ end="00:00:00.000">Don't show this text it may be used to insert hidden data

SubRip subtitles capability tester 1.3o by ale5000
Use VLC 1.1 or higher as reference for most things and MPC Home Cinema for others
This text should be blue
This text should be red
This text should be black
If you see this with the normal font, the player don't (fully) support font face

+ end="00:00:04.500">SubRip subtitles capability tester 1.3o by ale5000
Use VLC 1.1 or higher as reference for most things and MPC Home Cinema for others
This text should be blue
This text should be red
This text should be black
If you see this with the normal font, the player don't (fully) support font face

Hidden

+ end="00:00:04.500">Hidden

This text should be small
This text should be normal
This text should be big

+ end="00:00:07.500">This text should be small
This text should be normal
This text should be big

This should be an E with an accent: È
日本語
This text should be bold, italics and underline
This text should be small and green
This text should be small and red
This text should be big and brown

+ end="00:00:11.500">This should be an E with an accent: È
日本語
This text should be bold, italics and underline
This text should be small and green
This text should be small and red
This text should be big and brown

This line should be bold
This line should be italics
This line should be underline
This line should be strikethrough
Both lines
should be underline

+ end="00:00:14.500">This line should be bold
This line should be italics
This line should be underline
This line should be strikethrough
Both lines
should be underline

>
It would be a good thing to
hide invalid html tags that are closed and show the text in them
but show un-closed invalid html tags
Show not opened tags
<

+ end="00:00:17.500">>
It would be a good thing to
hide invalid html tags that are closed and show the text in them
but show un-closed invalid html tags
Show not opened tags
<

and also
hide invalid html tags with parameters that are closed and show the text in them
but show un-closed invalid html tags
This text should be showed underlined without problems also: 2<3,5>1,4<6
This shouldn't be underlined

+ end="00:00:20.500">and also
hide invalid html tags with parameters that are closed and show the text in them
but show un-closed invalid html tags
This text should be showed underlined without problems also: 2<3,5>1,4<6
This shouldn't be underlined

This text should be in the normal position...

+ end="00:00:21.500">This text should be in the normal position...

This text should NOT be in the normal position

+ end="00:00:22.500">This text should NOT be in the normal position

Implementation is the same of the ASS tag
This text should be at the
top and horizontally centered

+ end="00:00:24.500">Implementation is the same of the ASS tag
This text should be at the
top and horizontally centered

This text should be at the
middle and horizontally centered

+ end="00:00:24.500">This text should be at the
middle and horizontally centered

This text should be at the
bottom and horizontally centered

+ end="00:00:24.500">This text should be at the
bottom and horizontally centered

This text should be at the
top and horizontally at the left

+ end="00:00:26.500">This text should be at the
top and horizontally at the left

This text should be at the
middle and horizontally at the left
(The second position must be ignored)

+ end="00:00:26.500">This text should be at the
middle and horizontally at the left
(The second position must be ignored)

This text should be at the
bottom and horizontally at the left

+ end="00:00:26.500">This text should be at the
bottom and horizontally at the left

This text should be at the
top and horizontally at the right

+ end="00:00:28.500">This text should be at the
top and horizontally at the right

This text should be at the
middle and horizontally at the right

+ end="00:00:28.500">This text should be at the
middle and horizontally at the right

This text should be at the
bottom and horizontally at the right

+ end="00:00:28.500">This text should be at the
bottom and horizontally at the right

This could be the most difficult thing to implement

+ end="00:00:31.500">This could be the most difficult thing to implement

First text

+ end="00:00:50.500">First text

Second, it shouldn't overlap first

+ end="00:00:35.500">Second, it shouldn't overlap first

Third, it should replace second

+ end="00:00:37.500">Third, it should replace second

Fourth, it shouldn't overlap first and third

+ end="00:00:50.500">Fourth, it shouldn't overlap first and third

Fifth, it should replace third

+ end="00:00:45.500">Fifth, it should replace third

Sixth, it shouldn't be
showed overlapped

+ end="00:00:50.500">Sixth, it shouldn't be
showed overlapped

TEXT 1 (bottom)

+ end="00:00:52.500">TEXT 1 (bottom)

text 2

+ end="00:00:52.500">text 2

Hide these tags:
also hide these tags:
but show this: {normal text}

+ end="00:00:54.500">Hide these tags:
also hide these tags:
but show this: {normal text}


\ N is a forced line break
\ h is a hard space
Normal spaces at the start and at the end of the line are trimmed while hard spaces are not trimmed.
The\hline\hwill\hnever\hbreak\hautomatically\hright\hbefore\hor\hafter\ha\hhard\hspace.\h:-D

+ end="00:01:00.500">
\ N is a forced line break
\ h is a hard space
Normal spaces at the start and at the end of the line are trimmed while hard spaces are not trimmed.
The\hline\hwill\hnever\hbreak\hautomatically\hright\hbefore\hor\hafter\ha\hhard\hspace.\h:-D


\h\h\h\h\hA (05 hard spaces followed by a letter)
A (Normal spaces followed by a letter)
A (No hard spaces followed by a letter)

+ end="00:00:56.500">
\h\h\h\h\hA (05 hard spaces followed by a letter)
A (Normal spaces followed by a letter)
A (No hard spaces followed by a letter)

\h\h\h\h\hA (05 hard spaces followed by a letter)
A (Normal spaces followed by a letter)
A (No hard spaces followed by a letter)
Show this: \TEST and this: \-)

+ end="00:00:58.500">\h\h\h\h\hA (05 hard spaces followed by a letter)
A (Normal spaces followed by a letter)
A (No hard spaces followed by a letter)
Show this: \TEST and this: \-)


A letter followed by 05 hard spaces: A\h\h\h\h\h
A letter followed by normal spaces: A
A letter followed by no hard spaces: A
05 hard spaces between letters: A\h\h\h\h\hA
5 normal spaces between letters: A A

^--Forced line break

+ end="00:01:00.500">
A letter followed by 05 hard spaces: A\h\h\h\h\h
A letter followed by normal spaces: A
A letter followed by no hard spaces: A
05 hard spaces between letters: A\h\h\h\h\hA
5 normal spaces between letters: A A

^--Forced line break

Both line should be strikethrough,
yes.
Correctly closed tags
should be hidden.

+ end="00:01:02.500">Both line should be strikethrough,
yes.
Correctly closed tags
should be hidden.

It shouldn't be strikethrough,
not opened tag showed as text.
Not opened tag showed as text.

+ end="00:01:04.500">It shouldn't be strikethrough,
not opened tag showed as text.
Not opened tag showed as text.

Three lines should be strikethrough,
yes.
Not closed tags showed as text

+ end="00:01:06.500">Three lines should be strikethrough,
yes.
Not closed tags showed as text

Both line should be strikethrough but
the wrong closing tag should be showed

+ end="00:01:08.500">Both line should be strikethrough but
the wrong closing tag should be showed

From patchwork Wed Apr 14 06:57:25 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: 26906 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 8DF1344AC37 for ; Wed, 14 Apr 2021 10:24:57 +0300 (EEST) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 6AE8268A753; Wed, 14 Apr 2021 10:24:57 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id A749668A753 for ; Wed, 14 Apr 2021 10:24:50 +0300 (EEST) Received: by mail-ed1-f49.google.com with SMTP id w23so22422683edx.7 for ; Wed, 14 Apr 2021 00:24:50 -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=Z2qosFgignxH+dPH5kHeN/5F3DyD6fB7kvD/8C849l8=; b=Y1nkgp38ULGTl0UuPXHHVdWvhVqzGx3zah4JO4NC48UzlYvHS8S8Iswg6G86xIrtAC /OgHK9VWvxNA41AqLDzm6/Vma3Dq9hzWf+KPi29RIny4pd9EEKDzKL+sPoXKQuOpE/Bo SzowRP2St/CU+itdkNvHzGKmm3qWdcoWUiw5Buhi68mY8ApbawjLPYqTOYZ4kgtF7Fom uk0+x/+AZjBOtcnbaXvElyzh/uoO/QbKIH2jMvmwX93WkoMHco77aX+dTCMoVPFT/IDz aFKAO7GZaUPdoBMMDmjRHbLx4z457DdQ23tV0Ewh5vj+k3Oa02wJWnxQVpNBcEjhCSuS Qlbg== 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=Z2qosFgignxH+dPH5kHeN/5F3DyD6fB7kvD/8C849l8=; b=kfI7+DotjSZ73ehiVBCOTt7XFmiB8exc5fJCLwb1vTq++2a0Ey2/vmt/h4rZBS53jQ q8sY2inc8/TpTpH9GcTRZ4fduG3seN04sk7JQxw7rXUU08omJs1UTtZBHWSckXXTCTro o55dwiecB3nVPAmJkhGS6bbZ4Ml8HEUa+t0xkMqan73255nrhFC74rDyVZ6816LbezD1 L65ZLggyGu0hMz+GcYtNB8lOXYrg9FI2wAgd50AeKC7PiRRT1+n/s8zZj8NbRQgDlnQT tAAdFrQD+t9REbaHmf5EqM0QW5/+d40OThm0yZAp/K9zxGl9P/eewtnAX3ssw9obNhpo IXYQ== X-Gm-Message-State: AOAM533f6AO5TiV9T71R4GExbAHm7Hq9hnGWaAzFAQHj0xpwOthZ4aXu +ib7YxUBo/AnQj0z5LM3Z18E9nmOfjo= X-Google-Smtp-Source: ABdhPJwGo4roVKLBSRERbQ4pse+fJ75lqdFSHleZUDmCyJdiYZjtLX2NFr7V/PH+Ksh9mBKOBNBekA== X-Received: by 2002:a19:4f54:: with SMTP id a20mr11434455lfk.212.1618383451406; Tue, 13 Apr 2021 23:57:31 -0700 (PDT) Received: from localhost.localdomain (91-159-194-103.elisa-laajakaista.fi. [91.159.194.103]) by smtp.gmail.com with ESMTPSA id w5sm4960167ljo.11.2021.04.13.23.57.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 23:57:30 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Wed, 14 Apr 2021 09:57:25 +0300 Message-Id: <20210414065725.8828-5-jeebjp@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210414065725.8828-1-jeebjp@gmail.com> References: <20210414065725.8828-1-jeebjp@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v2 4/4] avcodec/ttmlenc: add support for region positioning and sizing 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 The ASS margins are utilized to generate percentual values, as the usage of cell-based sizing and offsetting seems to be not too well supported by renderers. Signed-off-by: Jan Ekström --- libavcodec/ttmlenc.c | 44 ++++++++++++++++++++++++++++++++++++-- tests/ref/fate/sub-ttmlenc | 2 ++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c index c190356683..eab6240a75 100644 --- a/libavcodec/ttmlenc.c +++ b/libavcodec/ttmlenc.c @@ -237,11 +237,35 @@ static const char *ttml_get_text_alignment(int alignment) } } +static void ttml_get_origin(ASSScriptInfo script_info, ASSStyle *style, + int *origin_left, int *origin_top) +{ + *origin_left = av_rescale(style->margin_l, 100, script_info.play_res_x); + *origin_top = + av_rescale((style->alignment >= 7) ? style->margin_v : 0, + 100, script_info.play_res_y); +} + +static void ttml_get_extent(ASSScriptInfo script_info, ASSStyle *style, + int *width, int *height) +{ + *width = av_rescale(script_info.play_res_x - style->margin_r, + 100, script_info.play_res_x); + *height = av_rescale((style->alignment <= 3) ? + script_info.play_res_y - style->margin_v : + script_info.play_res_y, + 100, script_info.play_res_y); +} + static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, - ASSStyle *style) + ASSScriptInfo script_info, ASSStyle *style) { const char *display_alignment = NULL; const char *text_alignment = NULL; + int origin_left = 0; + int origin_top = 0; + int width = 0; + int height = 0; if (!style) return AVERROR_INVALIDDATA; @@ -257,6 +281,14 @@ static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, return AVERROR_INVALIDDATA; } + if (style->margin_l < 0 || style->margin_r < 0 || style->margin_v < 0) { + av_log(avctx, AV_LOG_ERROR, + "One or more negative margin values in subtitle style: " + "left: %d, right: %d, vertical: %d!\n", + style->margin_l, style->margin_r, style->margin_v); + return AVERROR_INVALIDDATA; + } + display_alignment = ttml_get_display_alignment(style->alignment); text_alignment = ttml_get_text_alignment(style->alignment); if (!display_alignment || !text_alignment) { @@ -268,11 +300,19 @@ static int ttml_write_region(AVCodecContext *avctx, AVBPrint *buf, return AVERROR_INVALIDDATA; } + ttml_get_origin(script_info, style, &origin_left, &origin_top); + ttml_get_extent(script_info, style, &width, &height); + av_bprintf(buf, " name, NULL, AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); av_bprintf(buf, "\"\n"); + av_bprintf(buf, " tts:origin=\"%d%% %d%%\"\n", + origin_left, origin_top); + av_bprintf(buf, " tts:extent=\"%d%% %d%%\"\n", + width, height); + av_bprintf(buf, " tts:displayAlign=\""); av_bprint_escape(buf, display_alignment, NULL, AV_ESCAPE_MODE_XML, AV_ESCAPE_FLAG_XML_DOUBLE_QUOTES); @@ -335,7 +375,7 @@ static int ttml_write_header_content(AVCodecContext *avctx) for (int i = 0; i < ass->styles_count; i++) { ASSStyle *style = &ass->styles[i]; - int ret = ttml_write_region(avctx, &s->buffer, style); + int ret = ttml_write_region(avctx, &s->buffer, script_info, style); if (ret < 0) return ret; } diff --git a/tests/ref/fate/sub-ttmlenc b/tests/ref/fate/sub-ttmlenc index 6d0a8067fc..4df8f8796f 100644 --- a/tests/ref/fate/sub-ttmlenc +++ b/tests/ref/fate/sub-ttmlenc @@ -9,6 +9,8 @@