* MacOS X aout now uses AudioConverter for int->float

* Various MacOS X intf improvements and bug fixes
This commit is contained in:
Jon Lech Johansen 2002-03-19 03:33:52 +00:00
parent 939b6ea136
commit 5dcebef960
18 changed files with 751 additions and 545 deletions

4
configure vendored
View File

@ -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"

View File

@ -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"
)])

View File

@ -33,7 +33,7 @@
LANGUAGE = ObjC;
OUTLETS = {o_table = id; };
SUPERCLASS = NSObject;
},
}
);
IBVersion = 1;
}
}

View File

@ -18,6 +18,6 @@
<integer>21</integer>
</array>
<key>IBSystem Version</key>
<string>5P48</string>
<string>5Q45</string>
</dict>
</plist>

View File

@ -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;
}

View File

@ -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

View File

@ -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 <colin@zoy.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
*
* 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 <Carbon/Carbon.h>
#include <CoreAudio/AudioHardware.h>
#include <sys/fcntl.h>
/*
* 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 <AudioToolbox/AudioConverter.h>
/*****************************************************************************
* 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 );
}

View File

@ -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 <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
@ -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

View File

@ -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 <fgp@phlo.org>
*
@ -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;

View File

@ -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 <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
@ -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

View File

@ -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 <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
@ -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;

View File

@ -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 <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
@ -25,36 +25,30 @@
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#import <Cocoa/Cocoa.h>
#include <videolan/vlc.h>
#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

View File

@ -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 <fgp@phlo.org>
* Jon Lech Johansen <jon-vl@nanocrew.net>
@ -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

View File

@ -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 <jon-vl@nanocrew.net>
*
* 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 <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#include <videolan/vlc.h>
#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

View File

@ -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 <jon-vl@nanocrew.net>
*
* 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

View File

@ -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 <jon-vl@nanocrew.net>
*
@ -24,27 +24,19 @@
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h> /* ENOMEM */
#include <stdlib.h> /* free() */
#include <string.h> /* strerror() */
#import <Cocoa/Cocoa.h>
#include <videolan/vlc.h>
#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

View File

@ -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 <jon-vl@nanocrew.net>
*
@ -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