[vlc-commits] demux: mkv: properly handle D_WEBVTT

Francois Cartegnie git at videolan.org
Thu Jul 16 15:10:25 CEST 2020


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Wed Jul 15 14:05:40 2020 +0200| [385ed6a8b1acfd51e097dd3c54196e1a91839d4d] | committer: Francois Cartegnie

demux: mkv: properly handle D_WEBVTT

refs #24949
Was wired as SUBT for ease, but that only works
as long as cue parameters are not used.

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

 modules/demux/Makefile.am                    |  2 +-
 modules/demux/mkv/matroska_segment_parse.cpp |  2 +-
 modules/demux/mkv/mkv.cpp                    |  7 ++--
 modules/demux/mkv/util.cpp                   | 50 ++++++++++++++++++++++++++++
 modules/demux/mkv/util.hpp                   |  1 +
 5 files changed, 55 insertions(+), 7 deletions(-)

diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am
index 67ec086af9..0f58860624 100644
--- a/modules/demux/Makefile.am
+++ b/modules/demux/Makefile.am
@@ -199,7 +199,7 @@ libmkv_plugin_la_SOURCES = \
 	demux/mkv/stream_io_callback.hpp demux/mkv/stream_io_callback.cpp \
 	demux/mp4/libmp4.c demux/vobsub.h \
 	demux/mkv/mkv.hpp demux/mkv/mkv.cpp \
-        demux/av1_unpack.h \
+        demux/av1_unpack.h codec/webvtt/helpers.h \
 	demux/windows_audio_commons.h
 libmkv_plugin_la_SOURCES += packetizer/dts_header.h packetizer/dts_header.c
 libmkv_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(CFLAGS_mkv)
diff --git a/modules/demux/mkv/matroska_segment_parse.cpp b/modules/demux/mkv/matroska_segment_parse.cpp
index a56514c536..70b2d7bc10 100644
--- a/modules/demux/mkv/matroska_segment_parse.cpp
+++ b/modules/demux/mkv/matroska_segment_parse.cpp
@@ -2270,7 +2270,7 @@ bool matroska_segment_c::TrackInit( mkv_track_t * p_tk )
         }
         S_CASE("D_WEBVTT/SUBTITLES") {
             ONLY_FMT(SPU);
-            vars.p_fmt->i_codec = VLC_CODEC_SUBT;
+            vars.p_fmt->i_codec = VLC_CODEC_WEBVTT;
             vars.p_fmt->subs.psz_encoding = strdup( "UTF-8");
         }
         S_CASE("S_TEXT/WEBVTT") {
diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
index 471de4134a..6f71936e22 100644
--- a/modules/demux/mkv/mkv.cpp
+++ b/modules/demux/mkv/mkv.cpp
@@ -624,13 +624,10 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
 
          case VLC_CODEC_WEBVTT:
             {
-                p_block = block_Realloc( p_block, 16, p_block->i_buffer );
+                p_block = WEBVTT_Repack_Sample( p_block, /* D_WEBVTT -> webm */
+                                         !p_track->codec.compare( 0, 1, "D" ) );
                 if( !p_block )
                     continue;
-                SetDWBE( p_block->p_buffer, p_block->i_buffer );
-                memcpy( &p_block->p_buffer[4], "vttc", 4 );
-                SetDWBE( &p_block->p_buffer[8], p_block->i_buffer - 8 );
-                memcpy( &p_block->p_buffer[12], "payl", 4 );
             }
             break;
 
diff --git a/modules/demux/mkv/util.cpp b/modules/demux/mkv/util.cpp
index afed921e6d..71b93090de 100644
--- a/modules/demux/mkv/util.cpp
+++ b/modules/demux/mkv/util.cpp
@@ -23,6 +23,7 @@
 #include "mkv.hpp"
 #include "util.hpp"
 #include "demux.hpp"
+#include "../../codec/webvtt/helpers.h"
 
 namespace mkv {
 
@@ -243,6 +244,55 @@ void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, v
     }
 }
 
+block_t *WEBVTT_Repack_Sample(block_t *p_block, bool b_webm)
+{
+    struct webvtt_cueelements_s els;
+    memset(&els, 0, sizeof(els));
+    /* Repack to ISOBMFF samples format */
+    if( !b_webm ) /* S_TEXT/WEBVTT */
+    {
+        p_block = block_Realloc( p_block, 16, p_block->i_buffer );
+        if( !p_block )
+            return NULL;
+        SetDWBE( p_block->p_buffer, p_block->i_buffer );
+        memcpy(  &p_block->p_buffer[ 4], "vttc", 4 );
+        SetDWBE( &p_block->p_buffer[ 8], p_block->i_buffer - 8 );
+        memcpy(  &p_block->p_buffer[12], "payl", 4 );
+    }
+    else /* deprecated D_WEBVTT/ */
+    {
+        const uint8_t *start = p_block->p_buffer;
+        const uint8_t *end = p_block->p_buffer + p_block->i_buffer;
+        const uint8_t *sttg =
+                reinterpret_cast<const uint8_t *>(std::memchr( start, '\n', p_block->i_buffer ));
+        if( !sttg || ++sttg == end )
+            goto error;
+        const uint8_t *payl =
+                reinterpret_cast<const uint8_t *>(std::memchr( sttg, '\n', end - sttg ));
+        if( !payl || ++payl == end )
+            goto error;
+        els.iden.p_data = start;
+        els.iden.i_data = &sttg[-1] - start;
+        els.sttg.p_data = sttg;
+        els.sttg.i_data = &payl[-1] - sttg;
+        els.payl.p_data = payl;
+        els.payl.i_data = end - payl;
+        size_t newsize = WEBVTT_Pack_CueElementsGetNewSize( &els );
+        block_t *newblock = block_Alloc( newsize );
+        if( !newblock )
+            goto error;
+        WEBVTT_Pack_CueElements( &els, newblock->p_buffer );
+        block_CopyProperties( newblock, p_block );
+        block_Release( p_block );
+        return newblock;
+    }
+    return p_block;
+
+error:
+    block_Release( p_block );
+    return NULL;
+}
+
 void send_Block( demux_t * p_demux, mkv_track_t * p_tk, block_t * p_block, unsigned int i_number_frames, int64_t i_duration )
 {
     demux_sys_t *p_sys = (demux_sys_t *)p_demux->p_sys;
diff --git a/modules/demux/mkv/util.hpp b/modules/demux/mkv/util.hpp
index b53ff3b657..a5676d807b 100644
--- a/modules/demux/mkv/util.hpp
+++ b/modules/demux/mkv/util.hpp
@@ -33,6 +33,7 @@ block_t *block_zlib_decompress( vlc_object_t *p_this, block_t *p_in_block );
 
 block_t *MemToBlock( uint8_t *p_mem, size_t i_mem, size_t offset);
 void handle_real_audio(demux_t * p_demux, mkv_track_t * p_tk, block_t * p_blk, vlc_tick_t i_pts);
+block_t *WEBVTT_Repack_Sample(block_t *p_block, bool b_webm = false);
 void send_Block( demux_t * p_demux, mkv_track_t * p_tk, block_t * p_block, unsigned int i_number_frames, int64_t i_duration );
 
 



More information about the vlc-commits mailing list