[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