|
|
|
@ -140,63 +140,91 @@ int ao_fifo_arts_delay()
|
|
|
|
|
return (int)(1000 * Arts::AudioSubSystem::the()->outputDelay());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xinePlayObject_impl::xinePlayObject_impl(bool audioOnly)
|
|
|
|
|
: mrl( "" ), xine( 0 ), stream( 0 ), queue( 0 ), ao_port( 0 ), vo_port( 0 ), audioOnly(audioOnly)
|
|
|
|
|
{
|
|
|
|
|
static int xine_play_object_x_errhandler( Display *dpy, XErrorEvent *err ) {
|
|
|
|
|
if ( err->error_code == BadWindow ) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
else if ( err->error_code == BadMatch &&
|
|
|
|
|
err->request_code == 42 /* X_SetInputFocus */ ) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!audioOnly)
|
|
|
|
|
{
|
|
|
|
|
XInitThreads();
|
|
|
|
|
char errstr[256];
|
|
|
|
|
XGetErrorText( dpy, err->error_code, errstr, 256 );
|
|
|
|
|
arts_warning( "X Error: %s %d\n"
|
|
|
|
|
" Major opcode: %d\n"
|
|
|
|
|
" Minor opcode: %d\n"
|
|
|
|
|
" Resource id: 0x%lx",
|
|
|
|
|
errstr, err->error_code,
|
|
|
|
|
err->request_code,
|
|
|
|
|
err->minor_code,
|
|
|
|
|
err->resourceid );
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!(display = XOpenDisplay( NULL )))
|
|
|
|
|
{
|
|
|
|
|
arts_fatal( "could not open X11 display" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XFlush( display );
|
|
|
|
|
static int xine_play_object_xio_errhandler( Display * ) {
|
|
|
|
|
arts_fatal( "Fatal IO error: client killed" );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Create a special window for uninterrupted X11 communication
|
|
|
|
|
xcomWindow = XCreateSimpleWindow( display, DefaultRootWindow( display ),
|
|
|
|
|
0, 0, 1, 1, 0, 0, 0 );
|
|
|
|
|
xinePlayObject_impl::xinePlayObject_impl(bool audioOnly)
|
|
|
|
|
: mrl( "" ), xine( 0 ), stream( 0 ), queue( 0 ), ao_port( 0 ), vo_port( 0 ), audioOnly(audioOnly)
|
|
|
|
|
{
|
|
|
|
|
if (!audioOnly) {
|
|
|
|
|
XInitThreads();
|
|
|
|
|
|
|
|
|
|
if (!(display = XOpenDisplay( NULL ))) {
|
|
|
|
|
arts_fatal( "could not open X11 display" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
XSelectInput( display, xcomWindow, ExposureMask );
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_init( &mutex, 0 );
|
|
|
|
|
// Install default error handlers
|
|
|
|
|
XSetErrorHandler( xine_play_object_x_errhandler );
|
|
|
|
|
XSetIOErrorHandler( xine_play_object_xio_errhandler );
|
|
|
|
|
|
|
|
|
|
if (!audioOnly)
|
|
|
|
|
{
|
|
|
|
|
// Initialize X11 properties
|
|
|
|
|
xcomAtomQuit = XInternAtom( display, "VPO_INTERNAL_EVENT", False );
|
|
|
|
|
xcomAtomResize = XInternAtom( display, "VPO_RESIZE_NOTIFY", False );
|
|
|
|
|
screen = DefaultScreen( display );
|
|
|
|
|
shmCompletionType = (XShmQueryExtension( display ) == True)
|
|
|
|
|
? XShmGetEventBase( display ) + ShmCompletion : -1;
|
|
|
|
|
|
|
|
|
|
width = 0;
|
|
|
|
|
height = 0;
|
|
|
|
|
dscbTimeOut = 0;
|
|
|
|
|
|
|
|
|
|
// Initialize xine visual structure
|
|
|
|
|
visual.display = display;
|
|
|
|
|
visual.screen = screen;
|
|
|
|
|
visual.d = xcomWindow;
|
|
|
|
|
visual.dest_size_cb = &dest_size_cb;
|
|
|
|
|
visual.frame_output_cb = &frame_output_cb;
|
|
|
|
|
visual.user_data = this;
|
|
|
|
|
}
|
|
|
|
|
XFlush( display );
|
|
|
|
|
|
|
|
|
|
// Initialize audio and video details
|
|
|
|
|
Arts::SoundServerV2 server = Arts::Reference( "global:Arts_SoundServerV2" );
|
|
|
|
|
audio.sample_rate = 0;
|
|
|
|
|
audio.num_channels = 0;
|
|
|
|
|
audio.bits_per_sample = 0;
|
|
|
|
|
// Create a special window for uninterrupted X11 communication
|
|
|
|
|
xcomWindow = XCreateSimpleWindow( display, DefaultRootWindow( display ), 0, 0, 1, 1, 0, 0, 0 );
|
|
|
|
|
|
|
|
|
|
flpos = 0.0;
|
|
|
|
|
if (!audioOnly)
|
|
|
|
|
if (pthread_create( &thread, 0, pthread_start_routine, this ))
|
|
|
|
|
{
|
|
|
|
|
arts_fatal( "could not create thread" );
|
|
|
|
|
}
|
|
|
|
|
XSelectInput( display, xcomWindow, ExposureMask );
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_init( &mutex, 0 );
|
|
|
|
|
|
|
|
|
|
if (!audioOnly) {
|
|
|
|
|
// Initialize X11 properties
|
|
|
|
|
xcomAtomQuit = XInternAtom( display, "VPO_INTERNAL_EVENT", False );
|
|
|
|
|
xcomAtomResize = XInternAtom( display, "VPO_RESIZE_NOTIFY", False );
|
|
|
|
|
screen = DefaultScreen( display );
|
|
|
|
|
shmCompletionType = (XShmQueryExtension( display ) == True)
|
|
|
|
|
? XShmGetEventBase( display ) + ShmCompletion : -1;
|
|
|
|
|
|
|
|
|
|
width = 0;
|
|
|
|
|
height = 0;
|
|
|
|
|
dscbTimeOut = 0;
|
|
|
|
|
|
|
|
|
|
// Initialize xine visual structure
|
|
|
|
|
visual.display = display;
|
|
|
|
|
visual.screen = screen;
|
|
|
|
|
visual.d = xcomWindow;
|
|
|
|
|
visual.dest_size_cb = &dest_size_cb;
|
|
|
|
|
visual.frame_output_cb = &frame_output_cb;
|
|
|
|
|
visual.user_data = this;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Initialize audio and video details
|
|
|
|
|
Arts::SoundServerV2 server = Arts::Reference( "global:Arts_SoundServerV2" );
|
|
|
|
|
audio.sample_rate = 0;
|
|
|
|
|
audio.num_channels = 0;
|
|
|
|
|
audio.bits_per_sample = 0;
|
|
|
|
|
|
|
|
|
|
flpos = 0.0;
|
|
|
|
|
if (!audioOnly) {
|
|
|
|
|
if (pthread_create( &thread, 0, pthread_start_routine, this )) {
|
|
|
|
|
arts_fatal( "could not create thread" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xinePlayObject_impl::~xinePlayObject_impl()
|
|
|
|
|