Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
dd71c902 by Steve Lhomme at 2026-01-22T11:28:17+01:00
demux: mkv: fix string to chapter_uid conversion
The integer can use the whole uint64_t range.
std::stoul() will generate a std::out_of_range exception on values larger than
a uint32_t.
Ref. #29553
- - - - -
ccc17742 by Steve Lhomme at 2026-01-22T11:28:17+01:00
demux: mkv: pass the MatroskaChapterProcessTime to the command interpreter
We may want to know when the chapter is entering/leaving with the command.
- - - - -
e32aac78 by Steve Lhomme at 2026-01-22T11:28:17+01:00
demux: mkv: avoid infinite loop on entering a chapter with GotoAndPlay(<itself>)
- - - - -
b63629f2 by Steve Lhomme at 2026-01-22T11:28:17+01:00
demux: mkv: discard GotoAndPlay command if there's extra text before the
parenthesis
- GotoAndPlay() is supported
- GotoAndPlay () is supported
- GotoAndPlay abc() is not supported
Ref. #29553
- - - - -
e2c579c7 by Steve Lhomme at 2026-01-22T11:28:17+01:00
demux: mkv: only interpret the command has a value to interpret
- - - - -
8 changed files:
- modules/demux/mkv/chapter_command.cpp
- modules/demux/mkv/chapter_command.hpp
- modules/demux/mkv/chapter_command_dvd.cpp
- modules/demux/mkv/chapter_command_dvd.hpp
- modules/demux/mkv/chapter_command_script.cpp
- modules/demux/mkv/chapter_command_script.hpp
- modules/demux/mkv/chapter_command_script_common.cpp
- modules/demux/mkv/chapter_command_script_common.hpp
Changes:
=====================================
modules/demux/mkv/chapter_command.cpp
=====================================
@@ -25,14 +25,6 @@
#include <vlc_arrays.h>
-#if LIBMATROSKA_VERSION < 0x010700
-typedef enum {
- MATROSKA_CHAPPROCESSTIME_DURING = 0,
- MATROSKA_CHAPPROCESSTIME_BEFORE = 1,
- MATROSKA_CHAPPROCESSTIME_AFTER = 2,
-} MatroskaChapterProcessTime;
-#endif
-
namespace mkv {
void chapter_codec_cmds_c::AddCommand( const KaxChapterProcessCommand &
command )
=====================================
modules/demux/mkv/chapter_command.hpp
=====================================
@@ -30,6 +30,15 @@
struct vlc_spu_highlight_t;
+#if LIBMATROSKA_VERSION < 0x010700
+typedef enum {
+ MATROSKA_CHAPPROCESSTIME_DURING = 0,
+ MATROSKA_CHAPPROCESSTIME_BEFORE = 1,
+ MATROSKA_CHAPPROCESSTIME_AFTER = 2,
+} MatroskaChapterProcessTime;
+#endif
+
+
namespace mkv {
class virtual_chapter_c;
=====================================
modules/demux/mkv/chapter_command_dvd.cpp
=====================================
@@ -36,15 +36,15 @@ int16_t dvd_chapter_codec_c::GetTitleNumber() const
bool dvd_chapter_codec_c::Enter()
{
- return EnterLeaveHelper( "Matroska DVD enter command", enter_cmds );
+ return EnterLeaveHelper( "Matroska DVD enter command", enter_cmds,
MATROSKA_CHAPPROCESSTIME_BEFORE );
}
bool dvd_chapter_codec_c::Leave()
{
- return EnterLeaveHelper( "Matroska DVD leave command", leave_cmds );
+ return EnterLeaveHelper( "Matroska DVD leave command", leave_cmds,
MATROSKA_CHAPPROCESSTIME_AFTER );
}
-bool dvd_chapter_codec_c::EnterLeaveHelper( char const * str_diag,
ChapterProcess & p_container )
+bool dvd_chapter_codec_c::EnterLeaveHelper( char const * str_diag,
ChapterProcess & p_container, MatroskaChapterProcessTime process_time )
{
bool f_result = false;
ChapterProcess::iterator it = p_container.begin ();
@@ -57,7 +57,7 @@ bool dvd_chapter_codec_c::EnterLeaveHelper( char const *
str_diag, ChapterProces
for( ; i_size > 0; i_size -=1, p_data += 8 )
{
vlc_debug( l, "%s", str_diag);
- f_result |= intepretor.Interpret( p_data );
+ f_result |= intepretor.Interpret( process_time, p_data, 8 );
}
}
++it;
@@ -108,7 +108,7 @@ std::string dvd_chapter_codec_c::GetCodecName( bool
f_for_title ) const
}
// see http://www.dvd-replica.com/DVD/vmcmdset.php for a description of DVD
commands
-bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t
i_size )
+bool dvd_command_interpretor_c::Interpret( MatroskaChapterProcessTime, const
binary * p_command, size_t i_size )
{
if ( i_size != 8 )
return false;
@@ -582,7 +582,7 @@ bool dvd_command_interpretor_c::ProcessNavAction( uint16_t
button )
if ( button_ptr.auto_action_mode )
{
// process the button action
- return Interpret( button_ptr.cmd.bytes, 8 );
+ return Interpret( MATROSKA_CHAPPROCESSTIME_DURING,
button_ptr.cmd.bytes, 8 );
}
return false;
}
@@ -605,7 +605,7 @@ bool dvd_command_interpretor_c::HandleKeyEvent(
NavivationKey key )
case DOWN: return ProcessNavAction( button_ptr.down );
case OK:
// process the button action
- return Interpret( button_ptr.cmd.bytes, 8 );
+ return Interpret( MATROSKA_CHAPPROCESSTIME_DURING,
button_ptr.cmd.bytes, 8 );
case MENU:
case POPUP:
return false;
@@ -657,7 +657,7 @@ void dvd_command_interpretor_c::HandleMousePressed(
unsigned x, unsigned y )
// process the button action
SetSPRM( 0x88, best );
- Interpret( button_ptr.cmd.bytes, 8 );
+ Interpret( MATROSKA_CHAPPROCESSTIME_DURING, button_ptr.cmd.bytes, 8 );
vlc_debug( l, "Processed button %d", best );
=====================================
modules/demux/mkv/chapter_command_dvd.hpp
=====================================
@@ -33,7 +33,7 @@ public:
p_PRMs[ 0x80 + 18 ] = 0xFFFFu;
}
- bool Interpret( const binary * p_command, size_t i_size = 8 );
+ bool Interpret( MatroskaChapterProcessTime, const binary * p_command,
size_t i_size );
bool HandleKeyEvent( NavivationKey );
void HandleMousePressed( unsigned x, unsigned y );
@@ -201,7 +201,7 @@ public:
int16_t GetTitleNumber() const override;
protected:
- bool EnterLeaveHelper( char const*, ChapterProcess & );
+ bool EnterLeaveHelper( char const*, ChapterProcess &,
MatroskaChapterProcessTime );
dvd_command_interpretor_c & intepretor;
};
=====================================
modules/demux/mkv/chapter_command_script.cpp
=====================================
@@ -16,7 +16,7 @@ const std::string
matroska_script_interpretor_c::CMD_MS_GOTO_AND_PLAY = "GotoAnd
// see http://www.matroska.org/technical/specs/chapters/index.html#mscript
// for a description of existing commands
-bool matroska_script_interpretor_c::Interpret( const binary * p_command,
size_t i_size )
+bool matroska_script_interpretor_c::Interpret( MatroskaChapterProcessTime
time, const binary * p_command, size_t i_size )
{
bool b_result = false;
@@ -31,11 +31,14 @@ bool matroska_script_interpretor_c::Interpret( const binary
* p_command, size_t
// find the (
for ( i=CMD_MS_GOTO_AND_PLAY.size(); i<sz_command.size(); i++)
{
+ if ( sz_command[i] == ' ' )
+ continue;
if ( sz_command[i] == '(' )
{
i++;
break;
}
+ return false; // extra characters between command and ( is not
supported
}
// find the )
for ( j=i; j<sz_command.size(); j++)
@@ -47,19 +50,29 @@ bool matroska_script_interpretor_c::Interpret( const binary
* p_command, size_t
}
}
- std::string st = sz_command.substr( i+1, j-i-1 );
- chapter_uid i_chapter_uid = std::stoul( st );
+ if(i+1 < j-i-1)
+ {
+ std::string st = sz_command.substr( i+1, j-i-1 );
+ chapter_uid i_chapter_uid = std::stoull( st );
- virtual_segment_c *p_vsegment;
- virtual_chapter_c *p_vchapter = vm.FindVChapter( i_chapter_uid,
p_vsegment );
+ virtual_segment_c *p_vsegment;
+ virtual_chapter_c *p_vchapter = vm.FindVChapter( i_chapter_uid,
p_vsegment );
- if ( p_vchapter == NULL )
- vlc_debug( l, "Chapter %" PRId64 " not found", i_chapter_uid);
- else
- {
- if ( !p_vchapter->EnterAndLeave(
vm.GetCurrentVSegment()->CurrentChapter(), false ) )
- vm.JumpTo( *p_vsegment, *p_vchapter );
- b_result = true;
+ if ( p_vchapter == NULL )
+ vlc_debug( l, "Chapter %" PRId64 " not found", i_chapter_uid);
+ else
+ {
+ auto current_chapter =
vm.GetCurrentVSegment()->CurrentChapter();
+ if ( p_vchapter == current_chapter) {
+ if ( time == MATROSKA_CHAPPROCESSTIME_BEFORE )
+ // the enter command is enter itself, avoid infinite
loop
+ return false;
+ vm.JumpTo( *p_vsegment, *p_vchapter );
+ }
+ else if ( !p_vchapter->EnterAndLeave( current_chapter, false )
)
+ vm.JumpTo( *p_vsegment, *p_vchapter );
+ b_result = true;
+ }
}
}
=====================================
modules/demux/mkv/chapter_command_script.hpp
=====================================
@@ -19,7 +19,7 @@ public:
:matroska_script_interpreter_common_c(log, vm_)
{}
- bool Interpret( const binary * p_command, size_t i_size ) override;
+ bool Interpret( MatroskaChapterProcessTime, const binary * p_command,
size_t i_size ) override;
// Matroska Script commands
static const std::string CMD_MS_GOTO_AND_PLAY;
=====================================
modules/demux/mkv/chapter_command_script_common.cpp
=====================================
@@ -1,7 +1,7 @@
// Copyright (C) 2024 VLC authors and VideoLAN
// SPDX-License-Identifier: LGPL-2.1-or-later
//
-// chapter_command_script_common.cpp :
+// chapter_command_script_common.cpp :
// Common file for Matroska JS and Matroska Script
// Authors: Laurent Aimar <[email protected]>
// Steve Lhomme <[email protected]>
@@ -21,7 +21,7 @@ bool matroska_script_codec_common_c::Enter()
if ( (*index).GetSize() )
{
vlc_debug( l, "Matroska Script enter command" );
- f_result |= get_interpreter().Interpret( (*index).GetBuffer(),
(*index).GetSize() );
+ f_result |= get_interpreter().Interpret(
MATROSKA_CHAPPROCESSTIME_BEFORE, (*index).GetBuffer(), (*index).GetSize() );
}
++index;
}
@@ -37,7 +37,7 @@ bool matroska_script_codec_common_c::Leave()
if ( (*index).GetSize() )
{
vlc_debug( l, "Matroska Script leave command" );
- f_result |= get_interpreter().Interpret( (*index).GetBuffer(),
(*index).GetSize() );
+ f_result |= get_interpreter().Interpret(
MATROSKA_CHAPPROCESSTIME_AFTER, (*index).GetBuffer(), (*index).GetSize() );
}
++index;
}
=====================================
modules/demux/mkv/chapter_command_script_common.hpp
=====================================
@@ -23,7 +23,7 @@ public:
virtual ~matroska_script_interpreter_common_c() = default;
// DVD command IDs
- virtual bool Interpret( const binary * p_command, size_t i_size ) = 0;
+ virtual bool Interpret( MatroskaChapterProcessTime time, const binary *
p_command, size_t i_size ) = 0;
protected:
struct vlc_logger *l;
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/f4b7c133c5752e958912181e6a1e22b875417e87...e2c579c7dfc5ca69913357bc086cbbae1031dbec
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/f4b7c133c5752e958912181e6a1e22b875417e87...e2c579c7dfc5ca69913357bc086cbbae1031dbec
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance_______________________________________________
vlc-commits mailing list
[email protected]
https://mailman.videolan.org/listinfo/vlc-commits