[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