Commit 56fbad8e authored by Laurent Aimar's avatar Laurent Aimar

Reworked how the event thread works in mkv demuxer.

It now uses vlc_clone()
It is started only when needed.
It does not uselessly poll every 100 or 10 milliseconds anymore...
parent b98e1a87
...@@ -27,207 +27,65 @@ ...@@ -27,207 +27,65 @@
#include "Ebml_parser.hpp" #include "Ebml_parser.hpp"
demux_sys_t::~demux_sys_t() event_thread_t::event_thread_t(demux_t *p_demux) : p_demux(p_demux)
{ {
StopUiThread(); vlc_mutex_init( &lock );
size_t i; vlc_cond_init( &wait );
for ( i=0; i<streams.size(); i++ ) is_running = false;
delete streams[i];
for ( i=0; i<opened_segments.size(); i++ )
delete opened_segments[i];
for ( i=0; i<used_segments.size(); i++ )
delete used_segments[i];
for ( i=0; i<stored_attachments.size(); i++ )
delete stored_attachments[i];
if( meta ) vlc_meta_Delete( meta );
while( titles.size() )
{ vlc_input_title_Delete( titles.back() ); titles.pop_back();}
vlc_mutex_destroy( &lock_demuxer );
} }
event_thread_t::~event_thread_t()
matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlStream *p_estream, bool b_initial )
{ {
int i_upper_lvl = 0; ResetPci();
EbmlElement *p_l0, *p_l1, *p_l2; vlc_cond_destroy( &wait );
bool b_keep_stream = false, b_keep_segment; vlc_mutex_destroy( &lock );
}
// verify the EBML Header
p_l0 = p_estream->FindNextID(EBML_INFO(EbmlHead), 0xFFFFFFFFL);
if (p_l0 == NULL)
{
msg_Err( p_demux, "No EBML header found" );
return NULL;
}
// verify we can read this Segment, we only support Matroska version 1 for now
p_l0->Read(*p_estream, EBML_CLASS_CONTEXT(EbmlHead), i_upper_lvl, p_l0, true);
EDocType doc_type = GetChild<EDocType>(*static_cast<EbmlHead*>(p_l0));
if (std::string(doc_type) != "matroska" && std::string(doc_type) != "webm" )
{
msg_Err( p_demux, "Not a Matroska file : DocType = %s ", std::string(doc_type).c_str());
return NULL;
}
EDocTypeReadVersion doc_read_version = GetChild<EDocTypeReadVersion>(*static_cast<EbmlHead*>(p_l0));
if (uint64(doc_read_version) > 2)
{
msg_Err( p_demux, "matroska file needs version %"PRId64" but only versions 1 & 2 supported", uint64(doc_read_version));
return NULL;
}
delete p_l0;
// find all segments in this file
p_l0 = p_estream->FindNextID(EBML_INFO(KaxSegment), 0xFFFFFFFFFLL);
if (p_l0 == NULL)
{
return NULL;
}
matroska_stream_c *p_stream1 = new matroska_stream_c( *this );
while (p_l0 != 0)
{
if ( MKV_IS_ID( p_l0, KaxSegment) )
{
EbmlParser *ep;
matroska_segment_c *p_segment1 = new matroska_segment_c( *this, *p_estream );
b_keep_segment = b_initial;
ep = new EbmlParser(p_estream, p_l0, &demuxer ); void event_thread_t::SetPci(const pci_t *data)
p_segment1->ep = ep; {
p_segment1->segment = (KaxSegment*)p_l0; vlc_mutex_locker l(&lock);
while ((p_l1 = ep->Get())) pci_packet = *data;
{
if (MKV_IS_ID(p_l1, KaxInfo))
{
// find the families of this segment
KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);
p_info->Read(*p_estream, EBML_CLASS_CONTEXT(KaxInfo), i_upper_lvl, p_l2, true); #ifndef WORDS_BIGENDIAN
for( size_t i = 0; i < p_info->ListSize(); i++ ) for( uint8_t button = 1; button <= pci_packet.hli.hl_gi.btn_ns; button++) {
{ btni_t *button_ptr = &(pci_packet.hli.btnit[button-1]);
EbmlElement *l = (*p_info)[i]; binary *p_data = (binary*) button_ptr;
if( MKV_IS_ID( l, KaxSegmentUID ) ) uint16 i_x_start = ((p_data[0] & 0x3F) << 4 ) + ( p_data[1] >> 4 );
{ uint16 i_x_end = ((p_data[1] & 0x03) << 8 ) + p_data[2];
KaxSegmentUID *p_uid = static_cast<KaxSegmentUID*>(l); uint16 i_y_start = ((p_data[3] & 0x3F) << 4 ) + ( p_data[4] >> 4 );
b_keep_segment = (FindSegment( *p_uid ) == NULL); uint16 i_y_end = ((p_data[4] & 0x03) << 8 ) + p_data[5];
if ( !b_keep_segment ) button_ptr->x_start = i_x_start;
break; // this segment is already known button_ptr->x_end = i_x_end;
opened_segments.push_back( p_segment1 ); button_ptr->y_start = i_y_start;
delete p_segment1->p_segment_uid; button_ptr->y_end = i_y_end;
p_segment1->p_segment_uid = new KaxSegmentUID(*p_uid);
}
else if( MKV_IS_ID( l, KaxPrevUID ) )
{
p_segment1->p_prev_segment_uid = new KaxPrevUID( *static_cast<KaxPrevUID*>(l) );
}
else if( MKV_IS_ID( l, KaxNextUID ) )
{
p_segment1->p_next_segment_uid = new KaxNextUID( *static_cast<KaxNextUID*>(l) );
}
else if( MKV_IS_ID( l, KaxSegmentFamily ) )
{
KaxSegmentFamily *p_fam = new KaxSegmentFamily( *static_cast<KaxSegmentFamily*>(l) );
p_segment1->families.push_back( p_fam );
}
}
break;
}
}
if ( b_keep_segment )
{
b_keep_stream = true;
p_stream1->segments.push_back( p_segment1 );
}
else
{
p_segment1->segment = NULL;
delete p_segment1;
}
}
if (p_l0->IsFiniteSize() )
{
p_l0->SkipData(*p_estream, KaxMatroska_Context);
p_l0 = p_estream->FindNextID(EBML_INFO(KaxSegment), 0xFFFFFFFFL);
}
else
{
p_l0 = NULL;
}
}
if ( !b_keep_stream )
{
delete p_stream1;
p_stream1 = NULL;
} }
for ( uint8_t i = 0; i<3; i++ )
return p_stream1; for ( uint8_t j = 0; j<2; j++ )
} pci_packet.hli.btn_colit.btn_coli[i][j] = U32_AT( &pci_packet.hli.btn_colit.btn_coli[i][j] );
#endif
void demux_sys_t::StartUiThread() if( !is_running )
{
if ( !b_ui_hooked )
{ {
msg_Dbg( &demuxer, "Starting the UI Hook" ); b_abort = false;
b_ui_hooked = true; is_running = !vlc_clone( &thread, EventThread, this, VLC_THREAD_PRIORITY_LOW );
/* FIXME hack hack hack hack FIXME */
/* Get p_input and create variable */
p_input = demux_GetParentInput( &demuxer );
var_Create( p_input, "x-start", VLC_VAR_INTEGER );
var_Create( p_input, "y-start", VLC_VAR_INTEGER );
var_Create( p_input, "x-end", VLC_VAR_INTEGER );
var_Create( p_input, "y-end", VLC_VAR_INTEGER );
var_Create( p_input, "color", VLC_VAR_ADDRESS );
var_Create( p_input, "menu-palette", VLC_VAR_ADDRESS );
var_Create( p_input, "highlight", VLC_VAR_BOOL );
var_Create( p_input, "highlight-mutex", VLC_VAR_MUTEX );
/* Now create our event thread catcher */
p_ev = (event_thread_t *) vlc_object_create( &demuxer, sizeof( event_thread_t ) );
p_ev->p_demux = &demuxer;
p_ev->b_die = false;
vlc_mutex_init( &p_ev->lock );
vlc_thread_create( p_ev, EventThread, VLC_THREAD_PRIORITY_LOW );
} }
} }
void event_thread_t::ResetPci()
void demux_sys_t::StopUiThread()
{ {
if ( b_ui_hooked ) if( !is_running )
{ return;
vlc_object_kill( p_ev );
vlc_thread_join( p_ev );
vlc_object_release( p_ev );
p_ev = NULL;
var_Destroy( p_input, "highlight-mutex" );
var_Destroy( p_input, "highlight" );
var_Destroy( p_input, "x-start" );
var_Destroy( p_input, "x-end" );
var_Destroy( p_input, "y-start" );
var_Destroy( p_input, "y-end" );
var_Destroy( p_input, "color" );
var_Destroy( p_input, "menu-palette" );
vlc_object_release( p_input ); vlc_mutex_lock( &lock );
b_abort = true;
vlc_cond_signal( &wait );
vlc_mutex_unlock( &lock );
msg_Dbg( &demuxer, "Stopping the UI Hook" ); vlc_join( thread, NULL );
} is_running = false;
b_ui_hooked = false;
} }
int event_thread_t::EventMouse( vlc_object_t *p_this, char const *psz_var,
int demux_sys_t::EventMouse( vlc_object_t *p_this, char const *psz_var, vlc_value_t oldval, vlc_value_t newval, void *p_data )
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{ {
event_thread_t *p_ev = (event_thread_t *) p_data; event_thread_t *p_ev = (event_thread_t *) p_data;
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &p_ev->lock );
...@@ -238,61 +96,82 @@ int demux_sys_t::EventMouse( vlc_object_t *p_this, char const *psz_var, ...@@ -238,61 +96,82 @@ int demux_sys_t::EventMouse( vlc_object_t *p_this, char const *psz_var,
} }
else if( psz_var[6] == 'm' ) else if( psz_var[6] == 'm' )
p_ev->b_moved = true; p_ev->b_moved = true;
vlc_cond_signal( &p_ev->wait );
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &p_ev->lock );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
int demux_sys_t::EventKey( vlc_object_t *p_this, char const *, int event_thread_t::EventKey( vlc_object_t *p_this, char const *,
vlc_value_t, vlc_value_t newval, void *p_data ) vlc_value_t, vlc_value_t newval, void *p_data )
{ {
event_thread_t *p_ev = (event_thread_t *) p_data; event_thread_t *p_ev = (event_thread_t *) p_data;
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &p_ev->lock );
p_ev->i_key_action = newval.i_int; p_ev->i_key_action = newval.i_int;
vlc_cond_signal( &p_ev->wait );
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &p_ev->lock );
msg_Dbg( p_this, "Event Key"); msg_Dbg( p_this, "Event Key");
return VLC_SUCCESS; return VLC_SUCCESS;
} }
void * demux_sys_t::EventThread( vlc_object_t *p_this ) int event_thread_t::EventInput( vlc_object_t *p_this, char const *,
vlc_value_t, vlc_value_t newval, void *p_data )
{
event_thread_t *p_ev = (event_thread_t *) p_data;
vlc_mutex_lock( &p_ev->lock );
if( newval.i_int == INPUT_EVENT_VOUT )
{
p_ev->b_vout |= true;
vlc_cond_signal( &p_ev->wait );
}
vlc_mutex_unlock( &p_ev->lock );
return VLC_SUCCESS;
}
void event_thread_t::EventThread()
{ {
event_thread_t *p_ev = (event_thread_t*)p_this; demux_sys_t *p_sys = p_demux->p_sys;
demux_sys_t *p_sys = p_ev->p_demux->p_sys;
vlc_object_t *p_vout = NULL; vlc_object_t *p_vout = NULL;
int canc = vlc_savecancel (); int canc = vlc_savecancel ();
p_ev->b_moved = false; b_moved = false;
p_ev->b_clicked = false; b_clicked = false;
p_ev->i_key_action = 0; i_key_action = 0;
b_vout = true;
/* catch all key event */ /* catch all key event */
var_AddCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev ); var_AddCallback( p_demux->p_libvlc, "key-action", EventKey, this );
/* catch input event */
var_AddCallback( p_sys->p_input, "intf-event", EventInput, this );
/* main loop */ /* main loop */
while( vlc_object_alive (p_ev) ) for( ;; )
{ {
if ( !p_sys->b_pci_packet_set ) vlc_mutex_lock( &lock );
while( !b_abort && !i_key_action && !b_moved && !b_clicked && !b_vout)
vlc_cond_wait( &wait, &lock );
if( b_abort )
{ {
/* Wait 100ms */ vlc_mutex_unlock( &lock );
msleep( 100000 ); break;
continue;
} }
bool b_activated = false; bool b_activated = false;
/* KEY part */ /* KEY part */
if( p_ev->i_key_action ) if( i_key_action )
{ {
msg_Dbg( p_ev->p_demux, "Handle Key Event"); msg_Dbg( p_demux, "Handle Key Event");
vlc_mutex_lock( &p_ev->lock );
pci_t *pci = (pci_t *) &p_sys->pci_packet; pci_t *pci = &pci_packet;
uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 ); uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 );
switch( p_ev->i_key_action ) switch( i_key_action )
{ {
case ACTIONID_NAV_LEFT: case ACTIONID_NAV_LEFT:
if ( i_curr_button > 0 && i_curr_button <= pci->hli.hl_gi.btn_ns ) if ( i_curr_button > 0 && i_curr_button <= pci->hli.hl_gi.btn_ns )
...@@ -305,14 +184,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -305,14 +184,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1]; btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode ) if ( button_ptr.auto_action_mode )
{ {
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer ); vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action // process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 ); p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
vlc_mutex_unlock( &p_sys->lock_demuxer ); vlc_mutex_unlock( &p_sys->lock_demuxer );
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &lock );
} }
} }
} }
...@@ -328,14 +207,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -328,14 +207,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1]; btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode ) if ( button_ptr.auto_action_mode )
{ {
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer ); vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action // process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 ); p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
vlc_mutex_unlock( &p_sys->lock_demuxer ); vlc_mutex_unlock( &p_sys->lock_demuxer );
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &lock );
} }
} }
} }
...@@ -351,14 +230,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -351,14 +230,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1]; btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode ) if ( button_ptr.auto_action_mode )
{ {
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer ); vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action // process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 ); p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
vlc_mutex_unlock( &p_sys->lock_demuxer ); vlc_mutex_unlock( &p_sys->lock_demuxer );
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &lock );
} }
} }
} }
...@@ -374,14 +253,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -374,14 +253,14 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1]; btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode ) if ( button_ptr.auto_action_mode )
{ {
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer ); vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action // process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 ); p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
vlc_mutex_unlock( &p_sys->lock_demuxer ); vlc_mutex_unlock( &p_sys->lock_demuxer );
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &lock );
} }
} }
} }
...@@ -393,39 +272,37 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -393,39 +272,37 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
{ {
btni_t button_ptr = pci->hli.btnit[i_curr_button-1]; btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer ); vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action // process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 ); p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
vlc_mutex_unlock( &p_sys->lock_demuxer ); vlc_mutex_unlock( &p_sys->lock_demuxer );
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &lock );
} }
break; break;
default: default:
break; break;
} }
p_ev->i_key_action = 0; i_key_action = 0;
vlc_mutex_unlock( &p_ev->lock );
} }
/* MOUSE part */ /* MOUSE part */
if( p_vout && ( p_ev->b_moved || p_ev->b_clicked ) ) if( p_vout && ( b_moved || b_clicked ) )
{ {
int x, y; int x, y;
var_GetCoords( p_vout, "mouse-moved", &x, &y ); var_GetCoords( p_vout, "mouse-moved", &x, &y );
vlc_mutex_lock( &p_ev->lock ); pci_t *pci = &pci_packet;
pci_t *pci = (pci_t *) &p_sys->pci_packet;
if( p_ev->b_clicked ) if( b_clicked )
{ {
int32_t button; int32_t button;
int32_t best,dist,d; int32_t best,dist,d;
int32_t mx,my,dx,dy; int32_t mx,my,dx,dy;
msg_Dbg( p_ev->p_demux, "Handle Mouse Event: Mouse clicked x(%d)*y(%d)", x, y); msg_Dbg( p_demux, "Handle Mouse Event: Mouse clicked x(%d)*y(%d)", x, y);
b_activated = true; b_activated = true;
// get current button // get current button
...@@ -460,7 +337,7 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -460,7 +337,7 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 ); uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 );
msg_Dbg( &p_sys->demuxer, "Clicked button %d", best ); msg_Dbg( &p_sys->demuxer, "Clicked button %d", best );
vlc_mutex_unlock( &p_ev->lock ); vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer ); vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action // process the button action
...@@ -511,24 +388,26 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -511,24 +388,26 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
} }
} }
vlc_mutex_unlock( &p_sys->lock_demuxer ); vlc_mutex_unlock( &p_sys->lock_demuxer );
vlc_mutex_lock( &p_ev->lock ); vlc_mutex_lock( &lock );
} }
} }
else if( p_ev->b_moved ) else if( b_moved )
{ {
// dvdnav_mouse_select( NULL, pci, x, y ); // dvdnav_mouse_select( NULL, pci, x, y );
} }
p_ev->b_moved = false; b_moved = false;
p_ev->b_clicked = false; b_clicked = false;
vlc_mutex_unlock( &p_ev->lock );
} }
/* VOUT part */ b_vout = false;
vlc_mutex_unlock( &lock );
/* Always check vout */
if( p_vout && !vlc_object_alive (p_vout) ) if( p_vout && !vlc_object_alive (p_vout) )
{ {
var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev ); var_DelCallback( p_vout, "mouse-moved", EventMouse, this );
var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev ); var_DelCallback( p_vout, "mouse-clicked", EventMouse, this );
vlc_object_release( p_vout ); vlc_object_release( p_vout );
p_vout = NULL; p_vout = NULL;
} }
...@@ -538,28 +417,214 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this ) ...@@ -538,28 +417,214 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
p_vout = (vlc_object_t*) input_GetVout(p_sys->p_input); p_vout = (vlc_object_t*) input_GetVout(p_sys->p_input);
if( p_vout) if( p_vout)
{ {
var_AddCallback( p_vout, "mouse-moved", EventMouse, p_ev ); var_AddCallback( p_vout, "mouse-moved", EventMouse, this );
var_AddCallback( p_vout, "mouse-clicked", EventMouse, p_ev ); var_AddCallback( p_vout, "mouse-clicked", EventMouse, this );
} }
} }
/* Wait a bit, 10ms */
msleep( 10000 );
} }
/* Release callback */ /* Release callback */
if( p_vout ) if( p_vout )
{ {
var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev ); var_DelCallback( p_vout, "mouse-moved", EventMouse, this );
var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev ); var_DelCallback( p_vout, "mouse-clicked", EventMouse, this );
vlc_object_release( p_vout ); vlc_object_release( p_vout );
} }
var_DelCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev ); var_DelCallback( p_sys->p_input, "intf-event", EventInput, this );
var_DelCallback( p_demux->p_libvlc, "key-action", EventKey, this );
vlc_mutex_destroy( &p_ev->lock );
vlc_restorecancel (canc); vlc_restorecancel (canc);
return VLC_SUCCESS; }
void *event_thread_t::EventThread(void *data)
{
static_cast<event_thread_t*>(data)->EventThread();
return NULL;
}
demux_sys_t::~demux_sys_t()
{
CleanUi();
size_t i;
for ( i=0; i<streams.size(); i++ )
delete streams[i];
for ( i=0; i<opened_segments.size(); i++ )
delete opened_segments[i];
for ( i=0; i<used_segments.size(); i++ )
delete used_segments[i];
for ( i=0; i<stored_attachments.size(); i++ )
delete stored_attachments[i];
if( meta ) vlc_meta_Delete( meta );
while( titles.size() )
{ vlc_input_title_Delete( titles.back() ); titles.pop_back();}
vlc_mutex_destroy( &lock_demuxer );
}
matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlStream *p_estream, bool b_initial )
{
int i_upper_lvl = 0;
EbmlElement *p_l0, *p_l1, *p_l2;
bool b_keep_stream = false, b_keep_segment;
// verify the EBML Header
p_l0 = p_estream->FindNextID(EBML_INFO(EbmlHead), 0xFFFFFFFFL);
if (p_l0 == NULL)
{
msg_Err( p_demux, "No EBML header found" );
return NULL;
}
// verify we can read this Segment, we only support Matroska version 1 for now
p_l0->Read(*p_estream, EBML_CLASS_CONTEXT(EbmlHead), i_upper_lvl, p_l0, true);
EDocType doc_type = GetChild<EDocType>(*static_cast<EbmlHead*>(p_l0));
if (std::string(doc_type) != "matroska" && std::string(doc_type) != "webm" )
{
msg_Err( p_demux, "Not a Matroska file : DocType = %s ", std::string(doc_type).c_str());
return NULL;
}
EDocTypeReadVersion doc_read_version = GetChild<EDocTypeReadVersion>(*static_cast<EbmlHead*>(p_l0));
if (uint64(doc_read_version) > 2)
{
msg_Err( p_demux, "matroska file needs version %"PRId64" but only versions 1 & 2 supported", uint64(doc_read_version));
return NULL;
}
delete p_l0;
// find all segments in this file
p_l0 = p_estream->FindNextID(EBML_INFO(KaxSegment), 0xFFFFFFFFFLL);
if (p_l0 == NULL)
{
return NULL;
}
matroska_stream_c *p_stream1 = new matroska_stream_c( *this );
while (p_l0 != 0)
{
if ( MKV_IS_ID( p_l0, KaxSegment) )
{
EbmlParser *ep;
matroska_segment_c *p_segment1 = new matroska_segment_c( *this, *p_estream );
b_keep_segment = b_initial;
ep = new EbmlParser(p_estream, p_l0, &demuxer );
p_segment1->ep = ep;
p_segment1->segment = (KaxSegment*)p_l0;
while ((p_l1 = ep->Get()))
{
if (MKV_IS_ID(p_l1, KaxInfo))
{
// find the families of this segment
KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);
p_info->Read(*p_estream, EBML_CLASS_CONTEXT(KaxInfo), i_upper_lvl, p_l2, true);
for( size_t i = 0; i < p_info->ListSize(); i++ )
{
EbmlElement *l = (*p_info)[i];
if( MKV_IS_ID( l, KaxSegmentUID ) )
{
KaxSegmentUID *p_uid = static_cast<KaxSegmentUID*>(l);
b_keep_segment = (FindSegment( *p_uid ) == NULL);
if ( !b_keep_segment )
break; // this segment is already known
opened_segments.push_back( p_segment1 );
delete p_segment1->p_segment_uid;
p_segment1->p_segment_uid = new KaxSegmentUID(*p_uid);
}
else if( MKV_IS_ID( l, KaxPrevUID ) )
{
p_segment1->p_prev_segment_uid = new KaxPrevUID( *static_cast<KaxPrevUID*>(l) );
}
else if( MKV_IS_ID( l, KaxNextUID ) )
{
p_segment1->p_next_segment_uid = new KaxNextUID( *static_cast<KaxNextUID*>(l) );
}
else if( MKV_IS_ID( l, KaxSegmentFamily ) )
{
KaxSegmentFamily *p_fam = new KaxSegmentFamily( *static_cast<KaxSegmentFamily*>(l) );
p_segment1->families.push_back( p_fam );
}
}
break;
}
}
if ( b_keep_segment )
{
b_keep_stream = true;
p_stream1->segments.push_back( p_segment1 );
}
else
{
p_segment1->segment = NULL;
delete p_segment1;
}
}
if (p_l0->IsFiniteSize() )
{
p_l0->SkipData(*p_estream, KaxMatroska_Context);
p_l0 = p_estream->FindNextID(EBML_INFO(KaxSegment), 0xFFFFFFFFL);
}
else
{
p_l0 = NULL;
}
}
if ( !b_keep_stream )
{
delete p_stream1;
p_stream1 = NULL;
}
return p_stream1;
}
void demux_sys_t::InitUi()
{
msg_Dbg( &demuxer, "Starting the UI Hook" );
/* FIXME hack hack hack hack FIXME */
/* Get p_input and create variable */
p_input = demux_GetParentInput( &demuxer );
var_Create( p_input, "x-start", VLC_VAR_INTEGER );
var_Create( p_input, "y-start", VLC_VAR_INTEGER );
var_Create( p_input, "x-end", VLC_VAR_INTEGER );
var_Create( p_input, "y-end", VLC_VAR_INTEGER );
var_Create( p_input, "color", VLC_VAR_ADDRESS );
var_Create( p_input, "menu-palette", VLC_VAR_ADDRESS );
var_Create( p_input, "highlight", VLC_VAR_BOOL );
var_Create( p_input, "highlight-mutex", VLC_VAR_MUTEX );
/* Now create our event thread catcher */
p_ev = new event_thread_t(&demuxer);
}
void demux_sys_t::CleanUi()
{
delete p_ev;
p_ev = NULL;
var_Destroy( p_input, "highlight-mutex" );
var_Destroy( p_input, "highlight" );
var_Destroy( p_input, "x-start" );
var_Destroy( p_input, "x-end" );
var_Destroy( p_input, "y-start" );
var_Destroy( p_input, "y-end" );
var_Destroy( p_input, "color" );
var_Destroy( p_input, "menu-palette" );
vlc_object_release( p_input );
msg_Dbg( &demuxer, "Stopping the UI Hook" );
} }
void demux_sys_t::PreloadFamily( const matroska_segment_c & of_segment ) void demux_sys_t::PreloadFamily( const matroska_segment_c & of_segment )
...@@ -753,31 +818,4 @@ chapter_item_c *demux_sys_t::FindChapter( int64_t i_find_uid, virtual_segment_c ...@@ -753,31 +818,4 @@ chapter_item_c *demux_sys_t::FindChapter( int64_t i_find_uid, virtual_segment_c
return p_result; return p_result;
} }
void demux_sys_t::SwapButtons()
{
#ifndef WORDS_BIGENDIAN
uint8_t button, i, j;
for( button = 1; button <= pci_packet.hli.hl_gi.btn_ns; button++) {
btni_t *button_ptr = &(pci_packet.hli.btnit[button-1]);
binary *p_data = (binary*) button_ptr;
uint16 i_x_start = ((p_data[0] & 0x3F) << 4 ) + ( p_data[1] >> 4 );
uint16 i_x_end = ((p_data[1] & 0x03) << 8 ) + p_data[2];
uint16 i_y_start = ((p_data[3] & 0x3F) << 4 ) + ( p_data[4] >> 4 );
uint16 i_y_end = ((p_data[4] & 0x03) << 8 ) + p_data[5];
button_ptr->x_start = i_x_start;
button_ptr->x_end = i_x_end;
button_ptr->y_start = i_y_start;
button_ptr->y_end = i_y_end;
}
for ( i = 0; i<3; i++ )
{
for ( j = 0; j<2; j++ )
{
pci_packet.hli.btn_colit.btn_coli[i][j] = U32_AT( &pci_packet.hli.btn_colit.btn_coli[i][j] );
}
}
#endif
}
...@@ -295,18 +295,37 @@ typedef struct { ...@@ -295,18 +295,37 @@ typedef struct {
class virtual_segment_c; class virtual_segment_c;
class chapter_item_c; class chapter_item_c;
typedef struct class event_thread_t
{ {
VLC_COMMON_MEMBERS public:
event_thread_t(demux_t *);
virtual ~event_thread_t();
void SetPci(const pci_t *data);
void ResetPci();
demux_t *p_demux; private:
vlc_mutex_t lock; void EventThread();
static void *EventThread(void *);
bool b_moved; static int EventMouse( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
bool b_clicked; static int EventKey( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
int i_key_action; static int EventInput( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
} event_thread_t; demux_t *p_demux;
bool is_running;
vlc_thread_t thread;
vlc_mutex_t lock;
vlc_cond_t wait;
bool b_abort;
bool b_moved;
bool b_clicked;
int i_key_action;
bool b_vout;
pci_t pci_packet;
};
class demux_sys_t class demux_sys_t
...@@ -322,9 +341,7 @@ public: ...@@ -322,9 +341,7 @@ public:
,p_current_segment(NULL) ,p_current_segment(NULL)
,dvd_interpretor( *this ) ,dvd_interpretor( *this )
,f_duration(-1.0) ,f_duration(-1.0)
,b_ui_hooked(false)
,p_input(NULL) ,p_input(NULL)
,b_pci_packet_set(false)
,p_ev(NULL) ,p_ev(NULL)
{ {
vlc_mutex_init( &lock_demuxer ); vlc_mutex_init( &lock_demuxer );
...@@ -369,27 +386,16 @@ public: ...@@ -369,27 +386,16 @@ public:
matroska_stream_c *AnalyseAllSegmentsFound( demux_t *p_demux, EbmlStream *p_estream, bool b_initial = false ); matroska_stream_c *AnalyseAllSegmentsFound( demux_t *p_demux, EbmlStream *p_estream, bool b_initial = false );
void JumpTo( virtual_segment_c & p_segment, chapter_item_c * p_chapter ); void JumpTo( virtual_segment_c & p_segment, chapter_item_c * p_chapter );
void StartUiThread(); void InitUi();
void StopUiThread(); void CleanUi();
bool b_ui_hooked;
void SwapButtons();
/* for spu variables */ /* for spu variables */
input_thread_t *p_input; input_thread_t *p_input;
pci_t pci_packet;
bool b_pci_packet_set;
uint8_t palette[4][4]; uint8_t palette[4][4];
vlc_mutex_t lock_demuxer; vlc_mutex_t lock_demuxer;
/* event */ /* event */
event_thread_t *p_ev; event_thread_t *p_ev;
static void * EventThread( vlc_object_t *p_this );
static int EventMouse( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data );
static int EventKey( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data );
protected: protected:
virtual_segment_c *VirtualFromSegments( matroska_segment_c *p_segment ) const; virtual_segment_c *VirtualFromSegments( matroska_segment_c *p_segment ) const;
......
...@@ -807,7 +807,6 @@ bool matroska_segment_c::Select( mtime_t i_start_time ) ...@@ -807,7 +807,6 @@ bool matroska_segment_c::Select( mtime_t i_start_time )
{ {
/* add all es */ /* add all es */
msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() ); msg_Dbg( &sys.demuxer, "found %d es", (int)tracks.size() );
sys.b_pci_packet_set = false;
for( size_t i_track = 0; i_track < tracks.size(); i_track++ ) for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
{ {
...@@ -1253,6 +1252,7 @@ bool matroska_segment_c::Select( mtime_t i_start_time ) ...@@ -1253,6 +1252,7 @@ bool matroska_segment_c::Select( mtime_t i_start_time )
void matroska_segment_c::UnSelect( ) void matroska_segment_c::UnSelect( )
{ {
sys.p_ev->ResetPci();
for( size_t i_track = 0; i_track < tracks.size(); i_track++ ) for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
{ {
if ( tracks[i_track]->p_es != NULL ) if ( tracks[i_track]->p_es != NULL )
......
...@@ -245,7 +245,7 @@ static int Open( vlc_object_t * p_this ) ...@@ -245,7 +245,7 @@ static int Open( vlc_object_t * p_this )
goto error; goto error;
} }
p_sys->StartUiThread(); p_sys->InitUi();
return VLC_SUCCESS; return VLC_SUCCESS;
...@@ -565,15 +565,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock ...@@ -565,15 +565,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
if ( tk->fmt.i_cat == NAV_ES ) if ( tk->fmt.i_cat == NAV_ES )
{ {
// TODO handle the start/stop times of this packet // TODO handle the start/stop times of this packet
if ( p_sys->b_ui_hooked ) p_sys->p_ev->SetPci( (const pci_t *)&p_block->p_buffer[1]);
{ block_Release( p_block );
vlc_mutex_lock( &p_sys->p_ev->lock );
memcpy( &p_sys->pci_packet, &p_block->p_buffer[1], sizeof(pci_t) );
p_sys->SwapButtons();
p_sys->b_pci_packet_set = true;
vlc_mutex_unlock( &p_sys->p_ev->lock );
block_Release( p_block );
}
return; return;
} }
// correct timestamping when B frames are used // correct timestamping when B frames are used
......
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