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,206 +27,64 @@
#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();
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 );
vlc_mutex_init( &lock );
vlc_cond_init( &wait );
is_running = false;
}
matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlStream *p_estream, bool b_initial )
event_thread_t::~event_thread_t()
{
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;
ResetPci();
vlc_cond_destroy( &wait );
vlc_mutex_destroy( &lock );
}
ep = new EbmlParser(p_estream, p_l0, &demuxer );
p_segment1->ep = ep;
p_segment1->segment = (KaxSegment*)p_l0;
void event_thread_t::SetPci(const pci_t *data)
{
vlc_mutex_locker l(&lock);
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);
pci_packet = *data;
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];
#ifndef WORDS_BIGENDIAN
for( uint8_t 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;
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;
}
}
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;
if ( !b_keep_stream )
{
delete p_stream1;
p_stream1 = NULL;
}
return p_stream1;
}
void demux_sys_t::StartUiThread()
{
if ( !b_ui_hooked )
for ( uint8_t i = 0; i<3; i++ )
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
if( !is_running )
{
msg_Dbg( &demuxer, "Starting the UI Hook" );
b_ui_hooked = true;
/* 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 );
b_abort = false;
is_running = !vlc_clone( &thread, EventThread, this, VLC_THREAD_PRIORITY_LOW );
}
}
void demux_sys_t::StopUiThread()
void event_thread_t::ResetPci()
{
if ( b_ui_hooked )
{
vlc_object_kill( p_ev );
vlc_thread_join( p_ev );
vlc_object_release( p_ev );
if( !is_running )
return;
p_ev = NULL;
vlc_mutex_lock( &lock );
b_abort = true;
vlc_cond_signal( &wait );
vlc_mutex_unlock( &lock );
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" );
}
b_ui_hooked = false;
vlc_join( thread, NULL );
is_running = false;
}
int demux_sys_t::EventMouse( vlc_object_t *p_this, char const *psz_var,
int event_thread_t::EventMouse( vlc_object_t *p_this, char const *psz_var,
vlc_value_t oldval, vlc_value_t newval, void *p_data )
{
event_thread_t *p_ev = (event_thread_t *) p_data;
......@@ -238,61 +96,82 @@ int demux_sys_t::EventMouse( vlc_object_t *p_this, char const *psz_var,
}
else if( psz_var[6] == 'm' )
p_ev->b_moved = true;
vlc_cond_signal( &p_ev->wait );
vlc_mutex_unlock( &p_ev->lock );
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 )
{
event_thread_t *p_ev = (event_thread_t *) p_data;
vlc_mutex_lock( &p_ev->lock );
p_ev->i_key_action = newval.i_int;
vlc_cond_signal( &p_ev->wait );
vlc_mutex_unlock( &p_ev->lock );
msg_Dbg( p_this, "Event Key");
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_this;
demux_sys_t *p_sys = p_ev->p_demux->p_sys;
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()
{
demux_sys_t *p_sys = p_demux->p_sys;
vlc_object_t *p_vout = NULL;
int canc = vlc_savecancel ();
p_ev->b_moved = false;
p_ev->b_clicked = false;
p_ev->i_key_action = 0;
b_moved = false;
b_clicked = false;
i_key_action = 0;
b_vout = true;
/* 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 */
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 */
msleep( 100000 );
continue;
vlc_mutex_unlock( &lock );
break;
}
bool b_activated = false;
/* KEY part */
if( p_ev->i_key_action )
if( i_key_action )
{
msg_Dbg( p_ev->p_demux, "Handle Key Event");
vlc_mutex_lock( &p_ev->lock );
msg_Dbg( p_demux, "Handle Key Event");
pci_t *pci = (pci_t *) &p_sys->pci_packet;
pci_t *pci = &pci_packet;
uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 );
switch( p_ev->i_key_action )
switch( i_key_action )
{
case ACTIONID_NAV_LEFT:
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 )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode )
{
vlc_mutex_unlock( &p_ev->lock );
vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
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 )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode )
{
vlc_mutex_unlock( &p_ev->lock );
vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
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 )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode )
{
vlc_mutex_unlock( &p_ev->lock );
vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
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 )
btni_t button_ptr = pci->hli.btnit[i_curr_button-1];
if ( button_ptr.auto_action_mode )
{
vlc_mutex_unlock( &p_ev->lock );
vlc_mutex_unlock( &lock );
vlc_mutex_lock( &p_sys->lock_demuxer );
// process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
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 )
{
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 );
// process the button action
p_sys->dvd_interpretor.Interpret( button_ptr.cmd.bytes, 8 );
vlc_mutex_unlock( &p_sys->lock_demuxer );
vlc_mutex_lock( &p_ev->lock );
vlc_mutex_lock( &lock );
}
break;
default:
break;
}
p_ev->i_key_action = 0;
vlc_mutex_unlock( &p_ev->lock );
i_key_action = 0;
}
/* MOUSE part */
if( p_vout && ( p_ev->b_moved || p_ev->b_clicked ) )
if( p_vout && ( b_moved || b_clicked ) )
{
int x, y;
var_GetCoords( p_vout, "mouse-moved", &x, &y );
vlc_mutex_lock( &p_ev->lock );
pci_t *pci = (pci_t *) &p_sys->pci_packet;
pci_t *pci = &pci_packet;
if( p_ev->b_clicked )
if( b_clicked )
{
int32_t button;
int32_t best,dist,d;
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;
// get current button
......@@ -460,7 +337,7 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
uint16 i_curr_button = p_sys->dvd_interpretor.GetSPRM( 0x88 );
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 );
// process the button action
......@@ -511,24 +388,26 @@ void * demux_sys_t::EventThread( vlc_object_t *p_this )
}
}
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 );
}
p_ev->b_moved = false;
p_ev->b_clicked = false;
vlc_mutex_unlock( &p_ev->lock );
b_moved = false;
b_clicked = false;
}
/* VOUT part */
b_vout = false;
vlc_mutex_unlock( &lock );
/* Always check vout */
if( p_vout && !vlc_object_alive (p_vout) )
{
var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev );
var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev );
var_DelCallback( p_vout, "mouse-moved", EventMouse, this );
var_DelCallback( p_vout, "mouse-clicked", EventMouse, this );
vlc_object_release( p_vout );
p_vout = NULL;
}
......@@ -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);
if( p_vout)
{
var_AddCallback( p_vout, "mouse-moved", EventMouse, p_ev );
var_AddCallback( p_vout, "mouse-clicked", EventMouse, p_ev );
var_AddCallback( p_vout, "mouse-moved", EventMouse, this );
var_AddCallback( p_vout, "mouse-clicked", EventMouse, this );
}
}
/* Wait a bit, 10ms */
msleep( 10000 );
}
/* Release callback */
if( p_vout )
{
var_DelCallback( p_vout, "mouse-moved", EventMouse, p_ev );
var_DelCallback( p_vout, "mouse-clicked", EventMouse, p_ev );
var_DelCallback( p_vout, "mouse-moved", EventMouse, this );
var_DelCallback( p_vout, "mouse-clicked", EventMouse, this );
vlc_object_release( p_vout );
}
var_DelCallback( p_ev->p_libvlc, "key-action", EventKey, p_ev );
vlc_mutex_destroy( &p_ev->lock );
var_DelCallback( p_sys->p_input, "intf-event", EventInput, this );
var_DelCallback( p_demux->p_libvlc, "key-action", EventKey, this );
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 )
......@@ -753,31 +818,4 @@ chapter_item_c *demux_sys_t::FindChapter( int64_t i_find_uid, virtual_segment_c
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 {
class virtual_segment_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();
private:
void EventThread();
static void *EventThread(void *);
static int EventMouse( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
static int EventKey( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
static int EventInput( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
demux_t *p_demux;
vlc_mutex_t lock;
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;
} event_thread_t;
bool b_vout;
pci_t pci_packet;
};
class demux_sys_t
......@@ -322,9 +341,7 @@ public:
,p_current_segment(NULL)
,dvd_interpretor( *this )
,f_duration(-1.0)
,b_ui_hooked(false)
,p_input(NULL)
,b_pci_packet_set(false)
,p_ev(NULL)
{
vlc_mutex_init( &lock_demuxer );
......@@ -369,27 +386,16 @@ public:
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 StartUiThread();
void StopUiThread();
bool b_ui_hooked;
void SwapButtons();
void InitUi();
void CleanUi();
/* for spu variables */
input_thread_t *p_input;
pci_t pci_packet;
bool b_pci_packet_set;
uint8_t palette[4][4];
vlc_mutex_t lock_demuxer;
/* event */
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:
virtual_segment_c *VirtualFromSegments( matroska_segment_c *p_segment ) const;
......
......@@ -807,7 +807,6 @@ bool matroska_segment_c::Select( mtime_t i_start_time )
{
/* add all es */
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++ )
{
......@@ -1253,6 +1252,7 @@ bool matroska_segment_c::Select( mtime_t i_start_time )
void matroska_segment_c::UnSelect( )
{
sys.p_ev->ResetPci();
for( size_t i_track = 0; i_track < tracks.size(); i_track++ )
{
if ( tracks[i_track]->p_es != NULL )
......
......@@ -245,7 +245,7 @@ static int Open( vlc_object_t * p_this )
goto error;
}
p_sys->StartUiThread();
p_sys->InitUi();
return VLC_SUCCESS;
......@@ -565,15 +565,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
if ( tk->fmt.i_cat == NAV_ES )
{
// TODO handle the start/stop times of this packet
if ( p_sys->b_ui_hooked )
{
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 );
p_sys->p_ev->SetPci( (const pci_t *)&p_block->p_buffer[1]);
block_Release( p_block );
}
return;
}
// 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