You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.7 KiB
89 lines
2.7 KiB
// Copyright (C) 2003-2024 VLC authors and VideoLAN
|
|
// SPDX-License-Identifier: LGPL-2.1-or-later
|
|
//
|
|
// chapter_command_script.cpp : Matroska Script Codec for Matroska Chapter Codecs
|
|
// Authors: Laurent Aimar <fenrir@via.ecp.fr>
|
|
// Steve Lhomme <steve.lhomme@free.fr>
|
|
|
|
|
|
#include "chapter_command_script.hpp"
|
|
#include "virtual_segment.hpp"
|
|
|
|
namespace mkv {
|
|
|
|
#define M_MS_MAX_DEPTH 8
|
|
//Matroska Script
|
|
const std::string matroska_script_interpretor_c::CMD_MS_GOTO_AND_PLAY = "GotoAndPlay";
|
|
|
|
// see http://www.matroska.org/technical/specs/chapters/index.html#mscript
|
|
// for a description of existing commands
|
|
bool matroska_script_interpretor_c::Interpret( MatroskaChapterProcessTime time, const binary * p_command, size_t i_size )
|
|
{
|
|
static thread_local int n_call = 0;
|
|
if( n_call > M_MS_MAX_DEPTH )
|
|
return false;
|
|
n_call++;
|
|
|
|
bool b_result = false;
|
|
|
|
std::string sz_command( reinterpret_cast<const char*> (p_command), i_size );
|
|
|
|
vlc_debug( l, "command : %s", sz_command.c_str() );
|
|
|
|
if ( sz_command.compare( 0, CMD_MS_GOTO_AND_PLAY.size(), CMD_MS_GOTO_AND_PLAY ) == 0 )
|
|
{
|
|
size_t i,j;
|
|
|
|
// 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++)
|
|
{
|
|
if ( sz_command[j] == ')' )
|
|
{
|
|
i--;
|
|
break;
|
|
}
|
|
}
|
|
|
|
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 );
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
n_call--;
|
|
return b_result;
|
|
}
|
|
|
|
} // namespace
|
|
|