1 /*****************************************************************************
2 * mkv.cpp : matroska demuxer
3 *****************************************************************************
4 * Copyright (C) 2003-2004 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Steve Lhomme <steve.lhomme@free.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 #include "chapter_command.hpp"
27 void chapter_codec_cmds_c::AddCommand( const KaxChapterProcessCommand & command )
29 uint32 codec_time = uint32(-1);
30 for( size_t i = 0; i < command.ListSize(); i++ )
32 const EbmlElement *k = command[i];
34 if( MKV_IS_ID( k, KaxChapterProcessTime ) )
36 codec_time = uint32( *static_cast<const KaxChapterProcessTime*>( k ) );
41 for( size_t i = 0; i < command.ListSize(); i++ )
43 const EbmlElement *k = command[i];
45 if( MKV_IS_ID( k, KaxChapterProcessData ) )
47 KaxChapterProcessData *p_data = new KaxChapterProcessData( *static_cast<const KaxChapterProcessData*>( k ) );
51 during_cmds.push_back( p_data );
54 enter_cmds.push_back( p_data );
57 leave_cmds.push_back( p_data );
66 int16 dvd_chapter_codec_c::GetTitleNumber()
68 if ( p_private_data->GetSize() >= 3)
70 const binary* p_data = p_private_data->GetBuffer();
71 if ( p_data[0] == MATROSKA_DVD_LEVEL_SS )
73 return int16( (p_data[2] << 8) + p_data[3] );
79 bool dvd_chapter_codec_c::Enter()
81 bool f_result = false;
82 std::vector<KaxChapterProcessData*>::iterator index = enter_cmds.begin();
83 while ( index != enter_cmds.end() )
85 if ( (*index)->GetSize() )
87 binary *p_data = (*index)->GetBuffer();
88 size_t i_size = *p_data++;
89 // avoid reading too much from the buffer
90 i_size = __MIN( i_size, ((*index)->GetSize() - 1) >> 3 );
91 for ( ; i_size > 0; i_size--, p_data += 8 )
93 msg_Dbg( &sys.demuxer, "Matroska DVD enter command" );
94 f_result |= sys.dvd_interpretor.Interpret( p_data );
102 bool dvd_chapter_codec_c::Leave()
104 bool f_result = false;
105 std::vector<KaxChapterProcessData*>::iterator index = leave_cmds.begin();
106 while ( index != leave_cmds.end() )
108 if ( (*index)->GetSize() )
110 binary *p_data = (*index)->GetBuffer();
111 size_t i_size = *p_data++;
112 // avoid reading too much from the buffer
113 i_size = __MIN( i_size, ((*index)->GetSize() - 1) >> 3 );
114 for ( ; i_size > 0; i_size--, p_data += 8 )
116 msg_Dbg( &sys.demuxer, "Matroska DVD leave command" );
117 f_result |= sys.dvd_interpretor.Interpret( p_data );
125 std::string dvd_chapter_codec_c::GetCodecName( bool f_for_title ) const
128 if ( p_private_data->GetSize() >= 3)
130 const binary* p_data = p_private_data->GetBuffer();
131 /* if ( p_data[0] == MATROSKA_DVD_LEVEL_TT )
133 uint16_t i_title = (p_data[1] << 8) + p_data[2];
135 sprintf( psz_str, " %d ---", i_title );
136 result = N_("--- DVD Title");
139 else */ if ( p_data[0] == MATROSKA_DVD_LEVEL_LU )
142 sprintf( psz_str, " (%c%c) ---", p_data[1], p_data[2] );
143 result = N_("--- DVD Menu");
146 else if ( p_data[0] == MATROSKA_DVD_LEVEL_SS && f_for_title )
148 if ( p_data[1] == 0x00 )
149 result = N_("First Played");
150 else if ( p_data[1] == 0xC0 )
151 result = N_("Video Manager");
152 else if ( p_data[1] == 0x80 )
154 uint16_t i_title = (p_data[2] << 8) + p_data[3];
156 sprintf( psz_str, " %d -----", i_title );
157 result = N_("----- Title");
165 class virtual_segment_c;
166 class chapter_item_c;
168 // see http://www.dvd-replica.com/DVD/vmcmdset.php for a description of DVD commands
169 bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_size )
174 virtual_segment_c *p_segment = NULL;
175 chapter_item_c *p_chapter = NULL;
176 bool f_result = false;
177 uint16 i_command = ( p_command[0] << 8 ) + p_command[1];
179 // handle register tests if there are some
180 if ( (i_command & 0xF0) != 0 )
182 bool b_test_positive = true;//(i_command & CMD_DVD_IF_NOT) == 0;
183 bool b_test_value = (i_command & CMD_DVD_TEST_VALUE) != 0;
184 uint8 i_test = i_command & 0x70;
187 // see http://dvd.sourceforge.net/dvdinfo/vmi.html
190 switch ( i_command >> 12 )
193 i_cr1 = p_command[3];
194 i_cr2 = (p_command[4] << 8) + p_command[5];
199 i_cr1 = p_command[6];
200 i_cr2 = p_command[7];
201 b_test_value = false;
205 if ( ((p_command[1] >> 4) & 0x7) == 0)
207 i_cr1 = p_command[2];
208 i_cr2 = (p_command[6] << 8) + p_command[7];
212 i_cr1 = p_command[2];
213 i_cr2 = (p_command[6] << 8) + p_command[7];
221 i_value = GetPRM( i_cr2 );
225 case CMD_DVD_IF_GPREG_EQUAL:
227 msg_Dbg( &sys.demuxer, "IF %s EQUALS %s", GetRegTypeName( false, i_cr1 ).c_str(), GetRegTypeName( b_test_value, i_value ).c_str() );
228 if (!( GetPRM( i_cr1 ) == i_value ))
230 b_test_positive = false;
233 case CMD_DVD_IF_GPREG_NOT_EQUAL:
235 msg_Dbg( &sys.demuxer, "IF %s NOT EQUALS %s", GetRegTypeName( false, i_cr1 ).c_str(), GetRegTypeName( b_test_value, i_value ).c_str() );
236 if (!( GetPRM( i_cr1 ) != i_value ))
238 b_test_positive = false;
241 case CMD_DVD_IF_GPREG_INF:
243 msg_Dbg( &sys.demuxer, "IF %s < %s", GetRegTypeName( false, p_command[3] ).c_str(), GetRegTypeName( b_test_value, i_value ).c_str() );
244 if (!( GetPRM( i_cr1 ) < i_value ))
246 b_test_positive = false;
249 case CMD_DVD_IF_GPREG_INF_EQUAL:
250 // if inferior or equal
251 msg_Dbg( &sys.demuxer, "IF %s < %s", GetRegTypeName( false, p_command[3] ).c_str(), GetRegTypeName( b_test_value, i_value ).c_str() );
252 if (!( GetPRM( i_cr1 ) <= i_value ))
254 b_test_positive = false;
257 case CMD_DVD_IF_GPREG_AND:
259 msg_Dbg( &sys.demuxer, "IF %s & %s", GetRegTypeName( false, p_command[3] ).c_str(), GetRegTypeName( b_test_value, i_value ).c_str() );
260 if (!( GetPRM( i_cr1 ) & i_value ))
262 b_test_positive = false;
265 case CMD_DVD_IF_GPREG_SUP:
267 msg_Dbg( &sys.demuxer, "IF %s >= %s", GetRegTypeName( false, p_command[3] ).c_str(), GetRegTypeName( b_test_value, i_value ).c_str() );
268 if (!( GetPRM( i_cr1 ) > i_value ))
270 b_test_positive = false;
273 case CMD_DVD_IF_GPREG_SUP_EQUAL:
274 // if superior or equal
275 msg_Dbg( &sys.demuxer, "IF %s >= %s", GetRegTypeName( false, p_command[3] ).c_str(), GetRegTypeName( b_test_value, i_value ).c_str() );
276 if (!( GetPRM( i_cr1 ) >= i_value ))
278 b_test_positive = false;
283 if ( !b_test_positive )
287 // strip the test command
295 msg_Dbg( &sys.demuxer, "NOP" );
300 msg_Dbg( &sys.demuxer, "Break" );
304 case CMD_DVD_JUMP_TT:
306 uint8 i_title = p_command[5];
307 msg_Dbg( &sys.demuxer, "JumpTT %d", i_title );
309 // find in the ChapProcessPrivate matching this Title level
310 p_chapter = sys.BrowseCodecPrivate( 1, MatchTitleNumber, &i_title, sizeof(i_title), p_segment );
311 if ( p_segment != NULL )
313 sys.JumpTo( *p_segment, p_chapter );
319 case CMD_DVD_CALLSS_VTSM1:
321 msg_Dbg( &sys.demuxer, "CallSS" );
323 switch( (p_command[6] & 0xC0) >> 6 ) {
325 p_type = p_command[5] & 0x0F;
329 msg_Dbg( &sys.demuxer, "CallSS PGC (rsm_cell %x)", p_command[4]);
332 msg_Dbg( &sys.demuxer, "CallSS Title Entry (rsm_cell %x)", p_command[4]);
335 msg_Dbg( &sys.demuxer, "CallSS Root Menu (rsm_cell %x)", p_command[4]);
338 msg_Dbg( &sys.demuxer, "CallSS Subpicture Menu (rsm_cell %x)", p_command[4]);
341 msg_Dbg( &sys.demuxer, "CallSS Audio Menu (rsm_cell %x)", p_command[4]);
344 msg_Dbg( &sys.demuxer, "CallSS Angle Menu (rsm_cell %x)", p_command[4]);
347 msg_Dbg( &sys.demuxer, "CallSS Chapter Menu (rsm_cell %x)", p_command[4]);
350 msg_Dbg( &sys.demuxer, "CallSS <unknown> (rsm_cell %x)", p_command[4]);
353 p_chapter = sys.BrowseCodecPrivate( 1, MatchPgcType, &p_type, 1, p_segment );
354 if ( p_segment != NULL )
356 sys.JumpTo( *p_segment, p_chapter );
361 msg_Dbg( &sys.demuxer, "CallSS VMGM (menu %d, rsm_cell %x)", p_command[5] & 0x0F, p_command[4]);
364 msg_Dbg( &sys.demuxer, "CallSS VTSM (menu %d, rsm_cell %x)", p_command[5] & 0x0F, p_command[4]);
367 msg_Dbg( &sys.demuxer, "CallSS VMGM (pgc %d, rsm_cell %x)", (p_command[2] << 8) + p_command[3], p_command[4]);
372 case CMD_DVD_JUMP_SS:
374 msg_Dbg( &sys.demuxer, "JumpSS");
376 switch( (p_command[5] & 0xC0) >> 6 ) {
378 msg_Dbg( &sys.demuxer, "JumpSS FP");
381 p_type = p_command[5] & 0x0F;
385 msg_Dbg( &sys.demuxer, "JumpSS VMGM Title Entry");
388 msg_Dbg( &sys.demuxer, "JumpSS VMGM Root Menu");
391 msg_Dbg( &sys.demuxer, "JumpSS VMGM Subpicture Menu");
394 msg_Dbg( &sys.demuxer, "JumpSS VMGM Audio Menu");
397 msg_Dbg( &sys.demuxer, "JumpSS VMGM Angle Menu");
400 msg_Dbg( &sys.demuxer, "JumpSS VMGM Chapter Menu");
403 msg_Dbg( &sys.demuxer, "JumpSS <unknown>");
407 p_chapter = sys.BrowseCodecPrivate( 1, MatchIsVMG, NULL, 0, p_segment );
408 if ( p_segment != NULL )
410 p_chapter = p_segment->BrowseCodecPrivate( 1, MatchPgcType, &p_type, 1 );
411 if ( p_chapter != NULL )
413 sys.JumpTo( *p_segment, p_chapter );
419 p_type = p_command[5] & 0x0F;
423 msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Title Entry", p_command[4], p_command[3]);
426 msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Root Menu", p_command[4], p_command[3]);
429 msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Subpicture Menu", p_command[4], p_command[3]);
432 msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Audio Menu", p_command[4], p_command[3]);
435 msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Angle Menu", p_command[4], p_command[3]);
438 msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Chapter Menu", p_command[4], p_command[3]);
441 msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) <unknown>", p_command[4], p_command[3]);
445 p_chapter = sys.BrowseCodecPrivate( 1, MatchVTSMNumber, &p_command[4], 1, p_segment );
447 if ( p_segment != NULL && p_chapter != NULL )
449 // find the title in the VTS
450 p_chapter = p_chapter->BrowseCodecPrivate( 1, MatchTitleNumber, &p_command[3], 1 );
451 if ( p_chapter != NULL )
453 // find the specified menu in the VTSM
454 p_chapter = p_segment->BrowseCodecPrivate( 1, MatchPgcType, &p_type, 1 );
455 if ( p_chapter != NULL )
457 sys.JumpTo( *p_segment, p_chapter );
462 msg_Dbg( &sys.demuxer, "Title (%d) does not exist in this VTS", p_command[3] );
465 msg_Dbg( &sys.demuxer, "DVD Domain VTS (%d) not found", p_command[4] );
468 msg_Dbg( &sys.demuxer, "JumpSS VMGM (pgc %d)", (p_command[2] << 8) + p_command[3]);
473 case CMD_DVD_JUMPVTS_PTT:
475 uint8 i_title = p_command[5];
476 uint8 i_ptt = p_command[3];
478 msg_Dbg( &sys.demuxer, "JumpVTS Title (%d) PTT (%d)", i_title, i_ptt);
480 // find the current VTS content segment
481 p_chapter = sys.p_current_segment->BrowseCodecPrivate( 1, MatchIsDomain, NULL, 0 );
482 if ( p_chapter != NULL )
484 int16 i_curr_title = p_chapter->GetTitleNumber( );
485 if ( i_curr_title > 0 )
487 p_chapter = sys.BrowseCodecPrivate( 1, MatchVTSNumber, &i_curr_title, sizeof(i_curr_title), p_segment );
489 if ( p_segment != NULL && p_chapter != NULL )
491 // find the title in the VTS
492 p_chapter = p_chapter->BrowseCodecPrivate( 1, MatchTitleNumber, &i_title, sizeof(i_title) );
493 if ( p_chapter != NULL )
495 // find the chapter in the title
496 p_chapter = p_chapter->BrowseCodecPrivate( 1, MatchChapterNumber, &i_ptt, sizeof(i_ptt) );
497 if ( p_chapter != NULL )
499 sys.JumpTo( *p_segment, p_chapter );
504 msg_Dbg( &sys.demuxer, "Title (%d) does not exist in this VTS", i_title );
507 msg_Dbg( &sys.demuxer, "DVD Domain VTS (%d) not found", i_curr_title );
510 msg_Dbg( &sys.demuxer, "JumpVTS_PTT command found but not in a VTS(M)");
513 msg_Dbg( &sys.demuxer, "JumpVTS_PTT command but the DVD domain wasn't found");
516 case CMD_DVD_SET_GPRMMD:
518 msg_Dbg( &sys.demuxer, "Set GPRMMD [%d]=%d", (p_command[4] << 8) + p_command[5], (p_command[2] << 8) + p_command[3]);
520 if ( !SetGPRM( (p_command[4] << 8) + p_command[5], (p_command[2] << 8) + p_command[3] ) )
521 msg_Dbg( &sys.demuxer, "Set GPRMMD failed" );
524 case CMD_DVD_LINKPGCN:
526 uint16 i_pgcn = (p_command[6] << 8) + p_command[7];
528 msg_Dbg( &sys.demuxer, "Link PGCN(%d)", i_pgcn );
529 p_chapter = sys.p_current_segment->BrowseCodecPrivate( 1, MatchPgcNumber, &i_pgcn, 2 );
530 if ( p_chapter != NULL )
532 if ( !p_chapter->Enter( true ) )
533 // jump to the location in the found segment
534 sys.p_current_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter, -1 );
542 uint8 i_cn = p_command[7];
544 p_chapter = sys.p_current_segment->CurrentChapter();
546 msg_Dbg( &sys.demuxer, "LinkCN (cell %d)", i_cn );
547 p_chapter = p_chapter->BrowseCodecPrivate( 1, MatchCellNumber, &i_cn, 1 );
548 if ( p_chapter != NULL )
550 if ( !p_chapter->Enter( true ) )
551 // jump to the location in the found segment
552 sys.p_current_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter, -1 );
558 case CMD_DVD_GOTO_LINE:
560 msg_Dbg( &sys.demuxer, "GotoLine (%d)", (p_command[6] << 8) + p_command[7] );
564 case CMD_DVD_SET_HL_BTNN1:
566 msg_Dbg( &sys.demuxer, "SetHL_BTN (%d)", p_command[4] );
567 SetSPRM( 0x88, p_command[4] );
572 msg_Dbg( &sys.demuxer, "unsupported command : %02X %02X %02X %02X %02X %02X %02X %02X"
590 bool dvd_command_interpretor_c::MatchIsDomain( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
592 return ( data.p_private_data != NULL && data.p_private_data->GetBuffer()[0] == MATROSKA_DVD_LEVEL_SS );
595 bool dvd_command_interpretor_c::MatchIsVMG( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
597 if ( data.p_private_data == NULL || data.p_private_data->GetSize() < 2 )
600 return ( data.p_private_data->GetBuffer()[0] == MATROSKA_DVD_LEVEL_SS && data.p_private_data->GetBuffer()[1] == 0xC0);
603 bool dvd_command_interpretor_c::MatchVTSNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
605 if ( i_cookie_size != 2 || data.p_private_data == NULL || data.p_private_data->GetSize() < 4 )
608 if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_SS || data.p_private_data->GetBuffer()[1] != 0x80 )
611 uint16 i_gtitle = (data.p_private_data->GetBuffer()[2] << 8 ) + data.p_private_data->GetBuffer()[3];
612 uint16 i_title = *(uint16*)p_cookie;
614 return (i_gtitle == i_title);
617 bool dvd_command_interpretor_c::MatchVTSMNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
619 if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 4 )
622 if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_SS || data.p_private_data->GetBuffer()[1] != 0x40 )
625 uint8 i_gtitle = data.p_private_data->GetBuffer()[3];
626 uint8 i_title = *(uint8*)p_cookie;
628 return (i_gtitle == i_title);
631 bool dvd_command_interpretor_c::MatchTitleNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
633 if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 4 )
636 if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_TT )
639 uint16 i_gtitle = (data.p_private_data->GetBuffer()[1] << 8 ) + data.p_private_data->GetBuffer()[2];
640 uint8 i_title = *(uint8*)p_cookie;
642 return (i_gtitle == i_title);
645 bool dvd_command_interpretor_c::MatchPgcType( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
647 if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 8 )
650 if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_PGC )
653 uint8 i_pgc_type = data.p_private_data->GetBuffer()[3] & 0x0F;
654 uint8 i_pgc = *(uint8*)p_cookie;
656 return (i_pgc_type == i_pgc);
659 bool dvd_command_interpretor_c::MatchPgcNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
661 if ( i_cookie_size != 2 || data.p_private_data == NULL || data.p_private_data->GetSize() < 8 )
664 if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_PGC )
667 uint16 *i_pgc_n = (uint16 *)p_cookie;
668 uint16 i_pgc_num = (data.p_private_data->GetBuffer()[1] << 8) + data.p_private_data->GetBuffer()[2];
670 return (i_pgc_num == *i_pgc_n);
673 bool dvd_command_interpretor_c::MatchChapterNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
675 if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 2 )
678 if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_PTT )
681 uint8 i_chapter = data.p_private_data->GetBuffer()[1];
682 uint8 i_ptt = *(uint8*)p_cookie;
684 return (i_chapter == i_ptt);
687 bool dvd_command_interpretor_c::MatchCellNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
689 if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 5 )
692 if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_CN )
695 uint8 *i_cell_n = (uint8 *)p_cookie;
696 uint8 i_cell_num = data.p_private_data->GetBuffer()[3];
698 return (i_cell_num == *i_cell_n);
701 const std::string matroska_script_interpretor_c::CMD_MS_GOTO_AND_PLAY = "GotoAndPlay";
703 // see http://www.matroska.org/technical/specs/chapters/index.html#mscript
704 // for a description of existing commands
705 bool matroska_script_interpretor_c::Interpret( const binary * p_command, size_t i_size )
707 bool b_result = false;
709 char *psz_str = (char*) malloc( i_size + 1 );
710 memcpy( psz_str, p_command, i_size );
711 psz_str[ i_size ] = '\0';
713 std::string sz_command = psz_str;
716 msg_Dbg( &sys.demuxer, "command : %s", sz_command.c_str() );
718 #if defined(__GNUC__) && (__GNUC__ < 3)
719 if ( sz_command.compare( CMD_MS_GOTO_AND_PLAY, 0, CMD_MS_GOTO_AND_PLAY.size() ) == 0 )
721 if ( sz_command.compare( 0, CMD_MS_GOTO_AND_PLAY.size(), CMD_MS_GOTO_AND_PLAY ) == 0 )
727 for ( i=CMD_MS_GOTO_AND_PLAY.size(); i<sz_command.size(); i++)
729 if ( sz_command[i] == '(' )
736 for ( j=i; j<sz_command.size(); j++)
738 if ( sz_command[j] == ')' )
745 std::string st = sz_command.substr( i+1, j-i-1 );
746 int64_t i_chapter_uid = atoi( st.c_str() );
748 virtual_segment_c *p_segment;
749 chapter_item_c *p_chapter = sys.FindChapter( i_chapter_uid, p_segment );
751 if ( p_chapter == NULL )
752 msg_Dbg( &sys.demuxer, "Chapter %"PRId64" not found", i_chapter_uid);
755 if ( !p_chapter->EnterAndLeave( sys.p_current_segment->CurrentChapter() ) )
756 p_segment->Seek( sys.demuxer, p_chapter->i_user_start_time, -1, p_chapter, -1 );
764 bool matroska_script_codec_c::Enter()
766 bool f_result = false;
767 std::vector<KaxChapterProcessData*>::iterator index = enter_cmds.begin();
768 while ( index != enter_cmds.end() )
770 if ( (*index)->GetSize() )
772 msg_Dbg( &sys.demuxer, "Matroska Script enter command" );
773 f_result |= interpretor.Interpret( (*index)->GetBuffer(), (*index)->GetSize() );
780 bool matroska_script_codec_c::Leave()
782 bool f_result = false;
783 std::vector<KaxChapterProcessData*>::iterator index = leave_cmds.begin();
784 while ( index != leave_cmds.end() )
786 if ( (*index)->GetSize() )
788 msg_Dbg( &sys.demuxer, "Matroska Script leave command" );
789 f_result |= interpretor.Interpret( (*index)->GetBuffer(), (*index)->GetSize() );