Commit d4342f69 authored by Steve Lhomme's avatar Steve Lhomme

mkv.cpp: add support for the JumpSS DVD command

parent 29201bc2
...@@ -814,7 +814,9 @@ protected: ...@@ -814,7 +814,9 @@ protected:
// callbacks when browsing inside CodecPrivate // callbacks when browsing inside CodecPrivate
static bool MatchIsDomain ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ); static bool MatchIsDomain ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
static bool MatchIsVMG ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
static bool MatchVTSNumber ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ); static bool MatchVTSNumber ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
static bool MatchVTSMNumber ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
static bool MatchTitleNumber ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ); static bool MatchTitleNumber ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
static bool MatchPgcType ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ); static bool MatchPgcType ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
static bool MatchPgcNumber ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ); static bool MatchPgcNumber ( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size );
...@@ -950,7 +952,7 @@ public: ...@@ -950,7 +952,7 @@ public:
bool Enter( bool b_do_subchapters ); bool Enter( bool b_do_subchapters );
bool Leave( bool b_do_subchapters ); bool Leave( bool b_do_subchapters );
bool EnterAndLeave( chapter_item_c *p_item ); bool EnterAndLeave( chapter_item_c *p_item, bool b_enter = true );
}; };
class chapter_edition_c : public chapter_item_c class chapter_edition_c : public chapter_item_c
...@@ -2791,7 +2793,7 @@ bool virtual_segment_c::UpdateCurrentToChapter( demux_t & demux ) ...@@ -2791,7 +2793,7 @@ bool virtual_segment_c::UpdateCurrentToChapter( demux_t & demux )
// out of the scope of the data described by chapters, leave the edition // out of the scope of the data described by chapters, leave the edition
if ( (*p_editions)[i_current_edition]->b_ordered && psz_current_chapter != NULL ) if ( (*p_editions)[i_current_edition]->b_ordered && psz_current_chapter != NULL )
{ {
if ( !(*p_editions)[i_current_edition]->EnterAndLeave( psz_current_chapter ) ) if ( !(*p_editions)[i_current_edition]->EnterAndLeave( psz_current_chapter, false ) )
psz_current_chapter = NULL; psz_current_chapter = NULL;
else else
return true; return true;
...@@ -5414,7 +5416,7 @@ bool chapter_item_c::Leave( bool b_do_subs ) ...@@ -5414,7 +5416,7 @@ bool chapter_item_c::Leave( bool b_do_subs )
return f_result; return f_result;
} }
bool chapter_item_c::EnterAndLeave( chapter_item_c *p_item ) bool chapter_item_c::EnterAndLeave( chapter_item_c *p_item, bool b_final_enter )
{ {
chapter_item_c *p_common_parent = p_item; chapter_item_c *p_common_parent = p_item;
...@@ -5449,7 +5451,10 @@ bool chapter_item_c::EnterAndLeave( chapter_item_c *p_item ) ...@@ -5449,7 +5451,10 @@ bool chapter_item_c::EnterAndLeave( chapter_item_c *p_item )
} while ( 1 ); } while ( 1 );
} }
if ( b_final_enter )
return Enter( true ); return Enter( true );
else
return false;
} }
bool dvd_chapter_codec_c::Enter() bool dvd_chapter_codec_c::Enter()
...@@ -5596,37 +5601,39 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si ...@@ -5596,37 +5601,39 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si
} }
case CMD_DVD_CALLSS_VTSM1: case CMD_DVD_CALLSS_VTSM1:
{ {
msg_Dbg( &sys.demuxer, "CallSS VTSM" ); msg_Dbg( &sys.demuxer, "CallSS" );
binary p_type;
switch( (p_command[6] & 0xC0) >> 6 ) { switch( (p_command[6] & 0xC0) >> 6 ) {
case 0: case 0:
switch ( p_command[5] ) p_type = p_command[5] & 0x0F;
switch ( p_type )
{ {
case 0x00: case 0x00:
msg_Dbg( &sys.demuxer, "CallSS PGC (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS PGC (rsm_cell %x)", p_command[4]);
break; break;
case 0x82: case 0x02:
msg_Dbg( &sys.demuxer, "CallSS Title Entry (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS Title Entry (rsm_cell %x)", p_command[4]);
break; break;
case 0x83: case 0x03:
msg_Dbg( &sys.demuxer, "CallSS Root Menu (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS Root Menu (rsm_cell %x)", p_command[4]);
break; break;
case 0x84: case 0x04:
msg_Dbg( &sys.demuxer, "CallSS Subpicture Menu (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS Subpicture Menu (rsm_cell %x)", p_command[4]);
break; break;
case 0x85: case 0x05:
msg_Dbg( &sys.demuxer, "CallSS Audio Menu (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS Audio Menu (rsm_cell %x)", p_command[4]);
break; break;
case 0x86: case 0x06:
msg_Dbg( &sys.demuxer, "CallSS Angle Menu (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS Angle Menu (rsm_cell %x)", p_command[4]);
break; break;
case 0x87: case 0x07:
msg_Dbg( &sys.demuxer, "CallSS Chapter Menu (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS Chapter Menu (rsm_cell %x)", p_command[4]);
break; break;
default: default:
msg_Dbg( &sys.demuxer, "CallSS <unknown> (rsm_cell %x)", p_command[5]); msg_Dbg( &sys.demuxer, "CallSS <unknown> (rsm_cell %x)", p_command[4]);
break; break;
} }
p_chapter = sys.BrowseCodecPrivate( 1, MatchPgcType, &p_command[5], 1, p_segment ); p_chapter = sys.BrowseCodecPrivate( 1, MatchPgcType, &p_type, 1, p_segment );
if ( p_segment != NULL ) if ( p_segment != NULL )
{ {
sys.JumpTo( *p_segment, p_chapter ); sys.JumpTo( *p_segment, p_chapter );
...@@ -5634,13 +5641,114 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si ...@@ -5634,13 +5641,114 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si
} }
break; break;
case 1: case 1:
msg_Dbg( &sys.demuxer, "CallSS VMGM (menu %d, rsm_cell %x)", p_command[6] & 0x0F, p_command[5]); msg_Dbg( &sys.demuxer, "CallSS VMGM (menu %d, rsm_cell %x)", p_command[5] & 0x0F, p_command[4]);
break; break;
case 2: case 2:
msg_Dbg( &sys.demuxer, "CallSS VTSM (menu %d, rsm_cell %x)", p_command[6] & 0x0F, p_command[5]); msg_Dbg( &sys.demuxer, "CallSS VTSM (menu %d, rsm_cell %x)", p_command[5] & 0x0F, p_command[4]);
break;
case 3:
msg_Dbg( &sys.demuxer, "CallSS VMGM (pgc %d, rsm_cell %x)", (p_command[2] << 8) + p_command[3], p_command[4]);
break;
}
break;
}
case CMD_DVD_JUMP_SS:
{
msg_Dbg( &sys.demuxer, "JumpSS");
binary p_type;
switch( (p_command[5] & 0xC0) >> 6 ) {
case 0:
msg_Dbg( &sys.demuxer, "JumpSS FP");
break;
case 1:
p_type = p_command[5] & 0x0F;
switch ( p_type )
{
case 0x02:
msg_Dbg( &sys.demuxer, "JumpSS VMGM Title Entry");
break;
case 0x03:
msg_Dbg( &sys.demuxer, "JumpSS VMGM Root Menu");
break;
case 0x04:
msg_Dbg( &sys.demuxer, "JumpSS VMGM Subpicture Menu");
break;
case 0x05:
msg_Dbg( &sys.demuxer, "JumpSS VMGM Audio Menu");
break;
case 0x06:
msg_Dbg( &sys.demuxer, "JumpSS VMGM Angle Menu");
break;
case 0x07:
msg_Dbg( &sys.demuxer, "JumpSS VMGM Chapter Menu");
break;
default:
msg_Dbg( &sys.demuxer, "JumpSS <unknown>");
break;
}
// find the VMG
p_chapter = sys.BrowseCodecPrivate( 1, MatchIsVMG, NULL, 0, p_segment );
if ( p_segment != NULL )
{
p_chapter = p_segment->BrowseCodecPrivate( 1, MatchPgcType, &p_type, 1 );
if ( p_chapter != NULL )
{
sys.JumpTo( *p_segment, p_chapter );
f_result = true;
}
}
break;
case 2:
p_type = p_command[5] & 0x0F;
switch ( p_type )
{
case 0x02:
msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Title Entry", p_command[4], p_command[3]);
break;
case 0x03:
msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Root Menu", p_command[4], p_command[3]);
break;
case 0x04:
msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Subpicture Menu", p_command[4], p_command[3]);
break;
case 0x05:
msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Audio Menu", p_command[4], p_command[3]);
break;
case 0x06:
msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Angle Menu", p_command[4], p_command[3]);
break;
case 0x07:
msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) Chapter Menu", p_command[4], p_command[3]);
break;
default:
msg_Dbg( &sys.demuxer, "JumpSS VTSM (vts %d, ttn %d) <unknown>", p_command[4], p_command[3]);
break;
}
p_chapter = sys.BrowseCodecPrivate( 1, MatchVTSMNumber, &p_command[4], 1, p_segment );
if ( p_segment != NULL && p_chapter != NULL )
{
// find the title in the VTS
p_chapter = p_chapter->BrowseCodecPrivate( 1, MatchTitleNumber, &p_command[3], 1 );
if ( p_chapter != NULL )
{
// find the specified menu in the VTSM
p_chapter = p_segment->BrowseCodecPrivate( 1, MatchPgcType, &p_type, 1 );
if ( p_chapter != NULL )
{
sys.JumpTo( *p_segment, p_chapter );
f_result = true;
}
}
else
msg_Dbg( &sys.demuxer, "Title (%d) does not exist in this VTS", p_command[3] );
}
else
msg_Dbg( &sys.demuxer, "DVD Domain VTS (%d) not found", p_command[4] );
break; break;
case 3: case 3:
msg_Dbg( &sys.demuxer, "CallSS VMGM (pgc %d, rsm_cell %x)", (p_command[3] << 8) + p_command[4], p_command[5]); msg_Dbg( &sys.demuxer, "JumpSS VMGM (pgc %d)", (p_command[2] << 8) + p_command[3]);
break; break;
} }
break; break;
...@@ -5756,7 +5864,15 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si ...@@ -5756,7 +5864,15 @@ bool dvd_command_interpretor_c::Interpret( const binary * p_command, size_t i_si
bool dvd_command_interpretor_c::MatchIsDomain( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ) bool dvd_command_interpretor_c::MatchIsDomain( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
{ {
return ( data.p_private_data->GetBuffer()[0] == MATROSKA_DVD_LEVEL_SS ); return ( data.p_private_data != NULL && data.p_private_data->GetBuffer()[0] == MATROSKA_DVD_LEVEL_SS );
}
bool dvd_command_interpretor_c::MatchIsVMG( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
{
if ( data.p_private_data == NULL || data.p_private_data->GetSize() < 2 )
return false;
return ( data.p_private_data->GetBuffer()[0] == MATROSKA_DVD_LEVEL_SS && data.p_private_data->GetBuffer()[1] == 0xC0);
} }
bool dvd_command_interpretor_c::MatchVTSNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ) bool dvd_command_interpretor_c::MatchVTSNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
...@@ -5773,6 +5889,20 @@ bool dvd_command_interpretor_c::MatchVTSNumber( const chapter_codec_cmds_c &data ...@@ -5773,6 +5889,20 @@ bool dvd_command_interpretor_c::MatchVTSNumber( const chapter_codec_cmds_c &data
return (i_gtitle == i_title); return (i_gtitle == i_title);
} }
bool dvd_command_interpretor_c::MatchVTSMNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
{
if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 4 )
return false;
if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_SS || data.p_private_data->GetBuffer()[1] != 0x40 )
return false;
uint8 i_gtitle = data.p_private_data->GetBuffer()[3];
uint8 i_title = *(uint8*)p_cookie;
return (i_gtitle == i_title);
}
bool dvd_command_interpretor_c::MatchTitleNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size ) bool dvd_command_interpretor_c::MatchTitleNumber( const chapter_codec_cmds_c &data, const void *p_cookie, size_t i_cookie_size )
{ {
if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 4 ) if ( i_cookie_size != 1 || data.p_private_data == NULL || data.p_private_data->GetSize() < 4 )
...@@ -5795,7 +5925,7 @@ bool dvd_command_interpretor_c::MatchPgcType( const chapter_codec_cmds_c &data, ...@@ -5795,7 +5925,7 @@ bool dvd_command_interpretor_c::MatchPgcType( const chapter_codec_cmds_c &data,
if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_PGC ) if ( data.p_private_data->GetBuffer()[0] != MATROSKA_DVD_LEVEL_PGC )
return false; return false;
uint8 i_pgc_type = data.p_private_data->GetBuffer()[3]; uint8 i_pgc_type = data.p_private_data->GetBuffer()[3] & 0x0F;
uint8 i_pgc = *(uint8*)p_cookie; uint8 i_pgc = *(uint8*)p_cookie;
return (i_pgc_type == i_pgc); return (i_pgc_type == i_pgc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment