ffmpeg | branch: master | Jan Ekström <jan.ekst...@24i.com> | Mon Mar 15 
16:01:52 2021 +0200| [464d6ed98d67fe0c3819516e9b0ca5edaf956a0e] | committer: 
Jan Ekström

avformat/ttmlenc: enable writing out additional header values

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 <jan.ekst...@24i.com>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=464d6ed98d67fe0c3819516e9b0ca5edaf956a0e
---

 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[] =
 "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
 "<tt\n"
-"  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";
+"%s"
 "  xml:lang=\"%s\">\n"
+"%s"
 "  <body>\n"
 "    <div>\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;

_______________________________________________
ffmpeg-cvslog mailing list
ffmpeg-cvslog@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog

To unsubscribe, visit link above, or email
ffmpeg-cvslog-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to