[vlc-commits] codec: webvtt: add encoder

Francois Cartegnie git at videolan.org
Thu Jan 25 14:36:00 CET 2018


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Mon Jan 22 20:59:49 2018 +0100| [a777308941f582f1d2930f59254fe9e91e2f2293] | committer: Francois Cartegnie

codec: webvtt: add encoder

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=a777308941f582f1d2930f59254fe9e91e2f2293
---

 modules/MODULES_LIST          |   2 +-
 modules/codec/Makefile.am     |   1 +
 modules/codec/webvtt/encvtt.c | 179 ++++++++++++++++++++++++++++++++++++++++++
 modules/codec/webvtt/webvtt.c |   5 ++
 modules/codec/webvtt/webvtt.h |   3 +
 5 files changed, 189 insertions(+), 1 deletion(-)

diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST
index 56b2e40483..19b2892115 100644
--- a/modules/MODULES_LIST
+++ b/modules/MODULES_LIST
@@ -458,7 +458,7 @@ $Id$
  * wav: Wav demuxer
  * wave: Wave video effect
  * waveout: simple audio output module for Windows
- * webvtt: WEBVTT subtitles decoder and demuxer
+ * webvtt: WEBVTT subtitles decoder, encoder and demuxer
  * wgl: WGL extension for OpenGL
  * win_hotkeys: module to catch hotkeys when application doesn't have the focus
  * win_msg: Windows Messages module
diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am
index 7e08b184da..2d9add96d7 100644
--- a/modules/codec/Makefile.am
+++ b/modules/codec/Makefile.am
@@ -231,6 +231,7 @@ codec_LTLIBRARIES += libttml_plugin.la
 libwebvtt_plugin_la_SOURCES = codec/webvtt/subsvtt.c \
                               codec/webvtt/webvtt.c \
                               codec/webvtt/webvtt.h \
+                              codec/webvtt/encvtt.c \
                               demux/webvtt.c \
                               demux/mp4/minibox.h
 codec_LTLIBRARIES += libwebvtt_plugin.la
diff --git a/modules/codec/webvtt/encvtt.c b/modules/codec/webvtt/encvtt.c
new file mode 100644
index 0000000000..db7dfb2e16
--- /dev/null
+++ b/modules/codec/webvtt/encvtt.c
@@ -0,0 +1,179 @@
+/*****************************************************************************
+ * encvtt.c: Encoder for WEBVTT as ISO1446-30 payload
+ *****************************************************************************
+ * Copyright (C) 2018 VideoLabs, VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+#include <vlc_subpicture.h>
+#include <vlc_boxes.h>
+#include <vlc_charset.h>
+#include "webvtt.h"
+
+static block_t *Encode ( encoder_t *, subpicture_t * );
+
+int OpenEncoder( vlc_object_t *p_this )
+{
+    encoder_t *p_enc = (encoder_t *)p_this;
+
+    if( p_enc->fmt_out.i_codec != VLC_CODEC_WEBVTT )
+        return VLC_EGENERIC;
+
+    p_enc->p_sys = NULL;
+
+    p_enc->pf_encode_sub = Encode;
+    p_enc->fmt_out.i_cat = SPU_ES;
+    return VLC_SUCCESS;
+}
+
+
+void CloseEncoder( vlc_object_t *p_this )
+{
+    (void)p_this;
+}
+
+
+static block_t *Encode( encoder_t *p_enc, subpicture_t *p_spu )
+{
+    VLC_UNUSED( p_enc );
+
+    if( p_spu == NULL )
+        return NULL;
+
+    bo_t box;
+    if( !bo_init( &box, 8 ) )
+        return NULL;
+
+    for( subpicture_region_t *p_region = p_spu->p_region;
+                              p_region; p_region = p_region->p_next )
+    {
+        if( p_region->fmt.i_chroma != VLC_CODEC_TEXT ||
+            p_region->p_text == NULL ||
+            p_region->p_text->psz_text == NULL )
+            continue;
+
+        size_t i_offset = bo_size( &box );
+
+        bo_add_32be( &box, 0 );
+        bo_add_fourcc( &box, "vttc" );
+
+        /* Payload */
+
+        bo_add_32be( &box, 0 );
+        bo_add_fourcc( &box, "payl" );
+
+        /* This should already be UTF-8 encoded, so not much effort... */
+        for( const text_segment_t *p_segment = p_region->p_text;
+             p_segment; p_segment = p_segment->p_next )
+        {
+            if( p_segment->psz_text == NULL )
+                continue;
+            if( p_segment != p_region->p_text )
+                bo_add_8( &box, '\n' );
+
+            const text_style_t *style = p_segment->style;
+            if( style && style->i_features )
+            {
+                if( style->i_features & STYLE_HAS_FLAGS )
+                {
+                    if( style->i_style_flags & STYLE_BOLD )
+                        bo_add_mem( &box, 3, "<b>" );
+                    if( style->i_style_flags & STYLE_UNDERLINE )
+                        bo_add_mem( &box, 3, "<u>" );
+                    if( style->i_style_flags & STYLE_ITALIC )
+                        bo_add_mem( &box, 3, "<i>" );
+                }
+            }
+            bo_add_mem( &box, strlen(p_segment->psz_text), p_segment->psz_text );
+            if( style && style->i_features )
+            {
+                if( style->i_features & STYLE_HAS_FLAGS )
+                {
+                    if( style->i_style_flags & STYLE_BOLD )
+                        bo_add_mem( &box, 4, "</b>" );
+                    if( style->i_style_flags & STYLE_UNDERLINE )
+                        bo_add_mem( &box, 4, "</u>" );
+                    if( style->i_style_flags & STYLE_ITALIC )
+                        bo_add_mem( &box, 4, "</i>" );
+                }
+            }
+        }
+
+        bo_set_32be( &box, i_offset + 8, bo_size( &box ) - i_offset - 8 );
+
+        /* Settings */
+
+        if( (p_region->i_text_align & (SUBPICTURE_ALIGN_LEFT|SUBPICTURE_ALIGN_RIGHT)) ||
+                (p_region->i_align & SUBPICTURE_ALIGN_TOP) )
+        {
+            size_t i_start = bo_size( &box );
+
+            bo_add_32be( &box, 0 );
+            bo_add_fourcc( &box, "sttg" );
+
+            if( p_region->i_text_align & SUBPICTURE_ALIGN_LEFT )
+                bo_add_mem( &box, 10, "align:left" );
+            else if( p_region->i_text_align & SUBPICTURE_ALIGN_RIGHT )
+                bo_add_mem( &box, 11, "align:right" );
+
+            if( p_region->i_align & SUBPICTURE_ALIGN_TOP )
+            {
+                float offset = 100.0;
+                if( p_spu->i_original_picture_height > 0 )
+                    offset = offset * p_region->i_y / p_spu->i_original_picture_height;
+                if( bo_size( &box ) != i_start + 8 )
+                    bo_add_8( &box, ' ' );
+                char *psz;
+                int i_printed = us_asprintf( &psz, "line:%2.2f%%", offset );
+                if( i_printed >= 0 )
+                {
+                    if( i_printed > 0 )
+                        bo_add_mem( &box, i_printed, psz );
+                    free( psz );
+                }
+            }
+            bo_set_32be( &box, i_start, bo_size( &box ) - i_start );
+        }
+
+
+        bo_set_32be( &box, i_offset, bo_size( &box ) - i_offset );
+    }
+
+    if( bo_size( &box ) == 0 ) /* No cue */
+    {
+        bo_add_32be( &box, 8 );
+        bo_add_fourcc( &box, "vtte" );
+    }
+
+    block_t *p_block = box.b;
+    box.b = NULL;
+    bo_deinit( &box );
+
+    if( p_block )
+    {
+        p_block->i_pts = p_block->i_dts = p_spu->i_start;
+        if( p_spu->i_stop > p_spu->i_start )
+            p_block->i_length = p_spu->i_stop - p_spu->i_start;
+    }
+
+    return p_block;
+}
diff --git a/modules/codec/webvtt/webvtt.c b/modules/codec/webvtt/webvtt.c
index cc3aeca575..db07a8ecf1 100644
--- a/modules/codec/webvtt/webvtt.c
+++ b/modules/codec/webvtt/webvtt.c
@@ -58,6 +58,11 @@ vlc_module_begin ()
         set_subcategory( SUBCAT_INPUT_DEMUX )
         set_callbacks( OpenDemuxStream, CloseDemux )
         add_shortcut( "webvttstream" )
+    add_submodule()
+        set_description( "WEBVTT text encoder" )
+        set_capability( "encoder", 101 )
+        set_subcategory( SUBCAT_INPUT_SCODEC )
+        set_callbacks( OpenEncoder, CloseEncoder )
 vlc_module_end ()
 
 struct webvtt_text_parser_t
diff --git a/modules/codec/webvtt/webvtt.h b/modules/codec/webvtt/webvtt.h
index 1337be41be..7002fd7f0d 100644
--- a/modules/codec/webvtt/webvtt.h
+++ b/modules/codec/webvtt/webvtt.h
@@ -27,6 +27,9 @@ int  OpenDemux     ( vlc_object_t * );
 int  OpenDemuxStream (vlc_object_t *);
 void CloseDemux    ( vlc_object_t * );
 
+int  OpenEncoder   ( vlc_object_t * );
+void CloseEncoder  ( vlc_object_t * );
+
 typedef struct webvtt_text_parser_t webvtt_text_parser_t;
 
 enum webvtt_header_line_e



More information about the vlc-commits mailing list