diff --git a/configure b/configure index 44e643604a..7fb16d6303 100755 --- a/configure +++ b/configure @@ -7773,7 +7773,7 @@ if test "${enable_macosx+set}" = set; then if test x$enable_macosx = xyes then BUILTINS="${BUILTINS} macosx" - LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework Cocoa -framework AGL -framework QuickTime -lobjc" + LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework AudioToolbox -framework Cocoa -framework AGL -framework QuickTime -lobjc" CFLAGS_MACOSX="${CFLAGS_MACOSX} -ObjC" LIB="${LIB} -ObjC" fi @@ -7813,7 +7813,7 @@ if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then #define $ac_tr_hdr 1 EOF BUILTINS="${BUILTINS} macosx" - LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework Cocoa -framework AGL -framework QuickTime -lobjc" + LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework AudioToolbox -framework Cocoa -framework AGL -framework QuickTime -lobjc" CFLAGS_MACOSX="${CFLAGS_MACOSX} -ObjC" LIB="${LIB} -ObjC" diff --git a/configure.in b/configure.in index ff7baf4279..0167695402 100644 --- a/configure.in +++ b/configure.in @@ -1305,13 +1305,13 @@ AC_ARG_ENABLE(macosx, [if test x$enable_macosx = xyes then BUILTINS="${BUILTINS} macosx" - LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework Cocoa -framework AGL -framework QuickTime -lobjc" + LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework AudioToolbox -framework Cocoa -framework AGL -framework QuickTime -lobjc" CFLAGS_MACOSX="${CFLAGS_MACOSX} -ObjC" LIB="${LIB} -ObjC" fi], [AC_CHECK_HEADERS(Cocoa/Cocoa.h, BUILTINS="${BUILTINS} macosx" - LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework Cocoa -framework AGL -framework QuickTime -lobjc" + LIB_MACOSX="${LIB_MACOSX} -framework CoreAudio -framework AudioToolbox -framework Cocoa -framework AGL -framework QuickTime -lobjc" CFLAGS_MACOSX="${CFLAGS_MACOSX} -ObjC" LIB="${LIB} -ObjC" )]) diff --git a/extras/MacOSX/Resources/English.lproj/MainMenu.nib/classes.nib b/extras/MacOSX/Resources/English.lproj/MainMenu.nib/classes.nib index 6a480b67e5..b466b30af6 100644 --- a/extras/MacOSX/Resources/English.lproj/MainMenu.nib/classes.nib +++ b/extras/MacOSX/Resources/English.lproj/MainMenu.nib/classes.nib @@ -33,7 +33,7 @@ LANGUAGE = ObjC; OUTLETS = {o_table = id; }; SUPERCLASS = NSObject; - }, + } ); IBVersion = 1; -} +} \ No newline at end of file diff --git a/extras/MacOSX/Resources/English.lproj/MainMenu.nib/info.nib b/extras/MacOSX/Resources/English.lproj/MainMenu.nib/info.nib index 1819701a64..4f9aaecd0c 100644 --- a/extras/MacOSX/Resources/English.lproj/MainMenu.nib/info.nib +++ b/extras/MacOSX/Resources/English.lproj/MainMenu.nib/info.nib @@ -18,6 +18,6 @@ 21 IBSystem Version - 5P48 + 5Q45 diff --git a/extras/MacOSX/Resources/English.lproj/MainMenu.nib/objects.nib b/extras/MacOSX/Resources/English.lproj/MainMenu.nib/objects.nib index 076c5b957b..c90f1b832d 100644 Binary files a/extras/MacOSX/Resources/English.lproj/MainMenu.nib/objects.nib and b/extras/MacOSX/Resources/English.lproj/MainMenu.nib/objects.nib differ diff --git a/extras/MacOSX/vlc.pbproj/project.pbxproj b/extras/MacOSX/vlc.pbproj/project.pbxproj index c95669b0e6..106fd6bd54 100644 --- a/extras/MacOSX/vlc.pbproj/project.pbxproj +++ b/extras/MacOSX/vlc.pbproj/project.pbxproj @@ -77,6 +77,8 @@ F6799748020DCC2A01A80112, F6799749020DCC2A01A80112, F679974A020DCC2A01A80112, + F6EA76F5024171E201A80112, + F6EA76F6024171E201A80112, ); isa = PBXGroup; name = Files; @@ -366,6 +368,18 @@ path = plugins/macosx/vout_window.h; refType = 4; }; + F6EA76F5024171E201A80112 = { + isa = PBXFileReference; + name = vout_vlc_wrapper.c; + path = plugins/macosx/vout_vlc_wrapper.c; + refType = 4; + }; + F6EA76F6024171E201A80112 = { + isa = PBXFileReference; + name = vout_vlc_wrapper.h; + path = plugins/macosx/vout_vlc_wrapper.h; + refType = 4; + }; }; rootObject = F511306E0170620B01A80A1F; } diff --git a/plugins/macosx/Makefile b/plugins/macosx/Makefile index 42b2fd4f5b..1de19e1e8a 100644 --- a/plugins/macosx/Makefile +++ b/plugins/macosx/Makefile @@ -1 +1 @@ -macosx_SOURCES = macosx.c aout_macosx.c vout_macosx.c vout_window.c vout_qdview.c intf_macosx.c intf_controller.c intf_vlc_wrapper.c +macosx_SOURCES = macosx.c aout_macosx.c vout_macosx.c vout_window.c vout_qdview.c vout_vlc_wrapper.c intf_macosx.c intf_controller.c intf_vlc_wrapper.c diff --git a/plugins/macosx/aout_macosx.c b/plugins/macosx/aout_macosx.c index 47b25eb874..056d589ba8 100644 --- a/plugins/macosx/aout_macosx.c +++ b/plugins/macosx/aout_macosx.c @@ -1,10 +1,11 @@ /***************************************************************************** - * aout_darwin.c : Darwin audio output plugin + * aout_macosx.c : CoreAudio output plugin ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: aout_macosx.c,v 1.14 2002/02/24 22:06:50 sam Exp $ + * $Id: aout_macosx.c,v 1.15 2002/03/19 03:33:52 jlj Exp $ * * Authors: Colin Delacroix + * Jon Lech Johansen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,19 +22,6 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ -/* - * 2001/03/21 - * Status of audio under Darwin - * It currently works with 16 bits signed big endian mpeg 1 audio - * (and probably mpeg 2). This is the most common case. - * Note: ac3 decoder is currently broken under Darwin - * - * TODO: - * Find little endian files and adapt output - * Find unsigned files and adapt output - * Find 8 bits files and adapt output - */ - /***************************************************************************** * Preamble *****************************************************************************/ @@ -45,56 +33,49 @@ #include #include - -#include - -/* - * Debug: to dump the output of the decoder directly to a file - * May disappear when AC3 decoder will work on Darwin - */ -#define WRITE_AUDIO_OUTPUT_TO_FILE 0 +#include /***************************************************************************** * aout_sys_t: private audio output method descriptor ***************************************************************************** * This structure is part of the audio output thread descriptor. - * It describes the Darwin specific properties of an output thread. + * It describes the CoreAudio specific properties of an output thread. *****************************************************************************/ typedef struct aout_sys_s { -#if WRITE_AUDIO_OUTPUT_TO_FILE - int fd; // debug: fd to dump audio -#endif - AudioStreamBasicDescription deviceFormat; // info about the default device - AudioDeviceID device; // the default device - Ptr p_Data; // ptr to the 32 bit float data - UInt32 ui_deviceBufferSize; // audio device buffer size - vlc_mutex_t mutex_lock; // pthread locks for sync of - vlc_cond_t cond_sync; // aout_Play and callback + AudioDeviceID device; // the audio device + AudioConverterRef s_converter; // the AudioConverter + int b_format; // format begun + + AudioStreamBasicDescription s_src_stream_format; + AudioStreamBasicDescription s_dst_stream_format; + + Ptr p_buffer; // ptr to the 32 bit float data + UInt32 ui_buffer_size; // audio device buffer size + vlc_mutex_t mutex_lock; // pthread locks for sync of + vlc_cond_t cond_sync; // aout_Play and callback } aout_sys_t; /***************************************************************************** * Local prototypes. *****************************************************************************/ -static int aout_Open ( aout_thread_t *p_aout ); -static int aout_SetFormat ( aout_thread_t *p_aout ); -static int aout_GetBufInfo ( aout_thread_t *p_aout, int i_buffer_info ); -static void aout_Play ( aout_thread_t *p_aout, +static int aout_Open ( aout_thread_t *p_aout ); +static int aout_SetFormat ( aout_thread_t *p_aout ); +static int aout_GetBufInfo ( aout_thread_t *p_aout, int i_buffer_info ); +static void aout_Play ( aout_thread_t *p_aout, byte_t *buffer, int i_size ); -static void aout_Close ( aout_thread_t *p_aout ); +static void aout_Close ( aout_thread_t *p_aout ); -static OSStatus appIOProc( AudioDeviceID inDevice, const AudioTimeStamp* inNow, - const void* inInputData, const AudioTimeStamp* inInputTime, - AudioBufferList* outOutputData, - const AudioTimeStamp* inOutputTime, - void* threadGlobals ); -static void Convert16BitIntegerTo32Float( Ptr p_in16BitDataPtr, Ptr p_out32BitDataPtr, - UInt32 ui_totalBytes ); -static void Convert16BitIntegerTo32FloatWithByteSwap( Ptr p_in16BitDataPtr, - Ptr p_out32BitDataPtr, - UInt32 p_totalBytes ); -static void Convert8BitIntegerTo32Float( Ptr in8BitDataPtr, Ptr p_out32BitDataPtr, - UInt32 ui_totalBytes ); +static int CABeginFormat ( aout_thread_t *p_aout ); +static int CAEndFormat ( aout_thread_t *p_aout ); + +static OSStatus CAIOCallback ( AudioDeviceID inDevice, + const AudioTimeStamp *inNow, + const void *inInputData, + const AudioTimeStamp *inInputTime, + AudioBufferList *outOutputData, + const AudioTimeStamp *inOutputTime, + void *threadGlobals ); /***************************************************************************** * Functions exported as capabilities. They are declared as static so that @@ -110,87 +91,82 @@ void _M( aout_getfunctions )( function_list_t * p_function_list ) } /***************************************************************************** - * aout_Open: opens a HAL audio device + * aout_Open: opens a CoreAudio HAL device *****************************************************************************/ static int aout_Open( aout_thread_t *p_aout ) { - OSStatus err = noErr; - UInt32 ui_paramSize, ui_bufferSize; - AudioDeviceID device = kAudioDeviceUnknown; - AudioStreamBasicDescription format; + OSStatus err; + UInt32 ui_param_size; - /* Allocate structure */ + /* allocate instance */ p_aout->p_sys = malloc( sizeof( aout_sys_t ) ); if( p_aout->p_sys == NULL ) { - intf_ErrMsg("aout error: %s", strerror(ENOMEM) ); + intf_ErrMsg( "aout error: %s", strerror(ENOMEM) ); return( 1 ); } - /* Initialize some variables */ - p_aout->p_sys->device = kAudioDeviceUnknown; - p_aout->p_sys->p_Data = nil; - - /* - * get the default output device for the HAL - * it is required to pass the size of the data to be returned - */ - ui_paramSize = sizeof( p_aout->p_sys->device ); + /* initialize members */ + memset( p_aout->p_sys, 0, sizeof( aout_sys_t ) ); + + /* get the default output device */ + ui_param_size = sizeof( p_aout->p_sys->device ); err = AudioHardwareGetProperty( kAudioHardwarePropertyDefaultOutputDevice, - &ui_paramSize, (void *) &device ); - - - if( err == noErr) + &ui_param_size, + (void *)&p_aout->p_sys->device ); + + if( err != noErr ) { - /* - * The values we get here are not used. We may find another method for - * insuring us that the audio device is working ! - * - * First get the buffersize that the default device uses for IO - */ - ui_paramSize = sizeof( p_aout->p_sys->ui_deviceBufferSize ); - err = AudioDeviceGetProperty( device, 0, false, - kAudioDevicePropertyBufferSize, - &ui_paramSize, &ui_bufferSize); - if( err == noErr ) - { - /* get a description of the data format used by the default device */ - ui_paramSize = sizeof(p_aout->p_sys->deviceFormat); - err = AudioDeviceGetProperty( device, 0, false, - kAudioDevicePropertyStreamFormat, - &ui_paramSize, &format); - if( err == noErr ) - { - if( format.mFormatID != kAudioFormatLinearPCM ) return paramErr; - - /* everything is ok so fill in p_sys */ - p_aout->p_sys->device = device; - p_aout->p_sys->ui_deviceBufferSize = ui_bufferSize; - p_aout->p_sys->deviceFormat = format; - } - } + intf_ErrMsg( "aout error: failed to get the device: %d", err ); + return( -1 ); } - if (err != noErr) return err; + /* get the buffer size that the device uses for IO */ + ui_param_size = sizeof( p_aout->p_sys->ui_buffer_size ); + err = AudioDeviceGetProperty( p_aout->p_sys->device, 0, false, + kAudioDevicePropertyBufferSize, + &ui_param_size, + &p_aout->p_sys->ui_buffer_size ); - /* - * Size calcul taken from audio_output.c we may change that file so we would - * not be forced to compute the same value twice - */ - p_aout->p_sys->ui_deviceBufferSize = - 2 * 2 * sizeof(s16) * ((s64)p_aout->i_rate * AOUT_BUFFER_DURATION) / 1000000; - - /* Allocate memory for audio */ - p_aout->p_sys->p_Data = NewPtrClear( p_aout->p_sys->ui_deviceBufferSize ); - if( p_aout->p_sys->p_Data == nil ) return paramErr; + if( err != noErr ) + { + intf_ErrMsg( "aout error: failed to get device buffer size: %d", err ); + return( -1 ); + } -#if WRITE_AUDIO_OUTPUT_TO_FILE - p_aout->p_sys->fd = open( "audio-darwin.pcm", O_RDWR|O_CREAT ); - intf_WarnMsg( 3, "open(...) -> %d", p_aout->p_sys->fd ); -#endif + /* get a description of the data format used by the device */ + ui_param_size = sizeof( p_aout->p_sys->s_dst_stream_format ); + err = AudioDeviceGetProperty( p_aout->p_sys->device, 0, false, + kAudioDevicePropertyStreamFormat, + &ui_param_size, + &p_aout->p_sys->s_dst_stream_format ); - vlc_cond_init( &p_aout->p_sys->cond_sync ); + if( err != noErr ) + { + intf_ErrMsg( "aout error: failed to get dst stream format: %d", err ); + return( -1 ); + } + + if( p_aout->p_sys->s_dst_stream_format.mFormatID != kAudioFormatLinearPCM ) + { + intf_ErrMsg( "aout error: kAudioFormatLinearPCM required" ); + return( -1 ); + } + + /* initialize mutex and cond */ vlc_mutex_init( &p_aout->p_sys->mutex_lock ); + vlc_cond_init( &p_aout->p_sys->cond_sync ); + + /* initialize source stream format */ + memcpy( &p_aout->p_sys->s_src_stream_format, + &p_aout->p_sys->s_dst_stream_format, + sizeof( p_aout->p_sys->s_src_stream_format ) ); + + if( CABeginFormat( p_aout ) ) + { + intf_ErrMsg( "aout error: CABeginFormat failed" ); + return( -1 ); + } return( 0 ); } @@ -200,113 +176,85 @@ static int aout_Open( aout_thread_t *p_aout ) *****************************************************************************/ static int aout_SetFormat( aout_thread_t *p_aout ) { - OSStatus err = noErr; - UInt32 ui_paramSize, - ui_bufferSize = p_aout->p_sys->ui_deviceBufferSize; - AudioStreamBasicDescription format; - - /* set the buffersize that the default device uses for IO */ - ui_paramSize = sizeof( ui_bufferSize ); - err = AudioDeviceSetProperty( p_aout->p_sys->device, 0, 0, false, - kAudioDevicePropertyBufferSize, - ui_paramSize, &ui_bufferSize); - if( err != noErr ) + if( CAEndFormat( p_aout ) ) { - /* We have to tell the decoder to use audio device's buffer size */ - intf_ErrMsg( "aout : AudioDeviceSetProperty failed ( buffersize = %d ) -> %d", - ui_bufferSize, err ); + intf_ErrMsg( "aout error: CAEndFormat failed" ); return( -1 ); } - else + + switch( p_aout->i_format ) { - p_aout->p_sys->ui_deviceBufferSize = ui_bufferSize; - - ui_paramSize = sizeof( format ); - err = AudioDeviceGetProperty( p_aout->p_sys->device, 0, false, - kAudioDevicePropertyStreamFormat, - &ui_paramSize, &format); + case AOUT_FMT_S8: + intf_ErrMsg( "Audio format (Signed 8) not supported now," + "please report stream" ); + return( -1 ); + + case AOUT_FMT_U8: + intf_ErrMsg( "Audio format (Unsigned 8) not supported now," + "please report stream" ); + return( -1 ); - if( err == noErr ) - { - /* - * setting format.mFormatFlags to anything but the default value - * doesn't seem to work. Can anybody explain that ?? - */ + case AOUT_FMT_S16_LE: + p_aout->p_sys->s_src_stream_format.mFormatFlags &= + ~kLinearPCMFormatFlagIsBigEndian; + p_aout->p_sys->s_src_stream_format.mFormatFlags |= + kLinearPCMFormatFlagIsSignedInteger; + break; - switch( p_aout->i_format ) - { - case AOUT_FMT_U8: - intf_ErrMsg( "Audio format (Unsigned 8) not supported now," - "please report stream" ); - return( -1 ); - - case AOUT_FMT_S16_LE: /* Little endian signed 16 */ - // format.mFormatFlags &= ~kLinearPCMFormatFlagIsBigEndian; - intf_ErrMsg( "Audio format (LE Unsigned 16) not supported now," - "please report stream" ); - return( -1 ); - - case AOUT_FMT_S16_BE: /* Big endian signed 16 */ - // format.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian; - break; - - case AOUT_FMT_S8: - intf_ErrMsg( "Audio format (Signed 8) not supported now," - "please report stream" ); - return( -1 ); - - case AOUT_FMT_U16_LE: /* Little endian U16 */ - // format.mFormatFlags &= ~kLinearPCMFormatFlagIsSignedInteger; - intf_ErrMsg( "Audio format (LE Unsigned 8) not supported now," - "please report stream" ); - return( -1 ); - - case AOUT_FMT_U16_BE: /* Big endian U16 */ - // format.mFormatFlags &= ~kLinearPCMFormatFlagIsSignedInteger; - intf_ErrMsg( "Audio format (BE Unsigned 8) not supported now," - "please report stream" ); - return( -1 ); - - break; - default: - return( -1 ); - } + case AOUT_FMT_S16_BE: + p_aout->p_sys->s_src_stream_format.mFormatFlags |= + kLinearPCMFormatFlagIsBigEndian; + p_aout->p_sys->s_src_stream_format.mFormatFlags |= + kLinearPCMFormatFlagIsSignedInteger; + break; - /* - * It would have been nice to have these work (no more buffer - * convertion to float) but I couldn't manage to - */ - // format.mFormatFlags &= ~kLinearPCMFormatFlagIsFloat; - // format.mFormatFlags |= kLinearPCMFormatFlagIsFloat; - // format.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger; - - format.mSampleRate = p_aout->i_rate; - format.mChannelsPerFrame = p_aout->i_channels; - - err = AudioDeviceSetProperty( p_aout->p_sys->device, 0, 0, false, - kAudioDevicePropertyStreamFormat, - ui_paramSize, &format); - if( err != noErr ) - { - intf_ErrMsg( "aout : AudioDeviceSetProperty( mFormatFlags = %x, " - "mSampleRate = %f, mChannelsPerFrame = %d ) -> %d", - format.mFormatFlags, format.mSampleRate, - format.mChannelsPerFrame, err ); - return( -1 ); - } - } + case AOUT_FMT_U16_LE: + p_aout->p_sys->s_src_stream_format.mFormatFlags &= + ~kLinearPCMFormatFlagIsBigEndian; + p_aout->p_sys->s_src_stream_format.mFormatFlags &= + ~kLinearPCMFormatFlagIsSignedInteger; + break; + + case AOUT_FMT_U16_BE: + p_aout->p_sys->s_src_stream_format.mFormatFlags |= + kLinearPCMFormatFlagIsBigEndian; + p_aout->p_sys->s_src_stream_format.mFormatFlags &= + ~kLinearPCMFormatFlagIsSignedInteger; + break; + + default: + intf_ErrMsg( "Audio format (0x%08x) not supported now," + "please report stream", p_aout->i_format ); + return( -1 ); } - /* add callback */ - err = AudioDeviceAddIOProc( p_aout->p_sys->device, - (AudioDeviceIOProc)appIOProc, - (void *)p_aout->p_sys ); + /* source format is not float */ + p_aout->p_sys->s_src_stream_format.mFormatFlags &= + ~kLinearPCMFormatFlagIsFloat; - /* open the output */ - if( err == noErr ) - err = AudioDeviceStart( p_aout->p_sys->device, (AudioDeviceIOProc)appIOProc ); - - return( err ); + /* if destination format is float, take size diff into account */ + if( p_aout->p_sys->s_dst_stream_format.mFormatFlags & + kLinearPCMFormatFlagIsFloat ) + { + p_aout->p_sys->s_src_stream_format.mBytesPerPacket = + p_aout->p_sys->s_dst_stream_format.mBytesPerPacket / 2; + p_aout->p_sys->s_src_stream_format.mBytesPerFrame = + p_aout->p_sys->s_src_stream_format.mBytesPerFrame / 2; + p_aout->p_sys->s_src_stream_format.mBitsPerChannel = + p_aout->p_sys->s_src_stream_format.mBitsPerChannel / 2; + } + + /* set sample rate and channels per frame */ + p_aout->p_sys->s_src_stream_format.mSampleRate = p_aout->i_rate; + p_aout->p_sys->s_src_stream_format.mChannelsPerFrame = p_aout->i_channels; + + if( CABeginFormat( p_aout ) ) + { + intf_ErrMsg( "aout error: CABeginFormat failed" ); + return( -1 ); + } + + return( 0 ); } /***************************************************************************** @@ -314,36 +262,30 @@ static int aout_SetFormat( aout_thread_t *p_aout ) *****************************************************************************/ static int aout_GetBufInfo( aout_thread_t *p_aout, int i_buffer_limit ) { - return( 0 ); // Send data as soon as possible - - /* - * Tune me ? - * - return ( p_aout->p_sys->p_Data - + p_aout->p_sys->sizeOfDataInMemory - - p_aout->p_sys->currentDataLocationPtr - - p_aout->p_sys->ui_deviceBufferSize ); - */ + return( 0 ); /* send data as soon as possible */ } /***************************************************************************** - * appIOProc : callback for audio output + * CAIOCallback : callback for audio output *****************************************************************************/ -static OSStatus appIOProc( AudioDeviceID inDevice, const AudioTimeStamp* inNow, - const void* inInputData, const AudioTimeStamp* inInputTime, - AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, - void* threadGlobals ) +static OSStatus CAIOCallback( AudioDeviceID inDevice, + const AudioTimeStamp *inNow, + const void *inInputData, + const AudioTimeStamp *inInputTime, + AudioBufferList *outOutputData, + const AudioTimeStamp *inOutputTime, + void *threadGlobals ) { - aout_sys_t* p_sys = threadGlobals; + aout_sys_t *p_sys = (aout_sys_t *)threadGlobals; /* see aout_Play below */ vlc_mutex_lock( &p_sys->mutex_lock ); vlc_cond_signal( &p_sys->cond_sync ); /* move data into output data buffer */ - BlockMoveData( p_sys->p_Data, + BlockMoveData( p_sys->p_buffer, outOutputData->mBuffers[ 0 ].mData, - p_sys->ui_deviceBufferSize ); + p_sys->ui_buffer_size ); vlc_mutex_unlock( &p_sys->mutex_lock ); @@ -355,106 +297,172 @@ static OSStatus appIOProc( AudioDeviceID inDevice, const AudioTimeStamp* inNow *****************************************************************************/ static void aout_Play( aout_thread_t *p_aout, byte_t *buffer, int i_size ) { -#if WRITE_AUDIO_OUTPUT_TO_FILE - write( p_aout->p_sys->fd, buffer, i_size ); -#else - Convert16BitIntegerTo32Float( buffer, p_aout->p_sys->p_Data, i_size ); - + OSStatus err; + UInt32 ui_buffer_size = p_aout->p_sys->ui_buffer_size; + + err = AudioConverterConvertBuffer( p_aout->p_sys->s_converter, + i_size, buffer, + &ui_buffer_size, + p_aout->p_sys->p_buffer ); + + if( err != noErr ) + { + intf_ErrMsg( "aout error: ConvertBuffer failed: %d", err ); + } + /* * wait for a callback to occur (to flush the buffer), so aout_Play * can't be called twice, losing the data we just wrote. */ + vlc_mutex_lock( &p_aout->p_sys->mutex_lock ); vlc_cond_wait( &p_aout->p_sys->cond_sync, &p_aout->p_sys->mutex_lock ); -#endif + vlc_mutex_unlock( &p_aout->p_sys->mutex_lock ); } /***************************************************************************** - * aout_Close: closes the dummy audio device + * aout_Close: closes the CoreAudio HAL device *****************************************************************************/ static void aout_Close( aout_thread_t *p_aout ) { - OSStatus err = noErr; - + if( CAEndFormat( p_aout ) ) + { + intf_ErrMsg( "aout error: CAEndFormat failed" ); + } + + /* destroy lock and cond */ + vlc_mutex_destroy( &p_aout->p_sys->mutex_lock ); + vlc_cond_destroy( &p_aout->p_sys->cond_sync ); + + free( p_aout->p_sys ); +} + +/***************************************************************************** + * CABeginFormat: creates an AudioConverter + *****************************************************************************/ +static int CABeginFormat( aout_thread_t *p_aout ) +{ + OSStatus err; + UInt32 ui_param_size; + + if( p_aout->p_sys->b_format ) + { + intf_ErrMsg( "aout error: CABeginFormat (b_format)" ); + return( 1 ); + } + + p_aout->p_sys->ui_buffer_size = 2 * 2 * sizeof(s16) * + ((s64)p_aout->i_rate * AOUT_BUFFER_DURATION) / 1000000; + + /* set the buffer size that the device uses for IO */ + ui_param_size = sizeof( p_aout->p_sys->ui_buffer_size ); + err = AudioDeviceSetProperty( p_aout->p_sys->device, 0, 0, false, + kAudioDevicePropertyBufferSize, + ui_param_size, + &p_aout->p_sys->ui_buffer_size ); + + if( err != noErr ) + { + intf_ErrMsg( "aout error: AudioDeviceSetProperty failed: %d", err ); + return( 1 ); + } + + /* allocate audio buffer */ + p_aout->p_sys->p_buffer = NewPtrClear( p_aout->p_sys->ui_buffer_size ); + + if( p_aout->p_sys->p_buffer == nil ) + { + intf_ErrMsg( "aout error: failed to allocate audio buffer" ); + return( 1 ); + } + + /* create a new AudioConverter */ + err = AudioConverterNew( &p_aout->p_sys->s_src_stream_format, + &p_aout->p_sys->s_dst_stream_format, + &p_aout->p_sys->s_converter ); + + if( err != noErr ) + { + intf_ErrMsg( "aout error: AudioConverterNew failed: %d", err ); + DisposePtr( p_aout->p_sys->p_buffer ); + return( 1 ); + } + + /* add callback */ + err = AudioDeviceAddIOProc( p_aout->p_sys->device, + (AudioDeviceIOProc)CAIOCallback, + (void *)p_aout->p_sys ); + + if( err != noErr ) + { + intf_ErrMsg( "aout error: AudioDeviceAddIOProc failed: %d", err ); + AudioConverterDispose( p_aout->p_sys->s_converter ); + DisposePtr( p_aout->p_sys->p_buffer ); + return( 1 ); + } + + /* open the output */ + err = AudioDeviceStart( p_aout->p_sys->device, + (AudioDeviceIOProc)CAIOCallback ); + + if( err != noErr ) + { + intf_ErrMsg( "aout error: AudioDeviceStart failed: %d", err ); + AudioConverterDispose( p_aout->p_sys->s_converter ); + DisposePtr( p_aout->p_sys->p_buffer ); + return( 1 ); + } + + p_aout->p_sys->b_format = 1; + + return( 0 ); +} + +/***************************************************************************** + * CAEndFormat: destroys the AudioConverter + *****************************************************************************/ +static int CAEndFormat( aout_thread_t *p_aout ) +{ + OSStatus err; + + if( !p_aout->p_sys->b_format ) + { + intf_ErrMsg( "aout error: CAEndFormat (!b_format)" ); + return( 1 ); + } + /* stop playing sound through the device */ - err = AudioDeviceStop( p_aout->p_sys->device, - (AudioDeviceIOProc)appIOProc ); - if( err == noErr ) + err = AudioDeviceStop( p_aout->p_sys->device, + (AudioDeviceIOProc)CAIOCallback ); + + if( err != noErr ) { - /* remove the callback */ - err = AudioDeviceRemoveIOProc( p_aout->p_sys->device, - (AudioDeviceIOProc)appIOProc ); + intf_ErrMsg( "aout error: AudioDeviceStop failed: %d", err ); + return( 1 ); } - DisposePtr( p_aout->p_sys->p_Data ); - - return; -} + /* remove the callback */ + err = AudioDeviceRemoveIOProc( p_aout->p_sys->device, + (AudioDeviceIOProc)CAIOCallback ); -/***************************************************************************** - * Convert16BitIntegerTo32Float - *****************************************************************************/ -static void Convert16BitIntegerTo32Float( Ptr p_in16BitDataPtr, Ptr p_out32BitDataPtr, - UInt32 ui_totalBytes ) -{ - UInt32 i, ui_samples = ui_totalBytes / 2 /* each 16 bit sample is 2 bytes */; - SInt16 *p_s_inDataPtr = (SInt16 *) p_in16BitDataPtr; - Float32 *p_f_outDataPtr = (Float32 *) p_out32BitDataPtr; - - for( i = 0 ; i < ui_samples ; i++ ) + if( err != noErr ) { - *p_f_outDataPtr = (Float32)(*p_s_inDataPtr); - if( *p_f_outDataPtr > 0 ) - *p_f_outDataPtr /= 32767.0; - else - *p_f_outDataPtr /= 32768.0; - p_f_outDataPtr++; - p_s_inDataPtr++; + intf_ErrMsg( "aout error: AudioDeviceRemoveIOProc failed: %d", err ); + return( 1 ); } -} - -/***************************************************************************** - * Convert16BitIntegerTo32FloatWithByteSwap - *****************************************************************************/ -static void Convert16BitIntegerTo32FloatWithByteSwap( Ptr p_in16BitDataPtr, - Ptr p_out32BitDataPtr, - UInt32 ui_totalBytes ) -{ - UInt32 i, ui_samples = ui_totalBytes / 2 /* each 16 bit sample is 2 bytes */; - SInt16 *p_s_inDataPtr = (SInt16 *) p_in16BitDataPtr; - Float32 *p_f_outDataPtr = (Float32 *) p_out32BitDataPtr; - - for( i = 0 ; i < ui_samples ; i++ ) - { - *p_f_outDataPtr = (Float32)CFSwapInt16LittleToHost(*p_s_inDataPtr); - if( *p_f_outDataPtr > 0 ) - *p_f_outDataPtr /= 32767.0; - else - *p_f_outDataPtr /= 32768.0; - p_f_outDataPtr++; - p_s_inDataPtr++; - } -} - -/***************************************************************************** - * Convert8BitIntegerTo32Float - *****************************************************************************/ -static void Convert8BitIntegerTo32Float( Ptr p_in8BitDataPtr, Ptr p_out32BitDataPtr, - UInt32 ui_totalBytes ) -{ - UInt32 i, ui_samples = ui_totalBytes; - SInt8 *p_c_inDataPtr = (SInt8 *)p_in8BitDataPtr; - Float32 *p_f_outDataPtr = (Float32 *)p_out32BitDataPtr; - - for( i = 0 ; i < ui_samples ; i++ ) + /* destroy the AudioConverter */ + err = AudioConverterDispose( p_aout->p_sys->s_converter ); + + if( err != noErr ) { - *p_f_outDataPtr = (Float32)(*p_c_inDataPtr); - if( *p_f_outDataPtr > 0 ) - *p_f_outDataPtr /= 32767.0; - else - *p_f_outDataPtr /= 32768.0; - - p_f_outDataPtr++; - p_c_inDataPtr++; + intf_ErrMsg( "aout error: AudioConverterDispose failed: %d", err ); + return( 1 ); } + + /* release audio buffer */ + DisposePtr( p_aout->p_sys->p_buffer ); + + p_aout->p_sys->b_format = 0; + + return( 0 ); } diff --git a/plugins/macosx/intf_controller.c b/plugins/macosx/intf_controller.c index 83301a9d39..ffa202c74f 100644 --- a/plugins/macosx/intf_controller.c +++ b/plugins/macosx/intf_controller.c @@ -2,7 +2,7 @@ * intf_controller.c: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: intf_controller.c,v 1.3 2002/02/18 01:34:44 jlj Exp $ + * $Id: intf_controller.c,v 1.4 2002/03/19 03:33:52 jlj Exp $ * * Authors: Florian G. Pflug * Jon Lech Johansen @@ -32,10 +32,6 @@ #include "macosx.h" #include "intf_controller.h" -@interface Intf_Controller (Internal) -- (void)handlePortMessage:(NSPortMessage *)o_msg; -@end - @implementation Intf_Controller /* Initialization & Event-Management */ @@ -45,20 +41,17 @@ NSString *pTitle = [NSString stringWithCString: VOUT_TITLE " (Cocoa)"]; - o_vlc = [Intf_VlcWrapper instance]; - [o_vlc initWithDelegate: self]; - [o_window setTitle: pTitle]; } - (void)applicationDidFinishLaunching:(NSNotification *)o_notification { - [[o_vlc sendPort] setDelegate: self]; + o_intf = [[Intf_VLCWrapper instance] retain]; + o_vout = [[Vout_VLCWrapper instance] retain]; + + f_slider = f_slider_old = 0.0; + o_slider_lock = [[NSLock alloc] init]; - [[NSRunLoop currentRunLoop] - addPort: [o_vlc sendPort] - forMode: NSDefaultRunLoopMode]; - [NSThread detachNewThreadSelector: @selector(manage) toTarget: self withObject: nil]; } @@ -70,13 +63,31 @@ o_pool = [[NSAutoreleasePool alloc] init]; - while( ![o_vlc manage] ) + while( ![o_intf manage] ) { - [o_currenttime setStringValue: [o_vlc getTimeAsString]]; - [o_timeslider setFloatValue: [o_vlc getTimeAsFloat]]; + if( [o_intf playlistPlaying] ) + { + [o_currenttime setStringValue: [o_intf getTimeAsString]]; + + if( f_slider == f_slider_old ) + { + float f_updated = [o_intf getTimeAsFloat]; + + if( f_updated != f_slider ) + { + if( [o_slider_lock tryLock] ) + { + [o_timeslider setFloatValue: f_updated]; + [o_slider_lock unlock]; + } + } + } + else + { + [o_intf setTimeAsFloat: f_slider]; + f_slider_old = f_slider; + } - if( [o_vlc playlistPlaying] ) - { UpdateSystemActivity( UsrActivity ); } @@ -95,6 +106,9 @@ [NSApp stop: nil]; + [o_vout release]; + [o_intf release]; + /* send a dummy event to break out of the event loop */ pEvent = [NSEvent mouseEventWithType: NSLeftMouseDown location: NSMakePoint( 1, 1 ) modifierFlags: 0 @@ -120,36 +134,49 @@ while( ( o_file = (NSString *)[o_files nextObject] ) ) { - [o_vlc playlistAdd: o_file]; + [o_intf playlistAdd: o_file]; } - [o_vlc playlistPlayCurrent]; + [o_intf playlistPlayCurrent]; } } - (IBAction)pause:(id)sender { - [o_vlc playlistPause]; + [o_intf playlistPause]; } - (IBAction)play:(id)sender { - [o_vlc playlistPlayCurrent]; + [o_intf playlistPlayCurrent]; } - (IBAction)stop:(id)sender { - [o_vlc playlistStop]; + [o_intf playlistStop]; } - (IBAction)timeslider_update:(id)slider { - [o_vlc setTimeAsFloat: [o_timeslider floatValue]]; + switch( [[NSApp currentEvent] type] ) + { + case NSLeftMouseDown: + [o_slider_lock lock]; + break; + + case NSLeftMouseUp: + f_slider = [o_timeslider floatValue]; + [o_slider_lock unlock]; + break; + + default: + break; + } } - (IBAction)speedslider_update:(id)slider { - [o_vlc setSpeed: (intf_speed_t)[slider intValue]]; + [o_intf setSpeed: (intf_speed_t)[slider intValue]]; } - (IBAction)fullscreen_toggle:(id)sender @@ -159,31 +186,26 @@ - (IBAction)quit:(id)sender { - [o_vlc quit]; -} - -@end - -@implementation Intf_Controller (Internal) - -- (void)handlePortMessage:(NSPortMessage *)o_msg -{ - [o_vlc handlePortMessage: o_msg]; + [o_intf quit]; } @end @implementation Intf_PlaylistDS -- (void)awakeFromNib +- (id)init { - o_vlc = [Intf_VlcWrapper instance]; + if( [super init] == nil ) + return( nil ); + o_playlist = nil; + + return( self ); } - + - (void)readPlaylist { - o_playlist = [[o_vlc playlistAsArray] retain]; + o_playlist = [[[Intf_VLCWrapper instance] playlistAsArray] retain]; } - (int)numberOfRowsInTableView:(NSTableView*)o_table @@ -202,4 +224,3 @@ } @end - diff --git a/plugins/macosx/intf_controller.h b/plugins/macosx/intf_controller.h index b950dfeb9a..9dde9f2105 100644 --- a/plugins/macosx/intf_controller.h +++ b/plugins/macosx/intf_controller.h @@ -2,7 +2,7 @@ * intf_controller.h: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: intf_controller.h,v 1.3 2002/02/18 01:34:44 jlj Exp $ + * $Id: intf_controller.h,v 1.4 2002/03/19 03:33:52 jlj Exp $ * * Authors: Florian G. Pflug * @@ -22,16 +22,15 @@ *****************************************************************************/ #include "intf_vlc_wrapper.h" +#include "vout_vlc_wrapper.h" @interface Intf_PlaylistDS : NSObject { - Intf_VlcWrapper *o_vlc; NSMutableArray *o_playlist; IBOutlet NSTableView *o_table; } -- (void)awakeFromNib; - (void)readPlaylist; - (int)numberOfRowsInTableView:(NSTableView *)o_table; @@ -42,7 +41,11 @@ @interface Intf_Controller : NSObject { - Intf_VlcWrapper *o_vlc; + Intf_VLCWrapper *o_intf; + Vout_VLCWrapper *o_vout; + + NSLock *o_slider_lock; + float f_slider, f_slider_old; IBOutlet NSWindow *o_window; IBOutlet NSButton *o_play; diff --git a/plugins/macosx/intf_vlc_wrapper.c b/plugins/macosx/intf_vlc_wrapper.c index fea21f029a..39f2da39f7 100644 --- a/plugins/macosx/intf_vlc_wrapper.c +++ b/plugins/macosx/intf_vlc_wrapper.c @@ -2,7 +2,7 @@ * intf_vlc_wrapper.c: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: intf_vlc_wrapper.c,v 1.8 2002/02/18 01:34:44 jlj Exp $ + * $Id: intf_vlc_wrapper.c,v 1.9 2002/03/19 03:33:52 jlj Exp $ * * Authors: Florian G. Pflug * Jon Lech Johansen @@ -39,30 +39,36 @@ #include "macosx.h" #include "intf_vlc_wrapper.h" -@implementation Intf_VlcWrapper +@implementation Intf_VLCWrapper + +static Intf_VLCWrapper *o_intf = nil; /* Initialization */ -+ (Intf_VlcWrapper *)instance -{ - static bool b_initialized = 0; - static Intf_VlcWrapper* o_vlc = nil; - - if( !b_initialized ) - { - o_vlc = [[Intf_VlcWrapper alloc] init]; - b_initialized = TRUE; - } - - return o_vlc; -} - -- (Intf_VlcWrapper *)initWithDelegate:(id)_o_delegate +- (id)init { + if( [super init] == nil ) + return( nil ); + e_speed = SPEED_NORMAL; - o_delegate = _o_delegate; - - return self; + + return( self ); +} + ++ (Intf_VLCWrapper *)instance +{ + if( o_intf == nil ) + { + o_intf = [[[Intf_VLCWrapper alloc] init] autorelease]; + } + + return( o_intf ); +} + +- (void)dealloc +{ + o_intf = nil; + [super dealloc]; } - (bool)manage @@ -88,98 +94,6 @@ p_main->p_intf->b_die = 1; } -/* Vout requests */ -- (void)handlePortMessage:(NSPortMessage *)o_msg -{ - NSData *o_req; - struct vout_req_s *p_req; - - o_req = [[o_msg components] lastObject]; - p_req = *((struct vout_req_s **)[o_req bytes]); - - [p_req->o_lock lock]; - - if( p_req->i_type == VOUT_REQ_CREATE_WINDOW ) - { - VLCView *o_view; - - p_req->p_vout->p_sys->o_window = [VLCWindow alloc]; - [p_req->p_vout->p_sys->o_window setVout: p_req->p_vout]; - [p_req->p_vout->p_sys->o_window setReleasedWhenClosed: YES]; - - if( p_req->p_vout->b_fullscreen ) - { - [p_req->p_vout->p_sys->o_window - initWithContentRect: [[NSScreen mainScreen] frame] - styleMask: NSBorderlessWindowMask - backing: NSBackingStoreBuffered - defer: NO screen: [NSScreen mainScreen]]; - - [p_req->p_vout->p_sys->o_window - setLevel: CGShieldingWindowLevel()]; - } - else - { - unsigned int i_stylemask = NSTitledWindowMask | - NSMiniaturizableWindowMask | - NSResizableWindowMask; - - [p_req->p_vout->p_sys->o_window - initWithContentRect: p_req->p_vout->p_sys->s_rect - styleMask: i_stylemask - backing: NSBackingStoreBuffered - defer: NO screen: [NSScreen mainScreen]]; - - if( !p_req->p_vout->p_sys->b_pos_saved ) - { - [p_req->p_vout->p_sys->o_window center]; - } - } - - o_view = [[VLCView alloc] initWithVout: p_req->p_vout]; - [p_req->p_vout->p_sys->o_window setContentView: o_view]; - - [o_view lockFocus]; - p_req->p_vout->p_sys->p_qdport = [o_view qdPort]; - [o_view unlockFocus]; - - [p_req->p_vout->p_sys->o_window setTitle: [NSString - stringWithCString: VOUT_TITLE]]; - [p_req->p_vout->p_sys->o_window setAcceptsMouseMovedEvents: YES]; - [p_req->p_vout->p_sys->o_window makeKeyAndOrderFront: nil]; - - p_req->i_result = 1; - } - else if( p_req->i_type == VOUT_REQ_DESTROY_WINDOW ) - { - if( !p_req->p_vout->b_fullscreen ) - { - NSRect s_rect; - - s_rect = [[p_req->p_vout->p_sys->o_window contentView] frame]; - p_req->p_vout->p_sys->s_rect.size = s_rect.size; - - s_rect = [p_req->p_vout->p_sys->o_window frame]; - p_req->p_vout->p_sys->s_rect.origin = s_rect.origin; - - p_req->p_vout->p_sys->b_pos_saved = 1; - } - - p_req->p_vout->p_sys->p_qdport = nil; - [p_req->p_vout->p_sys->o_window close]; - p_req->p_vout->p_sys->o_window = nil; - - p_req->i_result = 1; - } - - [p_req->o_lock unlockWithCondition: 1]; -} - -- (NSPort *)sendPort -{ - return( p_main->p_intf->p_sys->o_port ); -} - /* Playback control */ - (void)setSpeed:(intf_speed_t)_e_speed { @@ -206,12 +120,18 @@ - (float)getTimeAsFloat { - if( p_input_bank->pp_input[0] == NULL ) + float f_time = 0.0; + + vlc_mutex_lock( &p_input_bank->lock ); + + if( p_input_bank->pp_input[0] != NULL ) { - return( 0.0 ); + f_time = (float)p_area->i_tell / (float)p_area->i_size; } - return( (float)p_area->i_tell / (float)p_area->i_size ); + vlc_mutex_unlock( &p_input_bank->lock ); + + return( f_time ); } - (void)setTimeAsFloat:(float)f_position @@ -400,7 +320,7 @@ - (bool)playlistPlaying { - return( p_main->p_playlist->b_stopped ); + return( !p_main->p_playlist->b_stopped ); } @end diff --git a/plugins/macosx/intf_vlc_wrapper.h b/plugins/macosx/intf_vlc_wrapper.h index 7688e19609..be86839f97 100644 --- a/plugins/macosx/intf_vlc_wrapper.h +++ b/plugins/macosx/intf_vlc_wrapper.h @@ -2,7 +2,7 @@ * intf_vlc_wrapper.h: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: intf_vlc_wrapper.h,v 1.3 2002/02/18 01:34:44 jlj Exp $ + * $Id: intf_vlc_wrapper.h,v 1.4 2002/03/19 03:33:52 jlj Exp $ * * Authors: Florian G. Pflug * Jon Lech Johansen @@ -29,26 +29,20 @@ typedef enum intf_speed_e SPEED_FAST } intf_speed_t; -/* Intf_VlcWrapper is a singleton class +/* Intf_VLCWrapper is a singleton class (only one instance at any time) */ -@interface Intf_VlcWrapper : NSObject +@interface Intf_VLCWrapper : NSObject { - id o_delegate; intf_speed_t e_speed; } /* Initialization */ -+ (Intf_VlcWrapper *)instance; -- (Intf_VlcWrapper *)initWithDelegate:(id)o_delegate; ++ (Intf_VLCWrapper *)instance; - (bool)manage; - (void)quit; -/* Vout requests */ -- (void)handlePortMessage:(NSPortMessage *)o_msg; -- (NSPort *)sendPort; - /* Playback control */ - (void)setSpeed:(intf_speed_t)e_speed; - (NSString *)getTimeAsString; diff --git a/plugins/macosx/vout_qdview.c b/plugins/macosx/vout_qdview.c index 8b4b22bad9..af8acfe259 100644 --- a/plugins/macosx/vout_qdview.c +++ b/plugins/macosx/vout_qdview.c @@ -2,7 +2,7 @@ * vout_qdview.c: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: vout_qdview.c,v 1.1 2002/02/18 01:34:44 jlj Exp $ + * $Id: vout_qdview.c,v 1.2 2002/03/19 03:33:52 jlj Exp $ * * Authors: Florian G. Pflug * Jon Lech Johansen @@ -25,36 +25,30 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* ENOMEM */ -#include /* free() */ -#include /* strerror() */ +#import -#include - -#include "video.h" -#include "video_output.h" - -#include "macosx.h" +#import "vout_qdview.h" /***************************************************************************** * VLCView implementation *****************************************************************************/ @implementation VLCView -- (id)initWithVout:(struct vout_thread_s *)_p_vout +- (id)initWithWrapper:(Vout_VLCWrapper *)_o_wrapper forVout:(void *)_p_vout { if( [super init] == nil ) return nil; p_vout = _p_vout; + o_wrapper = _o_wrapper; - return self; + return( self ); } - (void)drawRect:(NSRect)rect { [super drawRect: rect]; - p_vout->i_changes |= VOUT_SIZE_CHANGE; + [o_wrapper voutDidResize: p_vout]; } @end diff --git a/plugins/macosx/vout_qdview.h b/plugins/macosx/vout_qdview.h index 4b8ba6d750..ba3ceba1aa 100644 --- a/plugins/macosx/vout_qdview.h +++ b/plugins/macosx/vout_qdview.h @@ -2,7 +2,7 @@ * vout_qdview.h: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: vout_qdview.h,v 1.1 2002/02/18 01:34:44 jlj Exp $ + * $Id: vout_qdview.h,v 1.2 2002/03/19 03:33:52 jlj Exp $ * * Authors: Florian G. Pflug * Jon Lech Johansen @@ -22,11 +22,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +#import "vout_vlc_wrapper.h" + @interface VLCView : NSQuickDrawView { - struct vout_thread_s *p_vout; + void *p_vout; + Vout_VLCWrapper *o_wrapper; } -- (id)initWithVout:(struct vout_thread_s *)_p_vout; +- (id)initWithWrapper:(Vout_VLCWrapper *)_o_wrapper forVout:(void *)_p_vout; @end diff --git a/plugins/macosx/vout_vlc_wrapper.c b/plugins/macosx/vout_vlc_wrapper.c new file mode 100644 index 0000000000..2c9af4b446 --- /dev/null +++ b/plugins/macosx/vout_vlc_wrapper.c @@ -0,0 +1,220 @@ +/***************************************************************************** + * vout_vlc_wrapper.c: MacOS X plugin for vlc + ***************************************************************************** + * Copyright (C) 2001 VideoLAN + * $Id: vout_vlc_wrapper.c,v 1.1 2002/03/19 03:33:52 jlj Exp $ + * + * Authors: Jon Lech Johansen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +/***************************************************************************** + * Preamble + *****************************************************************************/ +#include /* ENOMEM */ +#include /* free() */ +#include /* strerror() */ + +#include + +#include "video.h" +#include "video_output.h" + +#include "interface.h" + +#include "macosx.h" +#include "vout_vlc_wrapper.h" + +/***************************************************************************** + * Vout_VLCWrapper implementation + *****************************************************************************/ +@implementation Vout_VLCWrapper + +static Vout_VLCWrapper *o_vout = nil; + ++ (Vout_VLCWrapper *)instance +{ + if( o_vout == nil ) + { + o_vout = [[[Vout_VLCWrapper alloc] init] autorelease]; + + [[Vout_VLCWrapper sendPort] setDelegate: o_vout]; + [[NSRunLoop currentRunLoop] + addPort: [Vout_VLCWrapper sendPort] + forMode: NSDefaultRunLoopMode]; + } + + return( o_vout ); +} + +- (void)dealloc +{ + o_vout = nil; + [super dealloc]; +} + ++ (NSPort *)sendPort +{ + return( p_main->p_intf->p_sys->o_port ); +} + +- (void)voutDidResize:(void *)_p_vout +{ + struct vout_thread_s *p_vout = + (struct vout_thread_s *)_p_vout; + + p_vout->i_changes |= VOUT_SIZE_CHANGE; +} + +- (void)mouseEvent:(unsigned int)ui_status forVout:(void *)_p_vout +{ + struct vout_thread_s *p_vout = + (struct vout_thread_s *)_p_vout; + + if( ui_status & MOUSE_MOVED ) + p_vout->p_sys->b_mouse_moved = 1; + if( ui_status & MOUSE_NOT_MOVED ) + p_vout->p_sys->b_mouse_moved = 0; + if( ui_status & MOUSE_LAST_MOVED ) + p_vout->p_sys->i_time_mouse_last_moved = mdate(); + if( ui_status & MOUSE_NOT_LAST_MOVED ) + p_vout->p_sys->i_time_mouse_last_moved = 0; +} + +- (BOOL)keyDown:(NSEvent *)o_event forVout:(void *)_p_vout +{ + unichar key = 0; + + struct vout_thread_s *p_vout = + (struct vout_thread_s *)_p_vout; + + if( [[o_event characters] length] ) + { + key = [[o_event characters] characterAtIndex: 0]; + } + + switch( key ) + { + case 'f': case 'F': + p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE; + break; + + case 'q': case 'Q': + p_main->p_intf->b_die = 1; + break; + + default: + return( NO ); + break; + } + + return( YES ); +} + +@end + +@implementation Vout_VLCWrapper (Internal) + +- (void)handlePortMessage:(NSPortMessage *)o_msg +{ + NSData *o_req; + struct vout_req_s *p_req; + + o_req = [[o_msg components] lastObject]; + p_req = *((struct vout_req_s **)[o_req bytes]); + + [p_req->o_lock lock]; + + if( p_req->i_type == VOUT_REQ_CREATE_WINDOW ) + { + VLCView *o_view; + + p_req->p_vout->p_sys->o_window = [VLCWindow alloc]; + [p_req->p_vout->p_sys->o_window + setWrapper: self forVout: (void *)p_req->p_vout]; + [p_req->p_vout->p_sys->o_window setReleasedWhenClosed: YES]; + + if( p_req->p_vout->b_fullscreen ) + { + [p_req->p_vout->p_sys->o_window + initWithContentRect: [[NSScreen mainScreen] frame] + styleMask: NSBorderlessWindowMask + backing: NSBackingStoreBuffered + defer: NO screen: [NSScreen mainScreen]]; + + [p_req->p_vout->p_sys->o_window + setLevel: CGShieldingWindowLevel()]; + } + else + { + unsigned int i_stylemask = NSTitledWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask; + + [p_req->p_vout->p_sys->o_window + initWithContentRect: p_req->p_vout->p_sys->s_rect + styleMask: i_stylemask + backing: NSBackingStoreBuffered + defer: NO screen: [NSScreen mainScreen]]; + + if( !p_req->p_vout->p_sys->b_pos_saved ) + { + [p_req->p_vout->p_sys->o_window center]; + } + } + + o_view = [[VLCView alloc] + initWithWrapper: self forVout: (void *)p_req->p_vout]; + [p_req->p_vout->p_sys->o_window setContentView: o_view]; + [o_view autorelease]; + + [o_view lockFocus]; + p_req->p_vout->p_sys->p_qdport = [o_view qdPort]; + [o_view unlockFocus]; + + [p_req->p_vout->p_sys->o_window setTitle: [NSString + stringWithCString: VOUT_TITLE]]; + [p_req->p_vout->p_sys->o_window setAcceptsMouseMovedEvents: YES]; + [p_req->p_vout->p_sys->o_window makeKeyAndOrderFront: nil]; + + p_req->i_result = 1; + } + else if( p_req->i_type == VOUT_REQ_DESTROY_WINDOW ) + { + if( !p_req->p_vout->b_fullscreen ) + { + NSRect s_rect; + + s_rect = [[p_req->p_vout->p_sys->o_window contentView] frame]; + p_req->p_vout->p_sys->s_rect.size = s_rect.size; + + s_rect = [p_req->p_vout->p_sys->o_window frame]; + p_req->p_vout->p_sys->s_rect.origin = s_rect.origin; + + p_req->p_vout->p_sys->b_pos_saved = 1; + } + + p_req->p_vout->p_sys->p_qdport = nil; + [p_req->p_vout->p_sys->o_window close]; + p_req->p_vout->p_sys->o_window = nil; + + p_req->i_result = 1; + } + + [p_req->o_lock unlockWithCondition: 1]; +} + +@end diff --git a/plugins/macosx/vout_vlc_wrapper.h b/plugins/macosx/vout_vlc_wrapper.h new file mode 100644 index 0000000000..8429dced99 --- /dev/null +++ b/plugins/macosx/vout_vlc_wrapper.h @@ -0,0 +1,45 @@ +/***************************************************************************** + * vout_vlc_wrapper.h: MacOS X plugin for vlc + ***************************************************************************** + * Copyright (C) 2001 VideoLAN + * $Id: vout_vlc_wrapper.h,v 1.1 2002/03/19 03:33:52 jlj Exp $ + * + * Authors: Jon Lech Johansen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ + +#define MOUSE_MOVED 0x00000001 +#define MOUSE_NOT_MOVED 0x00000002 +#define MOUSE_LAST_MOVED 0x00000004 +#define MOUSE_NOT_LAST_MOVED 0x00000008 + +@interface Vout_VLCWrapper : NSObject +{ + +} + ++ (Vout_VLCWrapper *)instance; ++ (NSPort *)sendPort; + +- (void)voutDidResize:(void *)_p_vout; +- (void)mouseEvent:(unsigned int)ui_status forVout:(void *)_p_vout; +- (BOOL)keyDown:(NSEvent *)o_event forVout:(void *)_p_vout; + +@end + +@interface Vout_VLCWrapper (Internal) +- (void)handlePortMessage:(NSPortMessage *)o_msg; +@end diff --git a/plugins/macosx/vout_window.c b/plugins/macosx/vout_window.c index 387cc0b7e0..a058ac2192 100644 --- a/plugins/macosx/vout_window.c +++ b/plugins/macosx/vout_window.c @@ -2,7 +2,7 @@ * vout_window.c: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: vout_window.c,v 1.1 2002/02/18 01:34:44 jlj Exp $ + * $Id: vout_window.c,v 1.2 2002/03/19 03:33:52 jlj Exp $ * * Authors: Jon Lech Johansen * @@ -24,27 +24,19 @@ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* ENOMEM */ -#include /* free() */ -#include /* strerror() */ +#import -#include - -#include "video.h" -#include "video_output.h" - -#include "interface.h" - -#include "macosx.h" +#import "vout_window.h" /***************************************************************************** * VLCWindow implementation *****************************************************************************/ @implementation VLCWindow -- (void)setVout:(struct vout_thread_s *)_p_vout +- (void)setWrapper:(Vout_VLCWrapper *)_o_wrapper forVout:(void *)_p_vout { p_vout = _p_vout; + o_wrapper = _o_wrapper; } - (BOOL)canBecomeKeyWindow @@ -55,45 +47,34 @@ - (void)becomeKeyWindow { [super becomeKeyWindow]; - p_vout->p_sys->b_mouse_moved = 0; - p_vout->p_sys->i_time_mouse_last_moved = mdate(); + + [o_wrapper + mouseEvent: (MOUSE_NOT_MOVED | MOUSE_LAST_MOVED) + forVout: p_vout]; } - (void)resignKeyWindow { [super resignKeyWindow]; - p_vout->p_sys->b_mouse_moved = 1; - p_vout->p_sys->i_time_mouse_last_moved = 0; + + [o_wrapper + mouseEvent: (MOUSE_MOVED | MOUSE_NOT_LAST_MOVED) + forVout: p_vout]; } -- (void)keyDown:(NSEvent *)theEvent +- (void)keyDown:(NSEvent *)o_event { - unichar key = 0; - - if( [[theEvent characters] length] ) + if( [o_wrapper keyDown: o_event forVout: p_vout] == NO ) { - key = [[theEvent characters] characterAtIndex: 0]; - } - - switch( key ) - { - case 'f': case 'F': - p_vout->i_changes |= VOUT_FULLSCREEN_CHANGE; - break; - - case 'q': case 'Q': - p_main->p_intf->b_die = 1; - break; - - default: - [super keyDown: theEvent]; - break; + [super keyDown: o_event]; } } -- (void)mouseMoved:(NSEvent *)theEvent +- (void)mouseMoved:(NSEvent *)o_event { - p_vout->p_sys->i_time_mouse_last_moved = mdate(); + [o_wrapper + mouseEvent: MOUSE_LAST_MOVED + forVout: p_vout]; } @end diff --git a/plugins/macosx/vout_window.h b/plugins/macosx/vout_window.h index e41273bb5b..4a12f0477b 100644 --- a/plugins/macosx/vout_window.h +++ b/plugins/macosx/vout_window.h @@ -2,7 +2,7 @@ * vout_window.h: MacOS X plugin for vlc ***************************************************************************** * Copyright (C) 2001 VideoLAN - * $Id: vout_window.h,v 1.1 2002/02/18 01:34:44 jlj Exp $ + * $Id: vout_window.h,v 1.2 2002/03/19 03:33:52 jlj Exp $ * * Authors: Jon Lech Johansen * @@ -21,11 +21,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. *****************************************************************************/ +#import "vout_vlc_wrapper.h" + @interface VLCWindow : NSWindow { - struct vout_thread_s *p_vout; + void *p_vout; + Vout_VLCWrapper *o_wrapper; } -- (void)setVout:(struct vout_thread_s *)_p_vout; +- (void)setWrapper:(Vout_VLCWrapper *)_o_wrapper forVout:(void *)_p_vout; @end