Commit 85c3dbc4 authored by Gildas Bazin's avatar Gildas Bazin

* Big rewrite of the DirectX audio plugin. The audio output is now (almost)
    perfect on Win32.
* Fixed a bug in ac3dec_CreateThread() in ac3_decoder_thread.
* On Win32, open() will now open files in binary mode by default.
* A few minor changes to vout_xvideo.c
parent f65e5509
......@@ -2,7 +2,7 @@
* aout_directx.c: Windows DirectX audio output method
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: aout_directx.c,v 1.8 2001/07/30 18:56:36 gbazin Exp $
* $Id: aout_directx.c,v 1.9 2001/08/05 15:32:46 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -24,12 +24,6 @@
#define MODULE_NAME directx
#include "modules_inner.h"
/* The most important thing to do for now is to fix the audio bug we've got
* on startup: the audio will start later than the video (sometimes) and
* is trying to catching up with it.
* At first sight it seems to be a scheduling problem
*/
/*****************************************************************************
* Preamble
......@@ -81,12 +75,24 @@ typedef struct aout_sys_s
* takes care of mixing all the
* secondary buffers into the primary) */
LPDIRECTSOUNDNOTIFY p_dsnotify; /* the position notify interface */
HINSTANCE hdsound_dll; /* handle of the opened dsound dll */
long l_buffer_size; /* secondary sound buffer size */
long l_write_position; /* next write position for the buffer */
boolean_t b_active;
volatile boolean_t b_buffer_underflown; /* buffer underflow detection */
volatile long l_data_played_from_beginning; /* for underflow detection */
volatile long l_data_written_from_beginning; /* for underflow detection */
vlc_mutex_t buffer_lock; /* audio buffer lock */
vlc_thread_t notification_thread_id; /* DirectSoundThread id */
DSBPOSITIONNOTIFY notification_events[2]; /* play notification events */
boolean_t b_notification_thread_die; /* flag to kill the thread */
} aout_sys_t;
......@@ -102,8 +108,10 @@ static void aout_Play ( aout_thread_t *p_aout,
static void aout_Close ( aout_thread_t *p_aout );
/* local functions */
static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout );
static int DirectxInitDSound( aout_thread_t *p_aout );
static int DirectxCreateSecondaryBuffer ( aout_thread_t *p_aout );
static void DirectxDestroySecondaryBuffer( aout_thread_t *p_aout );
static int DirectxInitDSound ( aout_thread_t *p_aout );
static void DirectSoundThread ( aout_thread_t *p_aout );
/*****************************************************************************
* Functions exported as capabilities. They are declared as static so that
......@@ -144,7 +152,6 @@ static int aout_Open( aout_thread_t *p_aout )
{
HRESULT dsresult;
DSBUFFERDESC dsbuffer_desc;
WAVEFORMATEX waveformat;
intf_WarnMsg( 3, "aout: DirectX aout_Open ");
......@@ -161,6 +168,12 @@ static int aout_Open( aout_thread_t *p_aout )
p_aout->p_sys->p_dsobject = NULL;
p_aout->p_sys->p_dsbuffer_primary = NULL;
p_aout->p_sys->p_dsbuffer = NULL;
p_aout->p_sys->p_dsnotify = NULL;
p_aout->p_sys->b_notification_thread_die = 0;
p_aout->p_sys->l_data_written_from_beginning = 0;
p_aout->p_sys->l_data_played_from_beginning = 0;
vlc_mutex_init( &p_aout->p_sys->buffer_lock );
p_aout->psz_device = 0;
p_aout->i_format = AOUT_FORMAT_DEFAULT;
......@@ -194,42 +207,25 @@ static int aout_Open( aout_thread_t *p_aout )
return( 1 );
}
/* Set Direct Sound primary buffer format because the default value set by
* Windows is usually not the high quality value */
memset(&waveformat, 0, sizeof(WAVEFORMATEX));
waveformat.wFormatTag = WAVE_FORMAT_PCM;
waveformat.nChannels = 2;
waveformat.nSamplesPerSec = 44100;
waveformat.wBitsPerSample = 16;
waveformat.nBlockAlign = waveformat.wBitsPerSample / 8 *
waveformat.nChannels;
waveformat.nAvgBytesPerSec = waveformat.nSamplesPerSec *
waveformat.nBlockAlign;
dsresult = IDirectSoundBuffer_SetFormat(p_aout->p_sys->p_dsbuffer_primary,
&waveformat);
if( dsresult != DS_OK )
{
intf_WarnMsg( 3, "aout: can't set primary buffer format");
}
/* Now we need to setup DirectSound play notification */
#if 0
/* ensure the primary buffer is playing. We won't actually hear anything
* until the secondary buffer is playing */
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer_primary,
0,
0,
DSBPLAY_LOOPING);
if( dsresult != DS_OK )
/* first we need to create the notification events */
p_aout->p_sys->notification_events[0].hEventNotify =
CreateEvent( NULL, FALSE, FALSE, NULL );
p_aout->p_sys->notification_events[1].hEventNotify =
CreateEvent( NULL, FALSE, FALSE, NULL );
/* then launch the notification thread */
intf_WarnMsg( 3, "aout: aout_Open creating DirectSoundThread" );
if( vlc_thread_create( &p_aout->p_sys->notification_thread_id,
"DirectSound Notification Thread",
(void *) DirectSoundThread, (void *) p_aout) )
{
intf_WarnMsg( 3, "aout: can't play direct sound primary buffer ");
IDirectSound_Release( p_aout->p_sys->p_dsbuffer_primary );
IDirectSound_Release( p_aout->p_sys->p_dsobject );
p_aout->p_sys->p_dsobject = NULL;
p_aout->p_sys->p_dsbuffer_primary = NULL;
return( 1 );
intf_ErrMsg( "aout error: can't create DirectSoundThread" );
intf_ErrMsg("aout error: %s", strerror(ENOMEM));
/* Let's go on anyway */
}
#endif
return( 0 );
}
......@@ -244,24 +240,64 @@ static int aout_Open( aout_thread_t *p_aout )
static int aout_SetFormat( aout_thread_t *p_aout )
{
HRESULT dsresult;
WAVEFORMATEX *p_waveformat;
unsigned long i_size_struct;
intf_WarnMsg( 3, "aout: DirectX aout_SetFormat ");
/* first release the current secondary buffer */
if( p_aout->p_sys->p_dsbuffer != NULL )
/* Set the format of Direct Sound primary buffer */
/* first we need to know the current format */
dsresult = IDirectSoundBuffer_GetFormat( p_aout->p_sys->p_dsbuffer_primary,
NULL, 0, &i_size_struct );
if( dsresult == DS_OK )
{
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer );
p_aout->p_sys->p_dsbuffer = NULL;
p_waveformat = malloc( i_size_struct );
dsresult = IDirectSoundBuffer_GetFormat(
p_aout->p_sys->p_dsbuffer_primary,
p_waveformat, i_size_struct,
NULL );
}
/* then create a new secondary buffer */
dsresult = DirectxCreateSecondaryBuffer( p_aout );
if( dsresult == DS_OK )
{
/* Here we'll change the format */
p_waveformat->nChannels = 2;
p_waveformat->nSamplesPerSec = (p_aout->l_rate < 44100) ? 44100
: p_aout->l_rate;
p_waveformat->wBitsPerSample = 16;
p_waveformat->nBlockAlign = p_waveformat->wBitsPerSample / 8 *
p_waveformat->nChannels;
p_waveformat->nAvgBytesPerSec = p_waveformat->nSamplesPerSec *
p_waveformat->nBlockAlign;
dsresult = IDirectSoundBuffer_SetFormat(
p_aout->p_sys->p_dsbuffer_primary,
p_waveformat );
}
else intf_WarnMsg( 3, "aout: can't get primary buffer format" );
if( dsresult != DS_OK )
intf_WarnMsg( 3, "aout: can't set primary buffer format" );
/* Now we need to take care of Direct Sound secondary buffer */
vlc_mutex_lock( &p_aout->p_sys->buffer_lock );
/* first release the current secondary buffer */
DirectxDestroySecondaryBuffer( p_aout );
/* then create a new secondary buffer */
if( DirectxCreateSecondaryBuffer( p_aout ) )
{
intf_WarnMsg( 3, "aout: DirectX aout_SetFormat cannot create buffer");
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
return( 1 );
}
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
p_aout->i_latency = 0;
return( 0 );
......@@ -270,48 +306,35 @@ static int aout_SetFormat( aout_thread_t *p_aout )
/*****************************************************************************
* aout_GetBufInfo: buffer status query
*****************************************************************************
* returns the number of bytes in the audio buffer compared to the size of
* l_buffer_limit...
* returns the number of bytes in the audio buffer that have not yet been
* sent to the sound device.
*****************************************************************************/
static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
{
long l_play_position, l_notused, l_result;
HRESULT dsresult;
dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer,
&l_play_position, &l_notused);
if( dsresult == DSERR_BUFFERLOST )
{
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer );
dsresult = IDirectSoundBuffer_GetCurrentPosition(
p_aout->p_sys->p_dsbuffer,
&l_play_position, &l_notused
);
}
if( dsresult != DS_OK )
if( p_aout->p_sys->b_buffer_underflown )
{
intf_WarnMsg(3,"aout: DirectX aout_GetBufInfo cannot get current pos");
intf_WarnMsg( 3, "aout: DirectX aout_GetBufInfo underflow");
return( l_buffer_limit );
}
#if 0
/* temporary hack. When you start playing a new file, the play position
* doesn't start changing immediatly, even though sound is already
* playing from the sound card */
if( l_play_position == 0 )
dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer,
&l_play_position, &l_notused);
if( dsresult != DS_OK )
{
intf_WarnMsg( 5, "aout: DirectX aout_GetBufInfo: %li", l_buffer_limit);
intf_WarnMsg(3,"aout: DirectX aout_GetBufInfo cannot get current pos");
return( l_buffer_limit );
}
#endif
l_result = (p_aout->p_sys->l_write_position >= l_play_position) ?
(p_aout->p_sys->l_write_position - l_play_position) /2
(p_aout->p_sys->l_write_position - l_play_position)
: (p_aout->p_sys->l_buffer_size - l_play_position
+ p_aout->p_sys->l_write_position) /2 ;
+ p_aout->p_sys->l_write_position);
#if 0
intf_WarnMsg( 5, "aout: DirectX aout_GetBufInfo: %li", l_result);
intf_WarnMsg( 3, "aout: DirectX aout_GetBufInfo: %li", l_result);
#endif
return l_result;
}
......@@ -320,58 +343,40 @@ static long aout_GetBufInfo( aout_thread_t *p_aout, long l_buffer_limit )
* aout_Play: play a sound buffer
*****************************************************************************
* This function writes a buffer of i_length bytes
* Don't forget that DirectSound buffers are circular buffers.
*****************************************************************************/
static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
{
VOID *p_write_position, *p_start_buffer;
long l_bytes1, l_bytes2;
long l_play_position, l_notused, l_buffer_free_length;
long l_bytes1, l_bytes2, l_play_position;
HRESULT dsresult;
/* We want to copy data to the circular sound buffer, so we first need to
* find out were in the buffer we can write our data */
dsresult = IDirectSoundBuffer_GetCurrentPosition(p_aout->p_sys->p_dsbuffer,
&l_play_position,
&l_notused);
if( dsresult == DSERR_BUFFERLOST )
/* protect buffer access (because of DirectSoundThread) */
vlc_mutex_lock( &p_aout->p_sys->buffer_lock );
if( p_aout->p_sys->b_buffer_underflown )
{
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer );
/* reset the position to the beginning of the buffer */
dsresult = IDirectSoundBuffer_SetCurrentPosition(
p_aout->p_sys->p_dsbuffer, 1024 );
/* there has been an underflow so we need to play the new sample
* as soon as possible. This is why we query the play position */
dsresult = IDirectSoundBuffer_GetCurrentPosition(
p_aout->p_sys->p_dsbuffer,
&l_play_position, &l_notused
);
}
&l_play_position,
&p_aout->p_sys->l_write_position );
if( dsresult != DS_OK )
{
intf_WarnMsg( 3, "aout: DirectX aout_Play can'get buffer position");
intf_WarnMsg( 3, "aout: aout_Play can'get buffer position");
p_aout->p_sys->l_write_position = 0;
}
#if 1
/* check that we are not overflowing the circular buffer (everything should
* be alright but just in case) */
l_buffer_free_length = l_play_position - p_aout->p_sys->l_write_position;
if( l_buffer_free_length <= 0 )
l_buffer_free_length += p_aout->p_sys->l_buffer_size;
if( i_size > l_buffer_free_length )
{
intf_WarnMsg( 3, "aout: DirectX aout_Play buffer overflow: size %i, free %i !!!", i_size, l_buffer_free_length);
intf_WarnMsg( 3, "aout: DirectX aout_Play buffer overflow: writepos %i, readpos %i !!!", p_aout->p_sys->l_write_position, l_play_position);
/*i_size = l_buffer_free_length;*/
/* Update the write pointer */
p_aout->p_sys->l_write_position = l_notused;
}
else
{
#if 0
intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: size %i, free %i !!!"
, i_size, l_buffer_free_length);
intf_WarnMsg( 4, "aout: DirectX aout_Play buffer: writepos %i, readpos %i !!!", p_aout->p_sys->l_write_position, l_play_position);
#endif
/* reinitialise the underflow detection counters */
p_aout->p_sys->l_data_written_from_beginning = 0;
p_aout->p_sys->l_data_played_from_beginning =
-(p_aout->p_sys->l_write_position % (p_aout->p_sys->l_buffer_size/2));
p_aout->p_sys->b_buffer_underflown = 0;
}
#endif
/* Before copying anything, we have to lock the buffer */
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
......@@ -398,10 +403,11 @@ static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
if( dsresult != DS_OK )
{
intf_WarnMsg( 3, "aout: DirectX aout_Play can't lock buffer");
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
return;
}
/* Now do the actual memcopy (two memcpy because the buffer is circular) */
/* Now do the actual memcpy (two memcpy because the buffer is circular) */
memcpy( p_write_position, buffer, l_bytes1 );
if( p_start_buffer != NULL )
{
......@@ -415,6 +421,9 @@ static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size )
/* Update the write position index of the buffer*/
p_aout->p_sys->l_write_position += i_size;
p_aout->p_sys->l_write_position %= p_aout->p_sys->l_buffer_size;
p_aout->p_sys->l_data_written_from_beginning += i_size;
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
/* The play function has no effect if the buffer is already playing */
dsresult = IDirectSoundBuffer_Play( p_aout->p_sys->p_dsbuffer,
......@@ -445,18 +454,14 @@ static void aout_Close( aout_thread_t *p_aout )
intf_WarnMsg( 3, "aout: DirectX aout_Close ");
/* make sure the buffer isn't playing */
if( p_aout->p_sys->p_dsbuffer != NULL )
{
IDirectSoundBuffer_Stop( p_aout->p_sys->p_dsbuffer );
}
/* kill the position notification thread */
p_aout->p_sys->b_notification_thread_die = 1;
SetEvent( p_aout->p_sys->notification_events[0].hEventNotify );
vlc_thread_join( p_aout->p_sys->notification_thread_id );
vlc_mutex_destroy( &p_aout->p_sys->buffer_lock );
/* first release the secondary buffer */
if( p_aout->p_sys->p_dsbuffer != NULL )
{
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer );
p_aout->p_sys->p_dsbuffer = NULL;
}
/* release the secondary buffer */
DirectxDestroySecondaryBuffer( p_aout );
/* then release the primary buffer */
if( p_aout->p_sys->p_dsbuffer_primary != NULL )
......@@ -576,6 +581,7 @@ static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout )
memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
dsbdesc.dwSize = sizeof(DSBUFFERDESC);
dsbdesc.dwFlags = DSBCAPS_GETCURRENTPOSITION2/* Better position accuracy */
| DSBCAPS_CTRLPOSITIONNOTIFY /* We need notification */
| DSBCAPS_GLOBALFOCUS; /* Allows background playing */
dsbdesc.dwBufferBytes = waveformat.nAvgBytesPerSec * 2; /* 2 sec buffer */
dsbdesc.lpwfxFormat = &waveformat;
......@@ -596,8 +602,179 @@ static int DirectxCreateSecondaryBuffer( aout_thread_t *p_aout )
IDirectSoundBuffer_GetCaps( p_aout->p_sys->p_dsbuffer, &dsbcaps );
p_aout->p_sys->l_buffer_size = dsbcaps.dwBufferBytes;
p_aout->p_sys->l_write_position = 0;
intf_WarnMsg( 3, "aout: DirectX DirectxCreateSecondaryBuffer: %li",
p_aout->p_sys->l_buffer_size);
/* Now the secondary buffer is created, we need to setup its position
* notification */
p_aout->p_sys->notification_events[0].dwOffset = 0; /* notif position */
p_aout->p_sys->notification_events[1].dwOffset = dsbcaps.dwBufferBytes / 2;
/* Get the IDirectSoundNotify interface */
if FAILED( IDirectSoundBuffer_QueryInterface( p_aout->p_sys->p_dsbuffer,
&IID_IDirectSoundNotify,
(LPVOID *)&p_aout->p_sys->p_dsnotify ) )
{
intf_WarnMsg( 3, "aout: DirectX can't get Notify interface" );
/* Go on anyway */
p_aout->p_sys->p_dsnotify = NULL;
return( 0 );
}
if FAILED( IDirectSoundNotify_SetNotificationPositions(
p_aout->p_sys->p_dsnotify,
2,
p_aout->p_sys->notification_events ) )
{
intf_WarnMsg( 3, "aout: DirectX can't set position Notification" );
/* Go on anyway */
}
return( 0 );
}
/*****************************************************************************
* DirectxCreateSecondaryBuffer
*****************************************************************************
* This function destroy the secondary buffer.
*****************************************************************************/
static void DirectxDestroySecondaryBuffer( aout_thread_t *p_aout )
{
/* make sure the buffer isn't playing */
if( p_aout->p_sys->p_dsbuffer != NULL )
{
IDirectSoundBuffer_Stop( p_aout->p_sys->p_dsbuffer );
}
if( p_aout->p_sys->p_dsnotify != NULL )
{
IDirectSoundNotify_Release( p_aout->p_sys->p_dsnotify );
p_aout->p_sys->p_dsnotify = NULL;
}
if( p_aout->p_sys->p_dsbuffer != NULL )
{
IDirectSoundBuffer_Release( p_aout->p_sys->p_dsbuffer );
p_aout->p_sys->p_dsbuffer = NULL;
}
}
/*****************************************************************************
* DirectSoundThread: this thread will capture play notification events.
*****************************************************************************
* As Direct Sound uses circular buffers, we need to use event notification to
* manage them.
* Using event notification implies blocking the thread until the event is
* signaled so we really need to run this in a separate thread.
*****************************************************************************/
static void DirectSoundThread( aout_thread_t *p_aout )
{
HANDLE notification_events[2];
VOID *p_write_position, *p_start_buffer;
long l_bytes1, l_bytes2;
HRESULT dsresult;
long l_buffer_size, l_play_position, l_data_in_buffer;
notification_events[0]=p_aout->p_sys->notification_events[0].hEventNotify;
notification_events[1]=p_aout->p_sys->notification_events[1].hEventNotify;
/* this thread must be high-priority */
if( !SetThreadPriority( GetCurrentThread(),
THREAD_PRIORITY_ABOVE_NORMAL ) )
{
intf_WarnMsg( 3, "aout: DirectSoundThread could not renice itself" );
}
intf_WarnMsg( 3, "aout: DirectSoundThread ready" );
while( !p_aout->p_sys->b_notification_thread_die )
{
/* wait for the position notification */
l_play_position = WaitForMultipleObjects( 2, notification_events,
0, INFINITE );
vlc_mutex_lock( &p_aout->p_sys->buffer_lock );
if( p_aout->p_sys->b_notification_thread_die )
{
break;
}
/* check for buffer underflow (bodge for wrap around) */
l_buffer_size = p_aout->p_sys->l_buffer_size;
l_play_position = (l_play_position - WAIT_OBJECT_0) * l_buffer_size/2;
p_aout->p_sys->l_data_played_from_beginning += (l_buffer_size/2);
l_data_in_buffer = p_aout->p_sys->l_data_written_from_beginning -
p_aout->p_sys->l_data_played_from_beginning;
/* detect wrap-around */
if( l_data_in_buffer < (-l_buffer_size/2) )
{
l_data_in_buffer += l_buffer_size;
}
/* detect underflow */
if( l_data_in_buffer <= 0 )
{
intf_WarnMsg(3,"aout: DirectSoundThread underflow");
p_aout->p_sys->b_buffer_underflown = 1;
p_aout->p_sys->l_write_position =
(l_play_position + l_buffer_size/2) % l_buffer_size;
l_data_in_buffer = l_buffer_size / 2;
}
/* Clear the data which has already been played */
/* Before copying anything, we have to lock the buffer */
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
p_aout->p_sys->l_write_position, /* Offset of lock start */
l_buffer_size - l_data_in_buffer, /* Number of bytes */
&p_write_position, /* Address of lock start */
&l_bytes1, /* Count of bytes locked before wrap around */
&p_start_buffer, /* Buffer adress (if wrap around) */
&l_bytes2, /* Count of bytes after wrap around */
0); /* Flags */
if( dsresult == DSERR_BUFFERLOST )
{
IDirectSoundBuffer_Restore( p_aout->p_sys->p_dsbuffer );
dsresult = IDirectSoundBuffer_Lock( p_aout->p_sys->p_dsbuffer,
p_aout->p_sys->l_write_position,
l_buffer_size - l_data_in_buffer,
&p_write_position,
&l_bytes1,
&p_start_buffer,
&l_bytes2,
0);
}
if( dsresult != DS_OK )
{
intf_WarnMsg( 3, "aout: DirectX aout_Play can't lock buffer");
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
return;
}
/* Now do the actual memcpy (two because the buffer is circular) */
memset( p_write_position, 0, l_bytes1 );
if( p_start_buffer != NULL )
{
memset( p_start_buffer, 0, l_bytes2 );
}
/* Now the data has been copied, unlock the buffer */
IDirectSoundBuffer_Unlock( p_aout->p_sys->p_dsbuffer,
p_write_position, l_bytes1, p_start_buffer, l_bytes2 );
vlc_mutex_unlock( &p_aout->p_sys->buffer_lock );
}
/* free the events */
CloseHandle( notification_events[0] );
CloseHandle( notification_events[1] );
intf_WarnMsg( 3, "aout: DirectSoundThread exiting" );
}
......@@ -2,7 +2,7 @@
* vout_directx.c: Windows DirectX video output display method
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: vout_directx.c,v 1.9 2001/07/30 00:53:04 sam Exp $
* $Id: vout_directx.c,v 1.10 2001/08/05 15:32:46 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
......@@ -202,7 +202,7 @@ static int vout_Create( vout_thread_t *p_vout )
* DirectXEventThread will take care of the creation of the video
* window (because PeekMessage has to be called from the same thread which
* created the window). */
intf_WarnMsg( 3, "vout : vout_Create creating DirectXEventThread" );
intf_WarnMsg( 3, "vout: vout_Create creating DirectXEventThread" );
if( vlc_thread_create( &p_vout->p_sys->event_thread_id,
"DirectX Events Thread",
(void *) DirectXEventThread, (void *) p_vout) )
......@@ -475,6 +475,7 @@ static void vout_Display( vout_thread_t *p_vout )
{
DDSURFACEDESC ddsd;
HRESULT dxresult;
int i;
int i_image_width;
int i_image_height;
......@@ -505,6 +506,7 @@ static void vout_Display( vout_thread_t *p_vout )
{
RECT rect_window;
POINT point_window;
DDBLTFX ddbltfx;
/* Nothing yet */
if( p_vout->p_sys->p_surface == NULL )
......@@ -539,17 +541,24 @@ static void vout_Display( vout_thread_t *p_vout )
rect_window.bottom = point_window.y;
/* We want to keep the aspect ratio of the video */
if( !p_vout->b_scale ) /* kuldge */
#if 0
if( p_vout->b_scale )
{
DirectXKeepAspectRatio( p_vout, &rect_window );
}
#endif
/* We ask for the "NOTEARING" option */
memset( &ddbltfx, 0, sizeof(DDBLTFX) );
ddbltfx.dwSize = sizeof(DDBLTFX);
ddbltfx.dwDDFX = DDBLTFX_NOTEARING;
/* Blit video surface to display */
dxresult = IDirectDrawSurface3_Blt(p_vout->p_sys->p_display,
&rect_window,
p_vout->p_sys->p_surface,
NULL,
0, NULL );
0, &ddbltfx );
if( dxresult != DD_OK )
{
intf_WarnMsg( 3, "vout: could not Blit the surface" );
......
......@@ -2,7 +2,7 @@
* vout_xvideo.c: Xvideo video output display method
*****************************************************************************
* Copyright (C) 1998, 1999, 2000, 2001 VideoLAN
* $Id: vout_xvideo.c,v 1.24 2001/08/03 16:04:17 gbazin Exp $
* $Id: vout_xvideo.c,v 1.25 2001/08/05 15:32:46 gbazin Exp $
*
* Authors: Shane Harper <shanegh@optusnet.com.au>
* Vincent Seguin <seguin@via.ecp.fr>
......@@ -287,35 +287,16 @@ static int vout_Create( vout_thread_t *p_vout )
return( 1 );
}
/* Spawn base window - this window will include the video output window,
* but also command buttons, subtitles and other indicators */
if( XVideoCreateWindow( p_vout ) )
{
intf_ErrMsg( "vout error: cannot create XVideo window" );
XCloseDisplay( p_vout->p_sys->p_display );
free( p_vout->p_sys );
return( 1 );
}
if( (p_vout->p_sys->xv_port = XVideoGetPort( p_vout->p_sys->p_display ))<0 )
/* Check we have access to a video port */
if( (p_vout->p_sys->xv_port = XVideoGetPort(p_vout->p_sys->p_display)) <0 )
{
intf_ErrMsg( "vout error: cannot get XVideo port" );
XVideoDestroyWindow( p_vout );
XCloseDisplay( p_vout->p_sys->p_display );
free( p_vout->p_sys );
return 1;
}
intf_DbgMsg( "Using xv port %d" , p_vout->p_sys->xv_port );
/* p_vout->pf_setbuffers( p_vout, NULL, NULL ); */
#if 0
/* XXX The brightness and contrast values should be read from environment
* XXX variables... */
XVideoSetAttribute( p_vout, "XV_BRIGHTNESS", 0.5 );
XVideoSetAttribute( p_vout, "XV_CONTRAST", 0.5 );
#endif
/* Create blank cursor (for mouse cursor autohiding) */
p_vout->p_sys->b_mouse_pointer_visible = 1;
p_vout->p_sys->cursor_pixmap = XCreatePixmap( p_vout->p_sys->p_display,
......@@ -340,6 +321,24 @@ static int vout_Create( vout_thread_t *p_vout )
&cursor_color,
&cursor_color, 1, 1 );
/* Spawn base window - this window will include the video output window,
* but also command buttons, subtitles and other indicators */
if( XVideoCreateWindow( p_vout ) )
{
intf_ErrMsg( "vout error: cannot create XVideo window" );
XCloseDisplay( p_vout->p_sys->p_display );
free( p_vout->p_sys );
return( 1 );
}
/* p_vout->pf_setbuffers( p_vout, NULL, NULL ); */
#if 0
/* XXX The brightness and contrast values should be read from environment
* XXX variables... */
XVideoSetAttribute( p_vout, "XV_BRIGHTNESS", 0.5 );
XVideoSetAttribute( p_vout, "XV_CONTRAST", 0.5 );
#endif
/* Disable screen saver and return */
XVideoDisableScreenSaver( p_vout );
......@@ -938,6 +937,13 @@ static int XVideoCreateWindow( vout_thread_t *p_vout )
XSelectInput( p_vout->p_sys->p_display, p_vout->p_sys->yuv_window,
ExposureMask );
/* If the cursor was formerly blank than blank it again */
if( !p_vout->p_sys->b_mouse_pointer_visible )
{
X11ToggleMousePointer( p_vout );
X11ToggleMousePointer( p_vout );
}
return( 0 );
}
......
......@@ -2,7 +2,7 @@
* ac3_decoder_thread.c: ac3 decoder thread
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder_thread.c,v 1.35 2001/07/08 23:15:11 reno Exp $
* $Id: ac3_decoder_thread.c,v 1.36 2001/08/05 15:32:46 gbazin Exp $
*
* Authors: Michel Lespinasse <walken@zoy.org>
*
......@@ -78,15 +78,17 @@ static void BitstreamCallback ( bit_stream_t *p_bit_stream,
vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
{
ac3dec_thread_t * p_ac3thread;
ac3dec_thread_t * p_ac3thread_temp;
intf_DbgMsg( "ac3dec debug: creating ac3 decoder thread" );
/* Allocate the memory needed to store the thread's structure */
p_ac3thread = (ac3dec_thread_t *)malloc(sizeof(ac3dec_thread_t));
p_ac3thread_temp = (ac3dec_thread_t *)malloc(sizeof(ac3dec_thread_t) + 15);
/* We need to be 16 bytes aligned */
p_ac3thread->ac3thread = (int)p_ac3thread & (-15);
p_ac3thread = (ac3dec_thread_t *)p_ac3thread->ac3thread;
p_ac3thread = (ac3dec_thread_t *)(((unsigned long)p_ac3thread_temp + 15)
& ~0xFUL );
p_ac3thread->ac3thread = p_ac3thread_temp;
if(p_ac3thread == NULL)
{
......@@ -110,7 +112,7 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
if( DOWNMIX.p_module == NULL )
{
intf_ErrMsg( "ac3dec error: no suitable downmix module" );
free( p_ac3thread );
free( p_ac3thread->ac3thread );
return( 0 );
}
......@@ -135,7 +137,7 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
{
intf_ErrMsg( "ac3dec error: no suitable IMDCT module" );
module_Unneed( p_ac3thread->ac3_decoder.downmix.p_module );
free( p_ac3thread );
free( p_ac3thread->ac3thread );
return( 0 );
}
......@@ -163,7 +165,7 @@ vlc_thread_t ac3dec_CreateThread( adec_config_t * p_config )
intf_ErrMsg( "ac3dec error: can't spawn ac3 decoder thread" );
module_Unneed( p_ac3thread->ac3_decoder.downmix.p_module );
module_Unneed( p_ac3thread->ac3_decoder.imdct.p_module );
free (p_ac3thread);
free (p_ac3thread->ac3thread);
return 0;
}
......@@ -341,8 +343,7 @@ static void EndThread (ac3dec_thread_t * p_ac3thread)
/* Destroy descriptor */
free( p_ac3thread->p_config );
p_ac3thread = (ac3dec_thread_t *)p_ac3thread->ac3thread;
free( p_ac3thread );
free( p_ac3thread->ac3thread );
intf_DbgMsg ("ac3dec debug: ac3 decoder thread %p destroyed", p_ac3thread);
}
......
......@@ -2,7 +2,7 @@
* ac3_decoder_thread.h : ac3 decoder thread interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: ac3_decoder_thread.h,v 1.8 2001/07/08 23:15:11 reno Exp $
* $Id: ac3_decoder_thread.h,v 1.9 2001/08/05 15:32:46 gbazin Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
*
......@@ -50,7 +50,8 @@ typedef struct ac3dec_thread_s
* Output properties
*/
aout_fifo_t * p_aout_fifo; /* stores the decompressed audio frames */
int ac3thread; /* save the old pointer */
struct ac3dec_thread_s * ac3thread; /* save the old pointer */
} ac3dec_thread_t;
......
......@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: input.c,v 1.127 2001/07/18 14:21:00 massiot Exp $
* $Id: input.c,v 1.128 2001/08/05 15:32:46 gbazin Exp $
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
......@@ -605,12 +605,8 @@ static void FileOpen( input_thread_t * p_input )
vlc_mutex_unlock( &p_input->stream.stream_lock );
intf_WarnMsg( 1, "input: opening file `%s'", p_input->p_source );
#if defined( WIN32 )
if( (p_input->i_handle = open( psz_name, O_BINARY ) ) == (-1) )
#else
if( (p_input->i_handle = open( psz_name,
/*O_NONBLOCK | O_LARGEFILE*/0 )) == (-1) )
#endif
{
intf_ErrMsg( "input error: cannot open file (%s)", strerror(errno) );
p_input->b_error = 1;
......
......@@ -4,7 +4,7 @@
* and spawn threads.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN
* $Id: main.c,v 1.109 2001/07/30 00:53:05 sam Exp $
* $Id: main.c,v 1.110 2001/08/05 15:32:46 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -287,6 +287,8 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
*/
#if defined( SYS_BEOS ) || defined( SYS_DARWIN )
system_Init( &i_argc, ppsz_argv, ppsz_env );
#elif defined( WIN32 )
_fmode = _O_BINARY; /* sets the default file-translation mode on Win32 */
#endif
/*
......
......@@ -2,7 +2,7 @@
* video_text.c : text manipulation functions
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: video_text.c,v 1.29 2001/06/25 11:34:08 sam Exp $
* $Id: video_text.c,v 1.30 2001/08/05 15:32:47 gbazin Exp $
*
* Authors: Vincent Seguin <seguin@via.ecp.fr>
* Samuel Hocevar <sam@zoy.org>
......@@ -263,11 +263,7 @@ vout_font_t *vout_LoadFont( const char *psz_name )
}
/* Open file */
#ifndef WIN32
i_file = open( psz_file, O_RDONLY );
#else
i_file = open( psz_file, O_RDONLY | O_BINARY );
#endif
free( psz_file );
if( i_file != -1 )
......
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