From patchwork Mon Apr 26 09:34: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: 27416 Delivered-To: ffmpegpatchwork2@gmail.com Received: by 2002:a6b:5014:0:0:0:0:0 with SMTP id e20csp3807530iob; Mon, 26 Apr 2021 02:42:12 -0700 (PDT) X-Google-Smtp-Source: ABdhPJybKezWtrLZwVa7vrQGmHtVOp5J6DQBUAtoKAcmAA3Vd7nRKlV8s8qG2/RVRx+teGnbWZEN X-Received: by 2002:a17:906:87d3:: with SMTP id zb19mr6052579ejb.342.1619430132313; Mon, 26 Apr 2021 02:42:12 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1619430132; cv=none; d=google.com; s=arc-20160816; b=nK8wjiYXQoxYgeG8Sr+upQIo3TrueDAH+QHCm40+WNJVBBU0mYhOD3gc8EQ8g+Oo3t wPkWK41cdeJ2mCJvI6DC5jFDs+TYtir9lXlVOXVo/nhv7CqM4Uy5I/Hsr2O+TfGENv/0 TlLbRXzKl1qs0WcKWZJVOE3+2rY4sUXzZfqhcDzCfeGp5JNJN5tYXjuCFKiPLXri4xtJ m4RyudmchNLiQHS7kDTFlGimKm0wI2SnVN9hbgOVg3oJja3/ZVTiS/2qpFW2JsyJLAsY XjyykIoe0j6D3La/lla9DKJiz2968iXKpIrePa/KUcfDf/99GEmHzVtmsq9KVWbb9TYh WLfg== 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=nkgLrp4FFz0V9KQlxc8EkOxd2Mfkv/sadV1/7eHToVA=; b=vO71YhJkeXT//nwxwHq7H9dTKw38lY+BwLH4wK1FK+OgbeLp0hiQQwqYc1xyYT51AS G2AJL1zakDHvfMZrUgkg+nuVLONKc5N+M5fYOgy6mPkykvI6vDX0xzY/7a2aX19kxFa4 cKcB9ImWOPmewuRWSwTBl7jcansSo1yzmBsPKG6F9VNlFoDxYsdIRA7U4qZVgvkHPRxp EdtQQ99k2zA6AxibXPYpHdVUnnmyOsieM8kqT7MO1xErTZgGsVOkOJdze7l2/zoWUrcK OM7gHWzDaBU2Q/FTapQjFu3kGK7L0o5o71U48Be7wQMp5+6k8IzYjOqIVpDTFIdi6HaQ W+cQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@gmail.com header.s=20161025 header.b=Zb4+kPdl; 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 d12si14215031ejj.422.2021.04.26.02.42.12; Mon, 26 Apr 2021 02:42:12 -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=20161025 header.b=Zb4+kPdl; 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 CA345689B83; Mon, 26 Apr 2021 12:42:08 +0300 (EEST) X-Original-To: ffmpeg-devel@ffmpeg.org Delivered-To: ffmpeg-devel@ffmpeg.org Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 4B08B6899BB for ; Mon, 26 Apr 2021 12:42:06 +0300 (EEST) Received: by mail-lf1-f49.google.com with SMTP id z13so6306929lft.1 for ; Mon, 26 Apr 2021 02:42:06 -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=rVYJfSPpNRW9t+ky9Ma6gd1JyGAcgiInt1EiUDpeCdo=; b=Zb4+kPdlgUBRBUyBsiSoPzDX1xPrAoSDIghKQwWrnQmEtLJ2qrnH3HaoMBIoRZfKbT pOZS5Iq4csG3oYjBhzyndDgYnOSVHkkC1APZNxhjAPkkF9tOuTb78hUDguepVyUvlG3O TPP9ZWHtd/SWgPaIke2UQJr0zKNp3H1AitVUrg4CHNWSZp5E9I/4lbhMRepg2xdTxNNK dvZnaN9RpJ3gCodArlXSW41J8mxTTtcGQdg9Qu866+TrRAjUq8Vwgpy/kA9NO8wkc1Q2 UCSpnfGP8DOw9dgyVevvLxJrh1kE7qvyasoLbg0z2nC9QzGMn33z/b5siWTJUas0ieMN gHjA== 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=rVYJfSPpNRW9t+ky9Ma6gd1JyGAcgiInt1EiUDpeCdo=; b=bRGNrBdjQCoohz9DcsUjq6ytohNJDQQFOPd/RT0paJsk+DR5v230xmRQP8AEsoxdo5 B6cgBVTROOajo3t2098z/aW2S9QjRDWZML585Xr92T6uGgEu2Arv769BhuJO7vDAXi/l oil8s7EAUszM7OZgyUyVe0r4jhLqtkK0yYHPr7FjZ18C44pFywTtP6aWuDPMNQUrWTGH 5cIkvXzYvPomU2fFV0D1/BlYlZgZoHtAO51A7o0xCJ2ziRD9zX4LIaleoVooPs/i0AMC Xh42Q6eV3EA5QDs+JLRrNlBc7ZsCXiohpdT2eS9nDKo8vYuMtGOH/xr4inewMEPIZ2f0 U2tg== X-Gm-Message-State: AOAM530YyNnhRutUTTfHT9LnHMInDcDDpCkRf7vbnJFc3wQaMXl4486z mCUgyCcer/jBI7bbCGKY4BQnD++DJ4k= X-Received: by 2002:a2e:2e10:: with SMTP id u16mr11935558lju.228.1619429670965; Mon, 26 Apr 2021 02:34: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 m7sm1402883ljp.102.2021.04.26.02.34.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 02:34:30 -0700 (PDT) From: =?utf-8?q?Jan_Ekstr=C3=B6m?= To: ffmpeg-devel@ffmpeg.org Date: Mon, 26 Apr 2021 12:34:24 +0300 Message-Id: <20210426093425.17900-4-jeebjp@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210426093425.17900-1-jeebjp@gmail.com> References: <20210426093425.17900-1-jeebjp@gmail.com> MIME-Version: 1.0 Subject: [FFmpeg-devel] [PATCH v3 3/4] avcodec/ttmlenc: add initial support for regions and styles 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: fI2lpQ8yrviK 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 | 206 ++++++++++++++++++++++++++++++++++--- libavcodec/ttmlenc.h | 3 +- tests/ref/fate/sub-ttmlenc | 86 +++++++++------- 3 files changed, 243 insertions(+), 52 deletions(-) diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c index e3c155fdd1..37372b29cd 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,171 @@ 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.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, " \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++) { + int ret = ttml_write_region(avctx, &s->buffer, ass->styles[i]); + 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