From a7e4ab04d7e714c572767e58b409a48ed46b862f Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 9 Apr 2009 20:04:24 +0000 Subject: Make sure waitop always unlocks the mainloop even if the operation could not be created. Patch by Lennart Poettering [lennart poettering net] git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29157 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_pulse.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'libao2') diff --git a/libao2/ao_pulse.c b/libao2/ao_pulse.c index 2d27c85540..66d28aa281 100644 --- a/libao2/ao_pulse.c +++ b/libao2/ao_pulse.c @@ -102,7 +102,10 @@ static void success_cb(pa_stream *s, int success, void *userdata) { */ static int waitop(pa_operation *op) { pa_operation_state_t state; - if (!op) return 0; + if (!op) { + pa_threaded_mainloop_unlock(mainloop); + return 0; + } state = pa_operation_get_state(op); while (state == PA_OPERATION_RUNNING) { pa_threaded_mainloop_wait(mainloop); -- cgit v1.2.3 From d1c4d6c7ef3625d6b2668a44406db832836d525c Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 9 Apr 2009 20:07:26 +0000 Subject: Also lock the mainloop when doing adjusting the volume for PulseAudio. Patch by Lennart Poettering [lennart poettering net] git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29158 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_pulse.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'libao2') diff --git a/libao2/ao_pulse.c b/libao2/ao_pulse.c index 66d28aa281..83270bbfcf 100644 --- a/libao2/ao_pulse.c +++ b/libao2/ao_pulse.c @@ -392,12 +392,15 @@ static int control(int cmd, void *arg) { volume.values[1] = (pa_volume_t)vol->right*PA_VOLUME_NORM/100; } + pa_threaded_mainloop_lock(mainloop); if (!(o = pa_context_set_sink_input_volume(context, pa_stream_get_index(stream), &volume, NULL, NULL))) { + pa_threaded_mainloop_unlock(mainloop); GENERIC_ERR_MSG(context, "pa_context_set_sink_input_volume() failed"); return CONTROL_ERROR; } /* We don't wait for completion here */ pa_operation_unref(o); + pa_threaded_mainloop_unlock(mainloop); return CONTROL_OK; } -- cgit v1.2.3 From 33645075f14917ed6b233c5c4c29d1e4ed8b4b35 Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 9 Apr 2009 20:10:35 +0000 Subject: Split oversized of "argument" onto a separate line. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29159 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_pulse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'libao2') diff --git a/libao2/ao_pulse.c b/libao2/ao_pulse.c index 83270bbfcf..444b85814d 100644 --- a/libao2/ao_pulse.c +++ b/libao2/ao_pulse.c @@ -393,7 +393,8 @@ static int control(int cmd, void *arg) { } pa_threaded_mainloop_lock(mainloop); - if (!(o = pa_context_set_sink_input_volume(context, pa_stream_get_index(stream), &volume, NULL, NULL))) { + o = pa_context_set_sink_input_volume(context, pa_stream_get_index(stream), &volume, NULL, NULL); + if (!o) { pa_threaded_mainloop_unlock(mainloop); GENERIC_ERR_MSG(context, "pa_context_set_sink_input_volume() failed"); return CONTROL_ERROR; -- cgit v1.2.3 From fe9c8d60b435679cc68022b936a9a036b10ea2dc Mon Sep 17 00:00:00 2001 From: reimar Date: Thu, 9 Apr 2009 20:20:00 +0000 Subject: Disable pause-hack from PulseAudio 0.9.15 on, it should be fixed. Patch Lennart Poettering [lennart poettering net] with documentation update by me. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29160 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_pulse.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'libao2') diff --git a/libao2/ao_pulse.c b/libao2/ao_pulse.c index 444b85814d..b2fdcbb175 100644 --- a/libao2/ao_pulse.c +++ b/libao2/ao_pulse.c @@ -153,11 +153,11 @@ static int init(int rate_hz, int channels, int format, int flags) { } broken_pause = 0; - // not sure which versions are affected, assume 0.9.1* + // not sure which versions are affected, assume 0.9.11* to 0.9.14* // known bad: 0.9.14, 0.9.13 - // known good: 0.9.9, 0.9.10 + // known good: 0.9.9, 0.9.10, 0.9.15 // to test: pause, wait ca. 5 seconds framestep and see if MPlayer hangs somewhen - if (strncmp(version, "0.9.1", 5) == 0 && strncmp(version, "0.9.10", 6) != 0) { + if (strncmp(version, "0.9.1", 5) == 0 && version[5] >= '1' && version[5] <= '4') { mp_msg(MSGT_AO, MSGL_WARN, "[pulse] working around probably broken pause functionality,\n" " see http://www.pulseaudio.org/ticket/440\n"); broken_pause = 1; -- cgit v1.2.3 From 690714883e7b83acdf0185df7498064308fb715c Mon Sep 17 00:00:00 2001 From: reimar Date: Fri, 10 Apr 2009 14:41:18 +0000 Subject: Simplify: use av_fifo_space git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29166 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_jack.c | 4 ++-- libao2/ao_sdl.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'libao2') diff --git a/libao2/ao_jack.c b/libao2/ao_jack.c index 494d44aa19..8ee5550602 100644 --- a/libao2/ao_jack.c +++ b/libao2/ao_jack.c @@ -82,7 +82,7 @@ static AVFifoBuffer *buffer; * If there is not enough room, the buffer is filled up */ static int write_buffer(unsigned char* data, int len) { - int free = BUFFSIZE - av_fifo_size(buffer); + int free = av_fifo_space(buffer); if (len > free) len = free; return av_fifo_generic_write(buffer, data, len, NULL); } @@ -337,7 +337,7 @@ static void audio_resume(void) { } static int get_space(void) { - return BUFFSIZE - av_fifo_size(buffer); + return av_fifo_space(buffer); } /** diff --git a/libao2/ao_sdl.c b/libao2/ao_sdl.c index d5652ccf09..28279abc87 100644 --- a/libao2/ao_sdl.c +++ b/libao2/ao_sdl.c @@ -67,7 +67,7 @@ static unsigned char volume=SDL_MIX_MAXVOLUME; #endif static int write_buffer(unsigned char* data,int len){ - int free = BUFFSIZE - av_fifo_size(buffer); + int free = av_fifo_space(buffer); if (len > free) len = free; return av_fifo_generic_write(buffer, data, len, NULL); } @@ -280,7 +280,7 @@ static void audio_resume(void) // return: how many bytes can be played without blocking static int get_space(void){ - return BUFFSIZE - av_fifo_size(buffer); + return av_fifo_space(buffer); } // plays 'len' bytes of 'data' -- cgit v1.2.3 From 1ba8ea2d34f3bc710e1d303525df7fb47b89ff14 Mon Sep 17 00:00:00 2001 From: reimar Date: Sun, 3 May 2009 20:57:37 +0000 Subject: Use libavutil/fifo.h for macosx ao instead of its own FIFO implementation. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29243 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libao2/ao_macosx.c | 98 ++++++++++++------------------------------------------ 1 file changed, 21 insertions(+), 77 deletions(-) (limited to 'libao2') diff --git a/libao2/ao_macosx.c b/libao2/ao_macosx.c index fb5883b3fb..7589e296d9 100644 --- a/libao2/ao_macosx.c +++ b/libao2/ao_macosx.c @@ -52,6 +52,7 @@ #include "audio_out_internal.h" #include "libaf/af_format.h" #include "osdep/timer.h" +#include "libavutil/fifo.h" static const ao_info_t info = { @@ -91,87 +92,35 @@ typedef struct ao_macosx_s int paused; /* Ring-buffer */ - /* does not need explicit synchronization, but needs to allocate - * (num_chunks + 1) * chunk_size memory to store num_chunks * chunk_size - * data */ - unsigned char *buffer; - unsigned int buffer_len; ///< must always be (num_chunks + 1) * chunk_size + AVFifoBuffer *buffer; + unsigned int buffer_len; ///< must always be num_chunks * chunk_size unsigned int num_chunks; unsigned int chunk_size; - - unsigned int buf_read_pos; - unsigned int buf_write_pos; } ao_macosx_t; static ao_macosx_t *ao = NULL; -/** - * \brief return number of free bytes in the buffer - * may only be called by mplayer's thread - * \return minimum number of free bytes in buffer, value may change between - * two immediately following calls, and the real number of free bytes - * might actually be larger! - */ -static int buf_free(void) { - int free = ao->buf_read_pos - ao->buf_write_pos - ao->chunk_size; - if (free < 0) free += ao->buffer_len; - return free; -} - -/** - * \brief return number of buffered bytes - * may only be called by playback thread - * \return minimum number of buffered bytes, value may change between - * two immediately following calls, and the real number of buffered bytes - * might actually be larger! - */ -static int buf_used(void) { - int used = ao->buf_write_pos - ao->buf_read_pos; - if (used < 0) used += ao->buffer_len; - return used; -} - /** * \brief add data to ringbuffer */ static int write_buffer(unsigned char* data, int len){ - int first_len = ao->buffer_len - ao->buf_write_pos; - int free = buf_free(); + int free = ao->buffer_len - av_fifo_size(ao->buffer); if (len > free) len = free; - if (first_len > len) first_len = len; - // till end of buffer - memcpy (&ao->buffer[ao->buf_write_pos], data, first_len); - if (len > first_len) { // we have to wrap around - // remaining part from beginning of buffer - memcpy (ao->buffer, &data[first_len], len - first_len); - } - ao->buf_write_pos = (ao->buf_write_pos + len) % ao->buffer_len; - return len; + return av_fifo_generic_write(ao->buffer, data, len, NULL); } /** * \brief remove data from ringbuffer */ static int read_buffer(unsigned char* data,int len){ - int first_len = ao->buffer_len - ao->buf_read_pos; - int buffered = buf_used(); + int buffered = av_fifo_size(ao->buffer); if (len > buffered) len = buffered; - if (first_len > len) first_len = len; - // till end of buffer - if (data) { - memcpy (data, &ao->buffer[ao->buf_read_pos], first_len); - if (len > first_len) { // we have to wrap around - // remaining part from beginning of buffer - memcpy (&data[first_len], ao->buffer, len - first_len); - } - } - ao->buf_read_pos = (ao->buf_read_pos + len) % ao->buffer_len; - return len; + return av_fifo_generic_read(ao->buffer, data, len, NULL); } OSStatus theRenderProc(void *inRefCon, AudioUnitRenderActionFlags *inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData) { -int amt=buf_used(); +int amt=av_fifo_size(ao->buffer); int req=(inNumFrames)*ao->packetSize; if(amt>req) @@ -493,8 +442,8 @@ int b_alive; ao_data.buffersize = ao_data.bps; ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; - ao->buffer_len = (ao->num_chunks + 1) * ao->chunk_size; - ao->buffer = calloc(ao->num_chunks + 1, ao->chunk_size); + ao->buffer_len = ao->num_chunks * ao->chunk_size; + ao->buffer = av_fifo_alloc(ao->buffer_len); ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); @@ -515,7 +464,7 @@ err_out2: err_out1: CloseComponent(ao->theOutputUnit); err_out: - free(ao->buffer); + av_fifo_free(ao->buffer); free(ao); ao = NULL; return CONTROL_FALSE; @@ -737,8 +686,8 @@ static int OpenSPDIF() ao_data.buffersize = ao_data.bps; ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; - ao->buffer_len = (ao->num_chunks + 1) * ao->chunk_size; - ao->buffer = calloc(ao->num_chunks + 1, ao->chunk_size); + ao->buffer_len = ao->num_chunks * ao->chunk_size; + ao->buffer = av_fifo_alloc(ao->buffer_len); ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); @@ -782,7 +731,7 @@ err_out: ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", (char *)&err); } - free(ao->buffer); + av_fifo_free(ao->buffer); free(ao); ao = NULL; return CONTROL_FALSE; @@ -981,7 +930,7 @@ static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, const AudioTimeStamp * inOutputTime, void * threadGlobals ) { - int amt = buf_used(); + int amt = av_fifo_size(ao->buffer); int req = outOutputData->mBuffers[ao->i_stream_index].mDataByteSize; if (amt > req) @@ -1030,27 +979,22 @@ static int play(void* output_samples,int num_bytes,int flags) static void reset(void) { audio_pause(); - /* reset ring-buffer state */ - ao->buf_read_pos=0; - ao->buf_write_pos=0; - - return; + av_fifo_reset(ao->buffer); } /* return available space */ static int get_space(void) { - return buf_free(); + return ao->buffer_len - av_fifo_size(ao->buffer); } /* return delay until audio is played */ static float get_delay(void) { - int buffered = ao->buffer_len - ao->chunk_size - buf_free(); // could be less // inaccurate, should also contain the data buffered e.g. by the OS - return (float)(buffered)/(float)ao_data.bps; + return (float)av_fifo_size(ao->buffer)/(float)ao_data.bps; } @@ -1061,8 +1005,8 @@ static void uninit(int immed) UInt32 i_param_size = 0; if (!immed) { - long long timeleft=(1000000LL*buf_used())/ao_data.bps; - ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%d usec)\n", buf_used(), ao_data.bps, (int)timeleft); + long long timeleft=(1000000LL*av_fifo_size(ao->buffer))/ao_data.bps; + ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%d usec)\n", av_fifo_size(ao->buffer), ao_data.bps, (int)timeleft); usec_sleep((int)timeleft); } @@ -1115,7 +1059,7 @@ static void uninit(int immed) } } - free(ao->buffer); + av_fifo_free(ao->buffer); free(ao); ao = NULL; } -- cgit v1.2.3 From e3ec5b1fd377254e19685ddcce0988efda8bffbf Mon Sep 17 00:00:00 2001 From: diego Date: Mon, 4 May 2009 14:53:47 +0000 Subject: Rename macosx audio output driver to coreaudio. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29251 b3059339-0415-0410-9bf9-f77b7e298cf2 --- AUTHORS | 2 +- DOCS/man/en/mplayer.1 | 2 +- DOCS/tech/MAINTAINERS | 2 +- Makefile | 2 +- configure | 4 +- libao2/ao_coreaudio.c | 1149 +++++++++++++++++++++++++++++++++++++++++++++++++ libao2/ao_macosx.c | 1149 ------------------------------------------------- libao2/audio_out.c | 4 +- 8 files changed, 1157 insertions(+), 1157 deletions(-) create mode 100644 libao2/ao_coreaudio.c delete mode 100644 libao2/ao_macosx.c (limited to 'libao2') diff --git a/AUTHORS b/AUTHORS index 99f52fa8de..ff606dee4b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -168,7 +168,7 @@ Bunkus, Moritz (Mosu) Christiansen, Dan Villiom Podlaski (danchr) * timer-darwin.c - * ao_macosx + * CoreAudio audio output driver for Mac OS X * build system cleanups for Darwin Clagg, Jeff (snacky) diff --git a/DOCS/man/en/mplayer.1 b/DOCS/man/en/mplayer.1 index f5b1f4999e..68d8ee317e 100644 --- a/DOCS/man/en/mplayer.1 +++ b/DOCS/man/en/mplayer.1 @@ -2786,7 +2786,7 @@ Note that this seems unreliable and will spam stdout with server messages. audio output through NAS . .TP -.B macosx (Mac OS X only) +.B coreaudio (Mac OS X only) native Mac OS X audio output driver . .TP diff --git a/DOCS/tech/MAINTAINERS b/DOCS/tech/MAINTAINERS index 87f4fbfdc0..198d2711ea 100644 --- a/DOCS/tech/MAINTAINERS +++ b/DOCS/tech/MAINTAINERS @@ -204,12 +204,12 @@ libao2 drivers: * ao_alsa5.c - None * ao_alsa.c - Clemens Ladisch * ao_arts.c - None + * ao_coreaudio.c - None * ao_dsound.c - None * ao_dxr2.c - None * ao_esd.c - None * ao_ivtv.c - Benjamin Zores * ao_jack.c - Reimar Döffinger - * ao_macosx.c - None * ao_mpegpes.c - None * ao_nas.c - Tobias Diedrich * ao_null.c - None diff --git a/Makefile b/Makefile index 662d7807a0..c56aa88e86 100644 --- a/Makefile +++ b/Makefile @@ -531,7 +531,7 @@ SRCS_MPLAYER-$(APPLE_REMOTE) += input/ar.c SRCS_MPLAYER-$(ARTS) += libao2/ao_arts.c SRCS_MPLAYER-$(BL) += libvo/vo_bl.c SRCS_MPLAYER-$(CACA) += libvo/vo_caca.c -SRCS_MPLAYER-$(COREAUDIO) += libao2/ao_macosx.c +SRCS_MPLAYER-$(COREAUDIO) += libao2/ao_coreaudio.c SRCS_MPLAYER-$(COREVIDEO) += libvo/vo_macosx.m SRCS_MPLAYER-$(DART) += libao2/ao_dart.c SRCS_MPLAYER-$(DFBMGA) += libvo/vo_dfbmga.c diff --git a/configure b/configure index 8b15401349..488783e81b 100755 --- a/configure +++ b/configure @@ -3815,10 +3815,10 @@ fi if test "$_coreaudio" = yes ; then extra_ldflags="$extra_ldflags -framework CoreAudio -framework AudioUnit -framework AudioToolbox" def_coreaudio='#define CONFIG_COREAUDIO 1' - _aomodules="macosx $_aomodules" + _aomodules="coreaudio $_aomodules" else def_coreaudio='#undef CONFIG_COREAUDIO' - _noaomodules="macosx $_noaomodules" + _noaomodules="coreaudio $_noaomodules" fi echores $_coreaudio diff --git a/libao2/ao_coreaudio.c b/libao2/ao_coreaudio.c new file mode 100644 index 0000000000..18a2fd7cf1 --- /dev/null +++ b/libao2/ao_coreaudio.c @@ -0,0 +1,1149 @@ +/* + * CoreAudio audio output driver for Mac OS X + * + * original copyright (C) Timothy J. Wood - Aug 2000 + * ported to MPlayer libao2 by Dan Christiansen + * + * The S/PDIF part of the code is based on the auhal audio output + * module from VideoLAN: + * Copyright (c) 2006 Derk-Jan Hartman + * + * This file is part of MPlayer. + * + * MPlayer 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. + * + * MPlayer 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 + * along with MPlayer; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * The MacOS X CoreAudio framework doesn't mesh as simply as some + * simpler frameworks do. This is due to the fact that CoreAudio pulls + * audio samples rather than having them pushed at it (which is nice + * when you are wanting to do good buffering of audio). + * + * AC-3 and MPEG audio passthrough is possible, but has never been tested + * due to lack of a soundcard that supports it. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "mp_msg.h" + +#include "audio_out.h" +#include "audio_out_internal.h" +#include "libaf/af_format.h" +#include "osdep/timer.h" +#include "libavutil/fifo.h" + +static const ao_info_t info = + { + "Darwin/Mac OS X native audio output", + "coreaudio", + "Timothy J. Wood & Dan Christiansen & Chris Roccati", + "" + }; + +LIBAO_EXTERN(coreaudio) + +/* Prefix for all mp_msg() calls */ +#define ao_msg(a, b, c...) mp_msg(a, b, "AO: [coreaudio] " c) + +typedef struct ao_coreaudio_s +{ + AudioDeviceID i_selected_dev; /* Keeps DeviceID of the selected device. */ + int b_supports_digital; /* Does the currently selected device support digital mode? */ + int b_digital; /* Are we running in digital mode? */ + int b_muted; /* Are we muted in digital mode? */ + + /* AudioUnit */ + AudioUnit theOutputUnit; + + /* CoreAudio SPDIF mode specific */ + pid_t i_hog_pid; /* Keeps the pid of our hog status. */ + AudioStreamID i_stream_id; /* The StreamID that has a cac3 streamformat */ + int i_stream_index; /* The index of i_stream_id in an AudioBufferList */ + AudioStreamBasicDescription stream_format;/* The format we changed the stream to */ + AudioStreamBasicDescription sfmt_revert; /* The original format of the stream */ + int b_revert; /* Whether we need to revert the stream format */ + int b_changed_mixing; /* Whether we need to set the mixing mode back */ + int b_stream_format_changed; /* Flag for main thread to reset stream's format to digital and reset buffer */ + + /* Original common part */ + int packetSize; + int paused; + + /* Ring-buffer */ + AVFifoBuffer *buffer; + unsigned int buffer_len; ///< must always be num_chunks * chunk_size + unsigned int num_chunks; + unsigned int chunk_size; +} ao_coreaudio_t; + +static ao_coreaudio_t *ao = NULL; + +/** + * \brief add data to ringbuffer + */ +static int write_buffer(unsigned char* data, int len){ + int free = ao->buffer_len - av_fifo_size(ao->buffer); + if (len > free) len = free; + return av_fifo_generic_write(ao->buffer, data, len, NULL); +} + +/** + * \brief remove data from ringbuffer + */ +static int read_buffer(unsigned char* data,int len){ + int buffered = av_fifo_size(ao->buffer); + if (len > buffered) len = buffered; + return av_fifo_generic_read(ao->buffer, data, len, NULL); +} + +OSStatus theRenderProc(void *inRefCon, AudioUnitRenderActionFlags *inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData) +{ +int amt=av_fifo_size(ao->buffer); +int req=(inNumFrames)*ao->packetSize; + + if(amt>req) + amt=req; + + if(amt) + read_buffer((unsigned char *)ioData->mBuffers[0].mData, amt); + else audio_pause(); + ioData->mBuffers[0].mDataByteSize = amt; + + return noErr; +} + +static int control(int cmd,void *arg){ +ao_control_vol_t *control_vol; +OSStatus err; +Float32 vol; + switch (cmd) { + case AOCONTROL_GET_VOLUME: + control_vol = (ao_control_vol_t*)arg; + if (ao->b_digital) { + // Digital output has no volume adjust. + return CONTROL_FALSE; + } + err = AudioUnitGetParameter(ao->theOutputUnit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, &vol); + + if(err==0) { + // printf("GET VOL=%f\n", vol); + control_vol->left=control_vol->right=vol*100.0/4.0; + return CONTROL_TRUE; + } + else { + ao_msg(MSGT_AO, MSGL_WARN, "could not get HAL output volume: [%4.4s]\n", (char *)&err); + return CONTROL_FALSE; + } + + case AOCONTROL_SET_VOLUME: + control_vol = (ao_control_vol_t*)arg; + + if (ao->b_digital) { + // Digital output can not set volume. Here we have to return true + // to make mixer forget it. Else mixer will add a soft filter, + // that's not we expected and the filter not support ac3 stream + // will cause mplayer die. + + // Although not support set volume, but at least we support mute. + // MPlayer set mute by set volume to zero, we handle it. + if (control_vol->left == 0 && control_vol->right == 0) + ao->b_muted = 1; + else + ao->b_muted = 0; + return CONTROL_TRUE; + } + + vol=(control_vol->left+control_vol->right)*4.0/200.0; + err = AudioUnitSetParameter(ao->theOutputUnit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, vol, 0); + if(err==0) { + // printf("SET VOL=%f\n", vol); + return CONTROL_TRUE; + } + else { + ao_msg(MSGT_AO, MSGL_WARN, "could not set HAL output volume: [%4.4s]\n", (char *)&err); + return CONTROL_FALSE; + } + /* Everything is currently unimplemented */ + default: + return CONTROL_FALSE; + } + +} + + +static void print_format(int lev, const char* str, const AudioStreamBasicDescription *f){ + uint32_t flags=(uint32_t) f->mFormatFlags; + ao_msg(MSGT_AO,lev, "%s %7.1fHz %lubit [%c%c%c%c][%lu][%lu][%lu][%lu][%lu] %s %s %s%s%s%s\n", + str, f->mSampleRate, f->mBitsPerChannel, + (int)(f->mFormatID & 0xff000000) >> 24, + (int)(f->mFormatID & 0x00ff0000) >> 16, + (int)(f->mFormatID & 0x0000ff00) >> 8, + (int)(f->mFormatID & 0x000000ff) >> 0, + f->mFormatFlags, f->mBytesPerPacket, + f->mFramesPerPacket, f->mBytesPerFrame, + f->mChannelsPerFrame, + (flags&kAudioFormatFlagIsFloat) ? "float" : "int", + (flags&kAudioFormatFlagIsBigEndian) ? "BE" : "LE", + (flags&kAudioFormatFlagIsSignedInteger) ? "S" : "U", + (flags&kAudioFormatFlagIsPacked) ? " packed" : "", + (flags&kAudioFormatFlagIsAlignedHigh) ? " aligned" : "", + (flags&kAudioFormatFlagIsNonInterleaved) ? " ni" : "" ); +} + + +static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ); +static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ); +static int OpenSPDIF(); +static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ); +static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, + const AudioTimeStamp * inNow, + const void * inInputData, + const AudioTimeStamp * inInputTime, + AudioBufferList * outOutputData, + const AudioTimeStamp * inOutputTime, + void * threadGlobals ); +static OSStatus StreamListener( AudioStreamID inStream, + UInt32 inChannel, + AudioDevicePropertyID inPropertyID, + void * inClientData ); +static OSStatus DeviceListener( AudioDeviceID inDevice, + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData ); + +static int init(int rate,int channels,int format,int flags) +{ +AudioStreamBasicDescription inDesc; +ComponentDescription desc; +Component comp; +AURenderCallbackStruct renderCallback; +OSStatus err; +UInt32 size, maxFrames, i_param_size; +char *psz_name; +AudioDeviceID devid_def = 0; +int b_alive; + + ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags); + + ao = calloc(1, sizeof(ao_coreaudio_t)); + + ao->i_selected_dev = 0; + ao->b_supports_digital = 0; + ao->b_digital = 0; + ao->b_muted = 0; + ao->b_stream_format_changed = 0; + ao->i_hog_pid = -1; + ao->i_stream_id = 0; + ao->i_stream_index = -1; + ao->b_revert = 0; + ao->b_changed_mixing = 0; + + /* Probe whether device support S/PDIF stream output if input is AC3 stream. */ + if ((format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3) + { + /* Find the ID of the default Device. */ + i_param_size = sizeof(AudioDeviceID); + err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, + &i_param_size, &devid_def); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device: [%4.4s]\n", (char *)&err); + goto err_out; + } + + /* Retrieve the length of the device name. */ + i_param_size = 0; + err = AudioDeviceGetPropertyInfo(devid_def, 0, 0, + kAudioDevicePropertyDeviceName, + &i_param_size, NULL); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name length: [%4.4s]\n", (char *)&err); + goto err_out; + } + + /* Retrieve the name of the device. */ + psz_name = (char *)malloc(i_param_size); + err = AudioDeviceGetProperty(devid_def, 0, 0, + kAudioDevicePropertyDeviceName, + &i_param_size, psz_name); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name: [%4.4s]\n", (char *)&err); + free( psz_name); + goto err_out; + } + + ao_msg(MSGT_AO,MSGL_V, "got default audio output device ID: %#lx Name: %s\n", devid_def, psz_name ); + + if (AudioDeviceSupportsDigital(devid_def)) + { + ao->b_supports_digital = 1; + ao->i_selected_dev = devid_def; + } + ao_msg(MSGT_AO,MSGL_V, "probe default audio output device whether support digital s/pdif output:%d\n", ao->b_supports_digital ); + + free( psz_name); + } + + // Build Description for the input format + inDesc.mSampleRate=rate; + inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM; + inDesc.mChannelsPerFrame=channels; + switch(format&AF_FORMAT_BITS_MASK){ + case AF_FORMAT_8BIT: + inDesc.mBitsPerChannel=8; + break; + case AF_FORMAT_16BIT: + inDesc.mBitsPerChannel=16; + break; + case AF_FORMAT_24BIT: + inDesc.mBitsPerChannel=24; + break; + case AF_FORMAT_32BIT: + inDesc.mBitsPerChannel=32; + break; + default: + ao_msg(MSGT_AO, MSGL_WARN, "Unsupported format (0x%08x)\n", format); + goto err_out; + } + + if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F) { + // float + inDesc.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked; + } + else if((format&AF_FORMAT_SIGN_MASK)==AF_FORMAT_SI) { + // signed int + inDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; + } + else { + // unsigned int + inDesc.mFormatFlags = kAudioFormatFlagIsPacked; + } + if ((format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3) { + // Currently ac3 input (comes from hwac3) is always in native byte-order. +#ifdef WORDS_BIGENDIAN + inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian; +#endif + } + else if ((format & AF_FORMAT_END_MASK) == AF_FORMAT_BE) + inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian; + + inDesc.mFramesPerPacket = 1; + ao->packetSize = inDesc.mBytesPerPacket = inDesc.mBytesPerFrame = inDesc.mFramesPerPacket*channels*(inDesc.mBitsPerChannel/8); + print_format(MSGL_V, "source:",&inDesc); + + if (ao->b_supports_digital) + { + b_alive = 1; + i_param_size = sizeof(b_alive); + err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, + kAudioDevicePropertyDeviceIsAlive, + &i_param_size, &b_alive); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is alive: [%4.4s]\n", (char *)&err); + if (!b_alive) + ao_msg(MSGT_AO, MSGL_WARN, "device is not alive\n" ); + /* S/PDIF output need device in HogMode. */ + i_param_size = sizeof(ao->i_hog_pid); + err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, + kAudioDevicePropertyHogMode, + &i_param_size, &ao->i_hog_pid); + + if (err != noErr) + { + /* This is not a fatal error. Some drivers simply don't support this property. */ + ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is hogged: [%4.4s]\n", + (char *)&err); + ao->i_hog_pid = -1; + } + + if (ao->i_hog_pid != -1 && ao->i_hog_pid != getpid()) + { + ao_msg(MSGT_AO, MSGL_WARN, "Selected audio device is exclusively in use by another program.\n" ); + goto err_out; + } + ao->stream_format = inDesc; + return OpenSPDIF(); + } + + /* original analog output code */ + desc.componentType = kAudioUnitType_Output; + desc.componentSubType = kAudioUnitSubType_DefaultOutput; + desc.componentManufacturer = kAudioUnitManufacturer_Apple; + desc.componentFlags = 0; + desc.componentFlagsMask = 0; + + comp = FindNextComponent(NULL, &desc); //Finds an component that meets the desc spec's + if (comp == NULL) { + ao_msg(MSGT_AO, MSGL_WARN, "Unable to find Output Unit component\n"); + goto err_out; + } + + err = OpenAComponent(comp, &(ao->theOutputUnit)); //gains access to the services provided by the component + if (err) { + ao_msg(MSGT_AO, MSGL_WARN, "Unable to open Output Unit component: [%4.4s]\n", (char *)&err); + goto err_out; + } + + // Initialize AudioUnit + err = AudioUnitInitialize(ao->theOutputUnit); + if (err) { + ao_msg(MSGT_AO, MSGL_WARN, "Unable to initialize Output Unit component: [%4.4s]\n", (char *)&err); + goto err_out1; + } + + size = sizeof(AudioStreamBasicDescription); + err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &inDesc, size); + + if (err) { + ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the input format: [%4.4s]\n", (char *)&err); + goto err_out2; + } + + size = sizeof(UInt32); + err = AudioUnitGetProperty(ao->theOutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Input, 0, &maxFrames, &size); + + if (err) + { + ao_msg(MSGT_AO,MSGL_WARN, "AudioUnitGetProperty returned [%4.4s] when getting kAudioDevicePropertyBufferSize\n", (char *)&err); + goto err_out2; + } + + ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame; + + ao_data.samplerate = inDesc.mSampleRate; + ao_data.channels = inDesc.mChannelsPerFrame; + ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame; + ao_data.outburst = ao->chunk_size; + ao_data.buffersize = ao_data.bps; + + ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; + ao->buffer_len = ao->num_chunks * ao->chunk_size; + ao->buffer = av_fifo_alloc(ao->buffer_len); + + ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); + + renderCallback.inputProc = theRenderProc; + renderCallback.inputProcRefCon = 0; + err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct)); + if (err) { + ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the render callback: [%4.4s]\n", (char *)&err); + goto err_out2; + } + + reset(); + + return CONTROL_OK; + +err_out2: + AudioUnitUninitialize(ao->theOutputUnit); +err_out1: + CloseComponent(ao->theOutputUnit); +err_out: + av_fifo_free(ao->buffer); + free(ao); + ao = NULL; + return CONTROL_FALSE; +} + +/***************************************************************************** + * Setup a encoded digital stream (SPDIF) + *****************************************************************************/ +static int OpenSPDIF() +{ + OSStatus err = noErr; + UInt32 i_param_size, b_mix = 0; + Boolean b_writeable = 0; + AudioStreamID *p_streams = NULL; + int i, i_streams = 0; + + /* Start doing the SPDIF setup process. */ + ao->b_digital = 1; + + /* Hog the device. */ + i_param_size = sizeof(ao->i_hog_pid); + ao->i_hog_pid = getpid() ; + + err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, + kAudioDevicePropertyHogMode, i_param_size, &ao->i_hog_pid); + + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "failed to set hogmode: [%4.4s]\n", (char *)&err); + ao->i_hog_pid = -1; + goto err_out; + } + + /* Set mixable to false if we are allowed to. */ + err = AudioDeviceGetPropertyInfo(ao->i_selected_dev, 0, FALSE, + kAudioDevicePropertySupportsMixing, + &i_param_size, &b_writeable); + err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, + kAudioDevicePropertySupportsMixing, + &i_param_size, &b_mix); + if (err != noErr && b_writeable) + { + b_mix = 0; + err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, + kAudioDevicePropertySupportsMixing, + i_param_size, &b_mix); + ao->b_changed_mixing = 1; + } + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); + goto err_out; + } + + /* Get a list of all the streams on this device. */ + err = AudioDeviceGetPropertyInfo(ao->i_selected_dev, 0, FALSE, + kAudioDevicePropertyStreams, + &i_param_size, NULL); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams: [%4.4s]\n", (char *)&err); + goto err_out; + } + + i_streams = i_param_size / sizeof(AudioStreamID); + p_streams = (AudioStreamID *)malloc(i_param_size); + if (p_streams == NULL) + { + ao_msg(MSGT_AO, MSGL_WARN, "out of memory\n" ); + goto err_out; + } + + err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, + kAudioDevicePropertyStreams, + &i_param_size, p_streams); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams: [%4.4s]\n", (char *)&err); + if (p_streams) free(p_streams); + goto err_out; + } + + ao_msg(MSGT_AO, MSGL_V, "current device stream number: %d\n", i_streams); + + for (i = 0; i < i_streams && ao->i_stream_index < 0; ++i) + { + /* Find a stream with a cac3 stream. */ + AudioStreamBasicDescription *p_format_list = NULL; + int i_formats = 0, j = 0, b_digital = 0; + + /* Retrieve all the stream formats supported by each output stream. */ + err = AudioStreamGetPropertyInfo(p_streams[i], 0, + kAudioStreamPropertyPhysicalFormats, + &i_param_size, NULL); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streamformats: [%4.4s]\n", (char *)&err); + continue; + } + + i_formats = i_param_size / sizeof(AudioStreamBasicDescription); + p_format_list = (AudioStreamBasicDescription *)malloc(i_param_size); + if (p_format_list == NULL) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not malloc the memory\n" ); + continue; + } + + err = AudioStreamGetProperty(p_streams[i], 0, + kAudioStreamPropertyPhysicalFormats, + &i_param_size, p_format_list); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not get the list of streamformats: [%4.4s]\n", (char *)&err); + if (p_format_list) free(p_format_list); + continue; + } + + /* Check if one of the supported formats is a digital format. */ + for (j = 0; j < i_formats; ++j) + { + if (p_format_list[j].mFormatID == 'IAC3' || + p_format_list[j].mFormatID == kAudioFormat60958AC3) + { + b_digital = 1; + break; + } + } + + if (b_digital) + { + /* If this stream supports a digital (cac3) format, then set it. */ + int i_requested_rate_format = -1; + int i_current_rate_format = -1; + int i_backup_rate_format = -1; + + ao->i_stream_id = p_streams[i]; + ao->i_stream_index = i; + + if (ao->b_revert == 0) + { + /* Retrieve the original format of this stream first if not done so already. */ + i_param_size = sizeof(ao->sfmt_revert); + err = AudioStreamGetProperty(ao->i_stream_id, 0, + kAudioStreamPropertyPhysicalFormat, + &i_param_size, + &ao->sfmt_revert); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not retrieve the original streamformat: [%4.4s]\n", (char *)&err); + if (p_format_list) free(p_format_list); + continue; + } + ao->b_revert = 1; + } + + for (j = 0; j < i_formats; ++j) + if (p_format_list[j].mFormatID == 'IAC3' || + p_format_list[j].mFormatID == kAudioFormat60958AC3) + { + if (p_format_list[j].mSampleRate == ao->stream_format.mSampleRate) + { + i_requested_rate_format = j; + break; + } + if (p_format_list[j].mSampleRate == ao->sfmt_revert.mSampleRate) + i_current_rate_format = j; + else if (i_backup_rate_format < 0 || p_format_list[j].mSampleRate > p_format_list[i_backup_rate_format].mSampleRate) + i_backup_rate_format = j; + } + + if (i_requested_rate_format >= 0) /* We prefer to output at the samplerate of the original audio. */ + ao->stream_format = p_format_list[i_requested_rate_format]; + else if (i_current_rate_format >= 0) /* If not possible, we will try to use the current samplerate of the device. */ + ao->stream_format = p_format_list[i_current_rate_format]; + else ao->stream_format = p_format_list[i_backup_rate_format]; /* And if we have to, any digital format will be just fine (highest rate possible). */ + } + if (p_format_list) free(p_format_list); + } + if (p_streams) free(p_streams); + + if (ao->i_stream_index < 0) + { + ao_msg(MSGT_AO, MSGL_WARN, "can not find any digital output stream format when OpenSPDIF().\n"); + goto err_out; + } + + print_format(MSGL_V, "original stream format:", &ao->sfmt_revert); + + if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) + goto err_out; + + err = AudioDeviceAddPropertyListener(ao->i_selected_dev, + kAudioPropertyWildcardChannel, + 0, + kAudioDevicePropertyDeviceHasChanged, + DeviceListener, + NULL); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddPropertyListener for kAudioDevicePropertyDeviceHasChanged failed: [%4.4s]\n", (char *)&err); + + + /* FIXME: If output stream is not native byte-order, we need change endian somewhere. */ + /* Although there's no such case reported. */ +#ifdef WORDS_BIGENDIAN + if (!(ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian)) +#else + if (ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian) +#endif + ao_msg(MSGT_AO, MSGL_WARN, "output stream has a no-native byte-order, digital output may failed.\n"); + + /* For ac3/dts, just use packet size 6144 bytes as chunk size. */ + ao->chunk_size = ao->stream_format.mBytesPerPacket; + + ao_data.samplerate = ao->stream_format.mSampleRate; + ao_data.channels = ao->stream_format.mChannelsPerFrame; + ao_data.bps = ao_data.samplerate * (ao->stream_format.mBytesPerPacket/ao->stream_format.mFramesPerPacket); + ao_data.outburst = ao->chunk_size; + ao_data.buffersize = ao_data.bps; + + ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; + ao->buffer_len = ao->num_chunks * ao->chunk_size; + ao->buffer = av_fifo_alloc(ao->buffer_len); + + ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); + + + /* Add IOProc callback. */ + err = AudioDeviceAddIOProc(ao->i_selected_dev, + (AudioDeviceIOProc)RenderCallbackSPDIF, + (void *)ao); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddIOProc failed: [%4.4s]\n", (char *)&err); + goto err_out1; + } + + reset(); + + return CONTROL_TRUE; + +err_out1: + if (ao->b_revert) + AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); +err_out: + if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) + { + int b_mix = 1; + err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, + kAudioDevicePropertySupportsMixing, + i_param_size, &b_mix); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", + (char *)&err); + } + if (ao->i_hog_pid == getpid()) + { + ao->i_hog_pid = -1; + i_param_size = sizeof(ao->i_hog_pid); + err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, + kAudioDevicePropertyHogMode, + i_param_size, &ao->i_hog_pid); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", + (char *)&err); + } + av_fifo_free(ao->buffer); + free(ao); + ao = NULL; + return CONTROL_FALSE; +} + +/***************************************************************************** + * AudioDeviceSupportsDigital: Check i_dev_id for digital stream support. + *****************************************************************************/ +static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ) +{ + OSStatus err = noErr; + UInt32 i_param_size = 0; + AudioStreamID *p_streams = NULL; + int i = 0, i_streams = 0; + int b_return = CONTROL_FALSE; + + /* Retrieve all the output streams. */ + err = AudioDeviceGetPropertyInfo(i_dev_id, 0, FALSE, + kAudioDevicePropertyStreams, + &i_param_size, NULL); + if (err != noErr) + { + ao_msg(MSGT_AO,MSGL_V, "could not get number of streams: [%4.4s]\n", (char *)&err); + return CONTROL_FALSE; + } + + i_streams = i_param_size / sizeof(AudioStreamID); + p_streams = (AudioStreamID *)malloc(i_param_size); + if (p_streams == NULL) + { + ao_msg(MSGT_AO,MSGL_V, "out of memory\n"); + return CONTROL_FALSE; + } + + err = AudioDeviceGetProperty(i_dev_id, 0, FALSE, + kAudioDevicePropertyStreams, + &i_param_size, p_streams); + + if (err != noErr) + { + ao_msg(MSGT_AO,MSGL_V, "could not get number of streams: [%4.4s]\n", (char *)&err); + free(p_streams); + return CONTROL_FALSE; + } + + for (i = 0; i < i_streams; ++i) + { + if (AudioStreamSupportsDigital(p_streams[i])) + b_return = CONTROL_OK; + } + + free(p_streams); + return b_return; +} + +/***************************************************************************** + * AudioStreamSupportsDigital: Check i_stream_id for digital stream support. + *****************************************************************************/ +static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ) +{ + OSStatus err = noErr; + UInt32 i_param_size; + AudioStreamBasicDescription *p_format_list = NULL; + int i, i_formats, b_return = CONTROL_FALSE; + + /* Retrieve all the stream formats supported by each output stream. */ + err = AudioStreamGetPropertyInfo(i_stream_id, 0, + kAudioStreamPropertyPhysicalFormats, + &i_param_size, NULL); + if (err != noErr) + { + ao_msg(MSGT_AO,MSGL_V, "could not get number of streamformats: [%4.4s]\n", (char *)&err); + return CONTROL_FALSE; + } + + i_formats = i_param_size / sizeof(AudioStreamBasicDescription); + p_format_list = (AudioStreamBasicDescription *)malloc(i_param_size); + if (p_format_list == NULL) + { + ao_msg(MSGT_AO,MSGL_V, "could not malloc the memory\n" ); + return CONTROL_FALSE; + } + + err = AudioStreamGetProperty(i_stream_id, 0, + kAudioStreamPropertyPhysicalFormats, + &i_param_size, p_format_list); + if (err != noErr) + { + ao_msg(MSGT_AO,MSGL_V, "could not get the list of streamformats: [%4.4s]\n", (char *)&err); + free(p_format_list); + return CONTROL_FALSE; + } + + for (i = 0; i < i_formats; ++i) + { + print_format(MSGL_V, "supported format:", &p_format_list[i]); + + if (p_format_list[i].mFormatID == 'IAC3' || + p_format_list[i].mFormatID == kAudioFormat60958AC3) + b_return = CONTROL_OK; + } + + free(p_format_list); + return b_return; +} + +/***************************************************************************** + * AudioStreamChangeFormat: Change i_stream_id to change_format + *****************************************************************************/ +static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ) +{ + OSStatus err = noErr; + UInt32 i_param_size = 0; + int i; + + static volatile int stream_format_changed; + stream_format_changed = 0; + + print_format(MSGL_V, "setting stream format:", &change_format); + + /* Install the callback. */ + err = AudioStreamAddPropertyListener(i_stream_id, 0, + kAudioStreamPropertyPhysicalFormat, + StreamListener, + (void *)&stream_format_changed); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamAddPropertyListener failed: [%4.4s]\n", (char *)&err); + return CONTROL_FALSE; + } + + /* Change the format. */ + err = AudioStreamSetProperty(i_stream_id, 0, 0, + kAudioStreamPropertyPhysicalFormat, + sizeof(AudioStreamBasicDescription), + &change_format); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "could not set the stream format: [%4.4s]\n", (char *)&err); + return CONTROL_FALSE; + } + + /* The AudioStreamSetProperty is not only asynchronious, + * it is also not Atomic, in its behaviour. + * Therefore we check 5 times before we really give up. + * FIXME: failing isn't actually implemented yet. */ + for (i = 0; i < 5; ++i) + { + AudioStreamBasicDescription actual_format; + int j; + for (j = 0; !stream_format_changed && j < 50; ++j) + usec_sleep(10000); + if (stream_format_changed) + stream_format_changed = 0; + else + ao_msg(MSGT_AO, MSGL_V, "reached timeout\n" ); + + i_param_size = sizeof(AudioStreamBasicDescription); + err = AudioStreamGetProperty(i_stream_id, 0, + kAudioStreamPropertyPhysicalFormat, + &i_param_size, + &actual_format); + + print_format(MSGL_V, "actual format in use:", &actual_format); + if (actual_format.mSampleRate == change_format.mSampleRate && + actual_format.mFormatID == change_format.mFormatID && + actual_format.mFramesPerPacket == change_format.mFramesPerPacket) + { + /* The right format is now active. */ + break; + } + /* We need to check again. */ + } + + /* Removing the property listener. */ + err = AudioStreamRemovePropertyListener(i_stream_id, 0, + kAudioStreamPropertyPhysicalFormat, + StreamListener); + if (err != noErr) + { + ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamRemovePropertyListener failed: [%4.4s]\n", (char *)&err); + return CONTROL_FALSE; + } + + return CONTROL_TRUE; +} + +/***************************************************************************** + * RenderCallbackSPDIF: callback for SPDIF audio output + *****************************************************************************/ +static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, + const AudioTimeStamp * inNow, + const void * inInputData, + const AudioTimeStamp * inInputTime, + AudioBufferList * outOutputData, + const AudioTimeStamp * inOutputTime, + void * threadGlobals ) +{ + int amt = av_fifo_size(ao->buffer); + int req = outOutputData->mBuffers[ao->i_stream_index].mDataByteSize; + + if (amt > req) + amt = req; + if (amt) + read_buffer(ao->b_muted ? NULL : (unsigned char *)outOutputData->mBuffers[ao->i_stream_index].mData, amt); + + return noErr; +} + + +static int play(void* output_samples,int num_bytes,int flags) +{ + int wrote, b_digital; + + // Check whether we need to reset the digital output stream. + if (ao->b_digital && ao->b_stream_format_changed) + { + ao->b_stream_format_changed = 0; + b_digital = AudioStreamSupportsDigital(ao->i_stream_id); + if (b_digital) + { + /* Current stream support digital format output, let's set it. */ + ao_msg(MSGT_AO, MSGL_V, "detected current stream support digital, try to restore digital output...\n"); + + if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) + { + ao_msg(MSGT_AO, MSGL_WARN, "restore digital output failed.\n"); + } + else + { + ao_msg(MSGT_AO, MSGL_WARN, "restore digital output succeed.\n"); + reset(); + } + } + else + ao_msg(MSGT_AO, MSGL_V, "detected current stream do not support digital.\n"); + } + + wrote=write_buffer(output_samples, num_bytes); + audio_resume(); + return wrote; +} + +/* set variables and buffer to initial state */ +static void reset(void) +{ + audio_pause(); + av_fifo_reset(ao->buffer); +} + + +/* return available space */ +static int get_space(void) +{ + return ao->buffer_len - av_fifo_size(ao->buffer); +} + + +/* return delay until audio is played */ +static float get_delay(void) +{ + // inaccurate, should also contain the data buffered e.g. by the OS + return (float)av_fifo_size(ao->buffer)/(float)ao_data.bps; +} + + +/* unload plugin and deregister from coreaudio */ +static void uninit(int immed) +{ + OSStatus err = noErr; + UInt32 i_param_size = 0; + + if (!immed) { + long long timeleft=(1000000LL*av_fifo_size(ao->buffer))/ao_data.bps; + ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%d usec)\n", av_fifo_size(ao->buffer), ao_data.bps, (int)timeleft); + usec_sleep((int)timeleft); + } + + if (!ao->b_digital) { + AudioOutputUnitStop(ao->theOutputUnit); + AudioUnitUninitialize(ao->theOutputUnit); + CloseComponent(ao->theOutputUnit); + } + else { + /* Stop device. */ + err = AudioDeviceStop(ao->i_selected_dev, + (AudioDeviceIOProc)RenderCallbackSPDIF); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); + + /* Remove IOProc callback. */ + err = AudioDeviceRemoveIOProc(ao->i_selected_dev, + (AudioDeviceIOProc)RenderCallbackSPDIF); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceRemoveIOProc failed: [%4.4s]\n", (char *)&err); + + if (ao->b_revert) + AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); + + if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) + { + int b_mix; + Boolean b_writeable; + /* Revert mixable to true if we are allowed to. */ + err = AudioDeviceGetPropertyInfo(ao->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, + &i_param_size, &b_writeable); + err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, + &i_param_size, &b_mix); + if (err != noErr && b_writeable) + { + b_mix = 1; + err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, + kAudioDevicePropertySupportsMixing, i_param_size, &b_mix); + } + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); + } + if (ao->i_hog_pid == getpid()) + { + ao->i_hog_pid = -1; + i_param_size = sizeof(ao->i_hog_pid); + err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, + kAudioDevicePropertyHogMode, i_param_size, &ao->i_hog_pid); + if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", (char *)&err); + } + } + + av_fifo_free(ao->buffer); + free(ao); + ao = NULL; +} + + +/* stop playing, keep buffers (for pause) */ +static void audio_pause(void) +{ + OSErr err=noErr; + + /* Stop callback. */ + if (!ao->b_digital) + { + err=AudioOutputUnitStop(ao->theOutputUnit); + if (err != noErr) + ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStop returned [%4.4s]\n", (char *)&err); + } + else + { + err = AudioDeviceStop(ao->i_selected_dev, (AudioDeviceIOProc)RenderCallbackSPDIF); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); + } + ao->paused = 1; +} + + +/* resume playing, after audio_pause() */ +static void audio_resume(void) +{ + OSErr err=noErr; + + if (!ao->paused) + return; + + /* Start callback. */ + if (!ao->b_digital) + { + err = AudioOutputUnitStart(ao->theOutputUnit); + if (err != noErr) + ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStart returned [%4.4s]\n", (char *)&err); + } + else + { + err = AudioDeviceStart(ao->i_selected_dev, (AudioDeviceIOProc)RenderCallbackSPDIF); + if (err != noErr) + ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStart failed: [%4.4s]\n", (char *)&err); + } + ao->paused = 0; +} + +/***************************************************************************** + * StreamListener + *****************************************************************************/ +static OSStatus StreamListener( AudioStreamID inStream, + UInt32 inChannel, + AudioDevicePropertyID inPropertyID, + void * inClientData ) +{ + switch (inPropertyID) + { + case kAudioStreamPropertyPhysicalFormat: + ao_msg(MSGT_AO, MSGL_V, "got notify kAudioStreamPropertyPhysicalFormat changed.\n"); + if (inClientData) + *(volatile int *)inClientData = 1; + default: + break; + } + return noErr; +} + +static OSStatus DeviceListener( AudioDeviceID inDevice, + UInt32 inChannel, + Boolean isInput, + AudioDevicePropertyID inPropertyID, + void* inClientData ) +{ + switch (inPropertyID) + { + case kAudioDevicePropertyDeviceHasChanged: + ao_msg(MSGT_AO, MSGL_WARN, "got notify kAudioDevicePropertyDeviceHasChanged.\n"); + ao->b_stream_format_changed = 1; + default: + break; + } + return noErr; +} diff --git a/libao2/ao_macosx.c b/libao2/ao_macosx.c deleted file mode 100644 index 7589e296d9..0000000000 --- a/libao2/ao_macosx.c +++ /dev/null @@ -1,1149 +0,0 @@ -/* - * Mac OS X audio output driver - * - * original copyright (C) Timothy J. Wood - Aug 2000 - * ported to MPlayer libao2 by Dan Christiansen - * - * The S/PDIF part of the code is based on the auhal audio output - * module from VideoLAN: - * Copyright (c) 2006 Derk-Jan Hartman - * - * This file is part of MPlayer. - * - * MPlayer 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. - * - * MPlayer 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 - * along with MPlayer; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * The MacOS X CoreAudio framework doesn't mesh as simply as some - * simpler frameworks do. This is due to the fact that CoreAudio pulls - * audio samples rather than having them pushed at it (which is nice - * when you are wanting to do good buffering of audio). - * - * AC-3 and MPEG audio passthrough is possible, but has never been tested - * due to lack of a soundcard that supports it. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "mp_msg.h" - -#include "audio_out.h" -#include "audio_out_internal.h" -#include "libaf/af_format.h" -#include "osdep/timer.h" -#include "libavutil/fifo.h" - -static const ao_info_t info = - { - "Darwin/Mac OS X native audio output", - "macosx", - "Timothy J. Wood & Dan Christiansen & Chris Roccati", - "" - }; - -LIBAO_EXTERN(macosx) - -/* Prefix for all mp_msg() calls */ -#define ao_msg(a, b, c...) mp_msg(a, b, "AO: [macosx] " c) - -typedef struct ao_macosx_s -{ - AudioDeviceID i_selected_dev; /* Keeps DeviceID of the selected device. */ - int b_supports_digital; /* Does the currently selected device support digital mode? */ - int b_digital; /* Are we running in digital mode? */ - int b_muted; /* Are we muted in digital mode? */ - - /* AudioUnit */ - AudioUnit theOutputUnit; - - /* CoreAudio SPDIF mode specific */ - pid_t i_hog_pid; /* Keeps the pid of our hog status. */ - AudioStreamID i_stream_id; /* The StreamID that has a cac3 streamformat */ - int i_stream_index; /* The index of i_stream_id in an AudioBufferList */ - AudioStreamBasicDescription stream_format;/* The format we changed the stream to */ - AudioStreamBasicDescription sfmt_revert; /* The original format of the stream */ - int b_revert; /* Whether we need to revert the stream format */ - int b_changed_mixing; /* Whether we need to set the mixing mode back */ - int b_stream_format_changed; /* Flag for main thread to reset stream's format to digital and reset buffer */ - - /* Original common part */ - int packetSize; - int paused; - - /* Ring-buffer */ - AVFifoBuffer *buffer; - unsigned int buffer_len; ///< must always be num_chunks * chunk_size - unsigned int num_chunks; - unsigned int chunk_size; -} ao_macosx_t; - -static ao_macosx_t *ao = NULL; - -/** - * \brief add data to ringbuffer - */ -static int write_buffer(unsigned char* data, int len){ - int free = ao->buffer_len - av_fifo_size(ao->buffer); - if (len > free) len = free; - return av_fifo_generic_write(ao->buffer, data, len, NULL); -} - -/** - * \brief remove data from ringbuffer - */ -static int read_buffer(unsigned char* data,int len){ - int buffered = av_fifo_size(ao->buffer); - if (len > buffered) len = buffered; - return av_fifo_generic_read(ao->buffer, data, len, NULL); -} - -OSStatus theRenderProc(void *inRefCon, AudioUnitRenderActionFlags *inActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData) -{ -int amt=av_fifo_size(ao->buffer); -int req=(inNumFrames)*ao->packetSize; - - if(amt>req) - amt=req; - - if(amt) - read_buffer((unsigned char *)ioData->mBuffers[0].mData, amt); - else audio_pause(); - ioData->mBuffers[0].mDataByteSize = amt; - - return noErr; -} - -static int control(int cmd,void *arg){ -ao_control_vol_t *control_vol; -OSStatus err; -Float32 vol; - switch (cmd) { - case AOCONTROL_GET_VOLUME: - control_vol = (ao_control_vol_t*)arg; - if (ao->b_digital) { - // Digital output has no volume adjust. - return CONTROL_FALSE; - } - err = AudioUnitGetParameter(ao->theOutputUnit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, &vol); - - if(err==0) { - // printf("GET VOL=%f\n", vol); - control_vol->left=control_vol->right=vol*100.0/4.0; - return CONTROL_TRUE; - } - else { - ao_msg(MSGT_AO, MSGL_WARN, "could not get HAL output volume: [%4.4s]\n", (char *)&err); - return CONTROL_FALSE; - } - - case AOCONTROL_SET_VOLUME: - control_vol = (ao_control_vol_t*)arg; - - if (ao->b_digital) { - // Digital output can not set volume. Here we have to return true - // to make mixer forget it. Else mixer will add a soft filter, - // that's not we expected and the filter not support ac3 stream - // will cause mplayer die. - - // Although not support set volume, but at least we support mute. - // MPlayer set mute by set volume to zero, we handle it. - if (control_vol->left == 0 && control_vol->right == 0) - ao->b_muted = 1; - else - ao->b_muted = 0; - return CONTROL_TRUE; - } - - vol=(control_vol->left+control_vol->right)*4.0/200.0; - err = AudioUnitSetParameter(ao->theOutputUnit, kHALOutputParam_Volume, kAudioUnitScope_Global, 0, vol, 0); - if(err==0) { - // printf("SET VOL=%f\n", vol); - return CONTROL_TRUE; - } - else { - ao_msg(MSGT_AO, MSGL_WARN, "could not set HAL output volume: [%4.4s]\n", (char *)&err); - return CONTROL_FALSE; - } - /* Everything is currently unimplemented */ - default: - return CONTROL_FALSE; - } - -} - - -static void print_format(int lev, const char* str, const AudioStreamBasicDescription *f){ - uint32_t flags=(uint32_t) f->mFormatFlags; - ao_msg(MSGT_AO,lev, "%s %7.1fHz %lubit [%c%c%c%c][%lu][%lu][%lu][%lu][%lu] %s %s %s%s%s%s\n", - str, f->mSampleRate, f->mBitsPerChannel, - (int)(f->mFormatID & 0xff000000) >> 24, - (int)(f->mFormatID & 0x00ff0000) >> 16, - (int)(f->mFormatID & 0x0000ff00) >> 8, - (int)(f->mFormatID & 0x000000ff) >> 0, - f->mFormatFlags, f->mBytesPerPacket, - f->mFramesPerPacket, f->mBytesPerFrame, - f->mChannelsPerFrame, - (flags&kAudioFormatFlagIsFloat) ? "float" : "int", - (flags&kAudioFormatFlagIsBigEndian) ? "BE" : "LE", - (flags&kAudioFormatFlagIsSignedInteger) ? "S" : "U", - (flags&kAudioFormatFlagIsPacked) ? " packed" : "", - (flags&kAudioFormatFlagIsAlignedHigh) ? " aligned" : "", - (flags&kAudioFormatFlagIsNonInterleaved) ? " ni" : "" ); -} - - -static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ); -static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ); -static int OpenSPDIF(); -static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ); -static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, - const AudioTimeStamp * inNow, - const void * inInputData, - const AudioTimeStamp * inInputTime, - AudioBufferList * outOutputData, - const AudioTimeStamp * inOutputTime, - void * threadGlobals ); -static OSStatus StreamListener( AudioStreamID inStream, - UInt32 inChannel, - AudioDevicePropertyID inPropertyID, - void * inClientData ); -static OSStatus DeviceListener( AudioDeviceID inDevice, - UInt32 inChannel, - Boolean isInput, - AudioDevicePropertyID inPropertyID, - void* inClientData ); - -static int init(int rate,int channels,int format,int flags) -{ -AudioStreamBasicDescription inDesc; -ComponentDescription desc; -Component comp; -AURenderCallbackStruct renderCallback; -OSStatus err; -UInt32 size, maxFrames, i_param_size; -char *psz_name; -AudioDeviceID devid_def = 0; -int b_alive; - - ao_msg(MSGT_AO,MSGL_V, "init([%dHz][%dch][%s][%d])\n", rate, channels, af_fmt2str_short(format), flags); - - ao = calloc(1, sizeof(ao_macosx_t)); - - ao->i_selected_dev = 0; - ao->b_supports_digital = 0; - ao->b_digital = 0; - ao->b_muted = 0; - ao->b_stream_format_changed = 0; - ao->i_hog_pid = -1; - ao->i_stream_id = 0; - ao->i_stream_index = -1; - ao->b_revert = 0; - ao->b_changed_mixing = 0; - - /* Probe whether device support S/PDIF stream output if input is AC3 stream. */ - if ((format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3) - { - /* Find the ID of the default Device. */ - i_param_size = sizeof(AudioDeviceID); - err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, - &i_param_size, &devid_def); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device: [%4.4s]\n", (char *)&err); - goto err_out; - } - - /* Retrieve the length of the device name. */ - i_param_size = 0; - err = AudioDeviceGetPropertyInfo(devid_def, 0, 0, - kAudioDevicePropertyDeviceName, - &i_param_size, NULL); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name length: [%4.4s]\n", (char *)&err); - goto err_out; - } - - /* Retrieve the name of the device. */ - psz_name = (char *)malloc(i_param_size); - err = AudioDeviceGetProperty(devid_def, 0, 0, - kAudioDevicePropertyDeviceName, - &i_param_size, psz_name); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not get default audio device name: [%4.4s]\n", (char *)&err); - free( psz_name); - goto err_out; - } - - ao_msg(MSGT_AO,MSGL_V, "got default audio output device ID: %#lx Name: %s\n", devid_def, psz_name ); - - if (AudioDeviceSupportsDigital(devid_def)) - { - ao->b_supports_digital = 1; - ao->i_selected_dev = devid_def; - } - ao_msg(MSGT_AO,MSGL_V, "probe default audio output device whether support digital s/pdif output:%d\n", ao->b_supports_digital ); - - free( psz_name); - } - - // Build Description for the input format - inDesc.mSampleRate=rate; - inDesc.mFormatID=ao->b_supports_digital ? kAudioFormat60958AC3 : kAudioFormatLinearPCM; - inDesc.mChannelsPerFrame=channels; - switch(format&AF_FORMAT_BITS_MASK){ - case AF_FORMAT_8BIT: - inDesc.mBitsPerChannel=8; - break; - case AF_FORMAT_16BIT: - inDesc.mBitsPerChannel=16; - break; - case AF_FORMAT_24BIT: - inDesc.mBitsPerChannel=24; - break; - case AF_FORMAT_32BIT: - inDesc.mBitsPerChannel=32; - break; - default: - ao_msg(MSGT_AO, MSGL_WARN, "Unsupported format (0x%08x)\n", format); - goto err_out; - } - - if((format&AF_FORMAT_POINT_MASK)==AF_FORMAT_F) { - // float - inDesc.mFormatFlags = kAudioFormatFlagIsFloat|kAudioFormatFlagIsPacked; - } - else if((format&AF_FORMAT_SIGN_MASK)==AF_FORMAT_SI) { - // signed int - inDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger|kAudioFormatFlagIsPacked; - } - else { - // unsigned int - inDesc.mFormatFlags = kAudioFormatFlagIsPacked; - } - if ((format & AF_FORMAT_SPECIAL_MASK) == AF_FORMAT_AC3) { - // Currently ac3 input (comes from hwac3) is always in native byte-order. -#ifdef WORDS_BIGENDIAN - inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian; -#endif - } - else if ((format & AF_FORMAT_END_MASK) == AF_FORMAT_BE) - inDesc.mFormatFlags |= kAudioFormatFlagIsBigEndian; - - inDesc.mFramesPerPacket = 1; - ao->packetSize = inDesc.mBytesPerPacket = inDesc.mBytesPerFrame = inDesc.mFramesPerPacket*channels*(inDesc.mBitsPerChannel/8); - print_format(MSGL_V, "source:",&inDesc); - - if (ao->b_supports_digital) - { - b_alive = 1; - i_param_size = sizeof(b_alive); - err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, - kAudioDevicePropertyDeviceIsAlive, - &i_param_size, &b_alive); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is alive: [%4.4s]\n", (char *)&err); - if (!b_alive) - ao_msg(MSGT_AO, MSGL_WARN, "device is not alive\n" ); - /* S/PDIF output need device in HogMode. */ - i_param_size = sizeof(ao->i_hog_pid); - err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, - kAudioDevicePropertyHogMode, - &i_param_size, &ao->i_hog_pid); - - if (err != noErr) - { - /* This is not a fatal error. Some drivers simply don't support this property. */ - ao_msg(MSGT_AO, MSGL_WARN, "could not check whether device is hogged: [%4.4s]\n", - (char *)&err); - ao->i_hog_pid = -1; - } - - if (ao->i_hog_pid != -1 && ao->i_hog_pid != getpid()) - { - ao_msg(MSGT_AO, MSGL_WARN, "Selected audio device is exclusively in use by another program.\n" ); - goto err_out; - } - ao->stream_format = inDesc; - return OpenSPDIF(); - } - - /* original analog output code */ - desc.componentType = kAudioUnitType_Output; - desc.componentSubType = kAudioUnitSubType_DefaultOutput; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - - comp = FindNextComponent(NULL, &desc); //Finds an component that meets the desc spec's - if (comp == NULL) { - ao_msg(MSGT_AO, MSGL_WARN, "Unable to find Output Unit component\n"); - goto err_out; - } - - err = OpenAComponent(comp, &(ao->theOutputUnit)); //gains access to the services provided by the component - if (err) { - ao_msg(MSGT_AO, MSGL_WARN, "Unable to open Output Unit component: [%4.4s]\n", (char *)&err); - goto err_out; - } - - // Initialize AudioUnit - err = AudioUnitInitialize(ao->theOutputUnit); - if (err) { - ao_msg(MSGT_AO, MSGL_WARN, "Unable to initialize Output Unit component: [%4.4s]\n", (char *)&err); - goto err_out1; - } - - size = sizeof(AudioStreamBasicDescription); - err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &inDesc, size); - - if (err) { - ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the input format: [%4.4s]\n", (char *)&err); - goto err_out2; - } - - size = sizeof(UInt32); - err = AudioUnitGetProperty(ao->theOutputUnit, kAudioDevicePropertyBufferSize, kAudioUnitScope_Input, 0, &maxFrames, &size); - - if (err) - { - ao_msg(MSGT_AO,MSGL_WARN, "AudioUnitGetProperty returned [%4.4s] when getting kAudioDevicePropertyBufferSize\n", (char *)&err); - goto err_out2; - } - - ao->chunk_size = maxFrames;//*inDesc.mBytesPerFrame; - - ao_data.samplerate = inDesc.mSampleRate; - ao_data.channels = inDesc.mChannelsPerFrame; - ao_data.bps = ao_data.samplerate * inDesc.mBytesPerFrame; - ao_data.outburst = ao->chunk_size; - ao_data.buffersize = ao_data.bps; - - ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; - ao->buffer_len = ao->num_chunks * ao->chunk_size; - ao->buffer = av_fifo_alloc(ao->buffer_len); - - ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); - - renderCallback.inputProc = theRenderProc; - renderCallback.inputProcRefCon = 0; - err = AudioUnitSetProperty(ao->theOutputUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &renderCallback, sizeof(AURenderCallbackStruct)); - if (err) { - ao_msg(MSGT_AO, MSGL_WARN, "Unable to set the render callback: [%4.4s]\n", (char *)&err); - goto err_out2; - } - - reset(); - - return CONTROL_OK; - -err_out2: - AudioUnitUninitialize(ao->theOutputUnit); -err_out1: - CloseComponent(ao->theOutputUnit); -err_out: - av_fifo_free(ao->buffer); - free(ao); - ao = NULL; - return CONTROL_FALSE; -} - -/***************************************************************************** - * Setup a encoded digital stream (SPDIF) - *****************************************************************************/ -static int OpenSPDIF() -{ - OSStatus err = noErr; - UInt32 i_param_size, b_mix = 0; - Boolean b_writeable = 0; - AudioStreamID *p_streams = NULL; - int i, i_streams = 0; - - /* Start doing the SPDIF setup process. */ - ao->b_digital = 1; - - /* Hog the device. */ - i_param_size = sizeof(ao->i_hog_pid); - ao->i_hog_pid = getpid() ; - - err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertyHogMode, i_param_size, &ao->i_hog_pid); - - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "failed to set hogmode: [%4.4s]\n", (char *)&err); - ao->i_hog_pid = -1; - goto err_out; - } - - /* Set mixable to false if we are allowed to. */ - err = AudioDeviceGetPropertyInfo(ao->i_selected_dev, 0, FALSE, - kAudioDevicePropertySupportsMixing, - &i_param_size, &b_writeable); - err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, - kAudioDevicePropertySupportsMixing, - &i_param_size, &b_mix); - if (err != noErr && b_writeable) - { - b_mix = 0; - err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertySupportsMixing, - i_param_size, &b_mix); - ao->b_changed_mixing = 1; - } - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); - goto err_out; - } - - /* Get a list of all the streams on this device. */ - err = AudioDeviceGetPropertyInfo(ao->i_selected_dev, 0, FALSE, - kAudioDevicePropertyStreams, - &i_param_size, NULL); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams: [%4.4s]\n", (char *)&err); - goto err_out; - } - - i_streams = i_param_size / sizeof(AudioStreamID); - p_streams = (AudioStreamID *)malloc(i_param_size); - if (p_streams == NULL) - { - ao_msg(MSGT_AO, MSGL_WARN, "out of memory\n" ); - goto err_out; - } - - err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, - kAudioDevicePropertyStreams, - &i_param_size, p_streams); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streams: [%4.4s]\n", (char *)&err); - if (p_streams) free(p_streams); - goto err_out; - } - - ao_msg(MSGT_AO, MSGL_V, "current device stream number: %d\n", i_streams); - - for (i = 0; i < i_streams && ao->i_stream_index < 0; ++i) - { - /* Find a stream with a cac3 stream. */ - AudioStreamBasicDescription *p_format_list = NULL; - int i_formats = 0, j = 0, b_digital = 0; - - /* Retrieve all the stream formats supported by each output stream. */ - err = AudioStreamGetPropertyInfo(p_streams[i], 0, - kAudioStreamPropertyPhysicalFormats, - &i_param_size, NULL); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not get number of streamformats: [%4.4s]\n", (char *)&err); - continue; - } - - i_formats = i_param_size / sizeof(AudioStreamBasicDescription); - p_format_list = (AudioStreamBasicDescription *)malloc(i_param_size); - if (p_format_list == NULL) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not malloc the memory\n" ); - continue; - } - - err = AudioStreamGetProperty(p_streams[i], 0, - kAudioStreamPropertyPhysicalFormats, - &i_param_size, p_format_list); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not get the list of streamformats: [%4.4s]\n", (char *)&err); - if (p_format_list) free(p_format_list); - continue; - } - - /* Check if one of the supported formats is a digital format. */ - for (j = 0; j < i_formats; ++j) - { - if (p_format_list[j].mFormatID == 'IAC3' || - p_format_list[j].mFormatID == kAudioFormat60958AC3) - { - b_digital = 1; - break; - } - } - - if (b_digital) - { - /* If this stream supports a digital (cac3) format, then set it. */ - int i_requested_rate_format = -1; - int i_current_rate_format = -1; - int i_backup_rate_format = -1; - - ao->i_stream_id = p_streams[i]; - ao->i_stream_index = i; - - if (ao->b_revert == 0) - { - /* Retrieve the original format of this stream first if not done so already. */ - i_param_size = sizeof(ao->sfmt_revert); - err = AudioStreamGetProperty(ao->i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - &i_param_size, - &ao->sfmt_revert); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not retrieve the original streamformat: [%4.4s]\n", (char *)&err); - if (p_format_list) free(p_format_list); - continue; - } - ao->b_revert = 1; - } - - for (j = 0; j < i_formats; ++j) - if (p_format_list[j].mFormatID == 'IAC3' || - p_format_list[j].mFormatID == kAudioFormat60958AC3) - { - if (p_format_list[j].mSampleRate == ao->stream_format.mSampleRate) - { - i_requested_rate_format = j; - break; - } - if (p_format_list[j].mSampleRate == ao->sfmt_revert.mSampleRate) - i_current_rate_format = j; - else if (i_backup_rate_format < 0 || p_format_list[j].mSampleRate > p_format_list[i_backup_rate_format].mSampleRate) - i_backup_rate_format = j; - } - - if (i_requested_rate_format >= 0) /* We prefer to output at the samplerate of the original audio. */ - ao->stream_format = p_format_list[i_requested_rate_format]; - else if (i_current_rate_format >= 0) /* If not possible, we will try to use the current samplerate of the device. */ - ao->stream_format = p_format_list[i_current_rate_format]; - else ao->stream_format = p_format_list[i_backup_rate_format]; /* And if we have to, any digital format will be just fine (highest rate possible). */ - } - if (p_format_list) free(p_format_list); - } - if (p_streams) free(p_streams); - - if (ao->i_stream_index < 0) - { - ao_msg(MSGT_AO, MSGL_WARN, "can not find any digital output stream format when OpenSPDIF().\n"); - goto err_out; - } - - print_format(MSGL_V, "original stream format:", &ao->sfmt_revert); - - if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) - goto err_out; - - err = AudioDeviceAddPropertyListener(ao->i_selected_dev, - kAudioPropertyWildcardChannel, - 0, - kAudioDevicePropertyDeviceHasChanged, - DeviceListener, - NULL); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddPropertyListener for kAudioDevicePropertyDeviceHasChanged failed: [%4.4s]\n", (char *)&err); - - - /* FIXME: If output stream is not native byte-order, we need change endian somewhere. */ - /* Although there's no such case reported. */ -#ifdef WORDS_BIGENDIAN - if (!(ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian)) -#else - if (ao->stream_format.mFormatFlags & kAudioFormatFlagIsBigEndian) -#endif - ao_msg(MSGT_AO, MSGL_WARN, "output stream has a no-native byte-order, digital output may failed.\n"); - - /* For ac3/dts, just use packet size 6144 bytes as chunk size. */ - ao->chunk_size = ao->stream_format.mBytesPerPacket; - - ao_data.samplerate = ao->stream_format.mSampleRate; - ao_data.channels = ao->stream_format.mChannelsPerFrame; - ao_data.bps = ao_data.samplerate * (ao->stream_format.mBytesPerPacket/ao->stream_format.mFramesPerPacket); - ao_data.outburst = ao->chunk_size; - ao_data.buffersize = ao_data.bps; - - ao->num_chunks = (ao_data.bps+ao->chunk_size-1)/ao->chunk_size; - ao->buffer_len = ao->num_chunks * ao->chunk_size; - ao->buffer = av_fifo_alloc(ao->buffer_len); - - ao_msg(MSGT_AO,MSGL_V, "using %5d chunks of %d bytes (buffer len %d bytes)\n", (int)ao->num_chunks, (int)ao->chunk_size, (int)ao->buffer_len); - - - /* Add IOProc callback. */ - err = AudioDeviceAddIOProc(ao->i_selected_dev, - (AudioDeviceIOProc)RenderCallbackSPDIF, - (void *)ao); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceAddIOProc failed: [%4.4s]\n", (char *)&err); - goto err_out1; - } - - reset(); - - return CONTROL_TRUE; - -err_out1: - if (ao->b_revert) - AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); -err_out: - if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) - { - int b_mix = 1; - err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertySupportsMixing, - i_param_size, &b_mix); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", - (char *)&err); - } - if (ao->i_hog_pid == getpid()) - { - ao->i_hog_pid = -1; - i_param_size = sizeof(ao->i_hog_pid); - err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertyHogMode, - i_param_size, &ao->i_hog_pid); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", - (char *)&err); - } - av_fifo_free(ao->buffer); - free(ao); - ao = NULL; - return CONTROL_FALSE; -} - -/***************************************************************************** - * AudioDeviceSupportsDigital: Check i_dev_id for digital stream support. - *****************************************************************************/ -static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ) -{ - OSStatus err = noErr; - UInt32 i_param_size = 0; - AudioStreamID *p_streams = NULL; - int i = 0, i_streams = 0; - int b_return = CONTROL_FALSE; - - /* Retrieve all the output streams. */ - err = AudioDeviceGetPropertyInfo(i_dev_id, 0, FALSE, - kAudioDevicePropertyStreams, - &i_param_size, NULL); - if (err != noErr) - { - ao_msg(MSGT_AO,MSGL_V, "could not get number of streams: [%4.4s]\n", (char *)&err); - return CONTROL_FALSE; - } - - i_streams = i_param_size / sizeof(AudioStreamID); - p_streams = (AudioStreamID *)malloc(i_param_size); - if (p_streams == NULL) - { - ao_msg(MSGT_AO,MSGL_V, "out of memory\n"); - return CONTROL_FALSE; - } - - err = AudioDeviceGetProperty(i_dev_id, 0, FALSE, - kAudioDevicePropertyStreams, - &i_param_size, p_streams); - - if (err != noErr) - { - ao_msg(MSGT_AO,MSGL_V, "could not get number of streams: [%4.4s]\n", (char *)&err); - free(p_streams); - return CONTROL_FALSE; - } - - for (i = 0; i < i_streams; ++i) - { - if (AudioStreamSupportsDigital(p_streams[i])) - b_return = CONTROL_OK; - } - - free(p_streams); - return b_return; -} - -/***************************************************************************** - * AudioStreamSupportsDigital: Check i_stream_id for digital stream support. - *****************************************************************************/ -static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ) -{ - OSStatus err = noErr; - UInt32 i_param_size; - AudioStreamBasicDescription *p_format_list = NULL; - int i, i_formats, b_return = CONTROL_FALSE; - - /* Retrieve all the stream formats supported by each output stream. */ - err = AudioStreamGetPropertyInfo(i_stream_id, 0, - kAudioStreamPropertyPhysicalFormats, - &i_param_size, NULL); - if (err != noErr) - { - ao_msg(MSGT_AO,MSGL_V, "could not get number of streamformats: [%4.4s]\n", (char *)&err); - return CONTROL_FALSE; - } - - i_formats = i_param_size / sizeof(AudioStreamBasicDescription); - p_format_list = (AudioStreamBasicDescription *)malloc(i_param_size); - if (p_format_list == NULL) - { - ao_msg(MSGT_AO,MSGL_V, "could not malloc the memory\n" ); - return CONTROL_FALSE; - } - - err = AudioStreamGetProperty(i_stream_id, 0, - kAudioStreamPropertyPhysicalFormats, - &i_param_size, p_format_list); - if (err != noErr) - { - ao_msg(MSGT_AO,MSGL_V, "could not get the list of streamformats: [%4.4s]\n", (char *)&err); - free(p_format_list); - return CONTROL_FALSE; - } - - for (i = 0; i < i_formats; ++i) - { - print_format(MSGL_V, "supported format:", &p_format_list[i]); - - if (p_format_list[i].mFormatID == 'IAC3' || - p_format_list[i].mFormatID == kAudioFormat60958AC3) - b_return = CONTROL_OK; - } - - free(p_format_list); - return b_return; -} - -/***************************************************************************** - * AudioStreamChangeFormat: Change i_stream_id to change_format - *****************************************************************************/ -static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ) -{ - OSStatus err = noErr; - UInt32 i_param_size = 0; - int i; - - static volatile int stream_format_changed; - stream_format_changed = 0; - - print_format(MSGL_V, "setting stream format:", &change_format); - - /* Install the callback. */ - err = AudioStreamAddPropertyListener(i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - StreamListener, - (void *)&stream_format_changed); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamAddPropertyListener failed: [%4.4s]\n", (char *)&err); - return CONTROL_FALSE; - } - - /* Change the format. */ - err = AudioStreamSetProperty(i_stream_id, 0, 0, - kAudioStreamPropertyPhysicalFormat, - sizeof(AudioStreamBasicDescription), - &change_format); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "could not set the stream format: [%4.4s]\n", (char *)&err); - return CONTROL_FALSE; - } - - /* The AudioStreamSetProperty is not only asynchronious, - * it is also not Atomic, in its behaviour. - * Therefore we check 5 times before we really give up. - * FIXME: failing isn't actually implemented yet. */ - for (i = 0; i < 5; ++i) - { - AudioStreamBasicDescription actual_format; - int j; - for (j = 0; !stream_format_changed && j < 50; ++j) - usec_sleep(10000); - if (stream_format_changed) - stream_format_changed = 0; - else - ao_msg(MSGT_AO, MSGL_V, "reached timeout\n" ); - - i_param_size = sizeof(AudioStreamBasicDescription); - err = AudioStreamGetProperty(i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - &i_param_size, - &actual_format); - - print_format(MSGL_V, "actual format in use:", &actual_format); - if (actual_format.mSampleRate == change_format.mSampleRate && - actual_format.mFormatID == change_format.mFormatID && - actual_format.mFramesPerPacket == change_format.mFramesPerPacket) - { - /* The right format is now active. */ - break; - } - /* We need to check again. */ - } - - /* Removing the property listener. */ - err = AudioStreamRemovePropertyListener(i_stream_id, 0, - kAudioStreamPropertyPhysicalFormat, - StreamListener); - if (err != noErr) - { - ao_msg(MSGT_AO, MSGL_WARN, "AudioStreamRemovePropertyListener failed: [%4.4s]\n", (char *)&err); - return CONTROL_FALSE; - } - - return CONTROL_TRUE; -} - -/***************************************************************************** - * RenderCallbackSPDIF: callback for SPDIF audio output - *****************************************************************************/ -static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, - const AudioTimeStamp * inNow, - const void * inInputData, - const AudioTimeStamp * inInputTime, - AudioBufferList * outOutputData, - const AudioTimeStamp * inOutputTime, - void * threadGlobals ) -{ - int amt = av_fifo_size(ao->buffer); - int req = outOutputData->mBuffers[ao->i_stream_index].mDataByteSize; - - if (amt > req) - amt = req; - if (amt) - read_buffer(ao->b_muted ? NULL : (unsigned char *)outOutputData->mBuffers[ao->i_stream_index].mData, amt); - - return noErr; -} - - -static int play(void* output_samples,int num_bytes,int flags) -{ - int wrote, b_digital; - - // Check whether we need to reset the digital output stream. - if (ao->b_digital && ao->b_stream_format_changed) - { - ao->b_stream_format_changed = 0; - b_digital = AudioStreamSupportsDigital(ao->i_stream_id); - if (b_digital) - { - /* Current stream support digital format output, let's set it. */ - ao_msg(MSGT_AO, MSGL_V, "detected current stream support digital, try to restore digital output...\n"); - - if (!AudioStreamChangeFormat(ao->i_stream_id, ao->stream_format)) - { - ao_msg(MSGT_AO, MSGL_WARN, "restore digital output failed.\n"); - } - else - { - ao_msg(MSGT_AO, MSGL_WARN, "restore digital output succeed.\n"); - reset(); - } - } - else - ao_msg(MSGT_AO, MSGL_V, "detected current stream do not support digital.\n"); - } - - wrote=write_buffer(output_samples, num_bytes); - audio_resume(); - return wrote; -} - -/* set variables and buffer to initial state */ -static void reset(void) -{ - audio_pause(); - av_fifo_reset(ao->buffer); -} - - -/* return available space */ -static int get_space(void) -{ - return ao->buffer_len - av_fifo_size(ao->buffer); -} - - -/* return delay until audio is played */ -static float get_delay(void) -{ - // inaccurate, should also contain the data buffered e.g. by the OS - return (float)av_fifo_size(ao->buffer)/(float)ao_data.bps; -} - - -/* unload plugin and deregister from coreaudio */ -static void uninit(int immed) -{ - OSStatus err = noErr; - UInt32 i_param_size = 0; - - if (!immed) { - long long timeleft=(1000000LL*av_fifo_size(ao->buffer))/ao_data.bps; - ao_msg(MSGT_AO,MSGL_DBG2, "%d bytes left @%d bps (%d usec)\n", av_fifo_size(ao->buffer), ao_data.bps, (int)timeleft); - usec_sleep((int)timeleft); - } - - if (!ao->b_digital) { - AudioOutputUnitStop(ao->theOutputUnit); - AudioUnitUninitialize(ao->theOutputUnit); - CloseComponent(ao->theOutputUnit); - } - else { - /* Stop device. */ - err = AudioDeviceStop(ao->i_selected_dev, - (AudioDeviceIOProc)RenderCallbackSPDIF); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); - - /* Remove IOProc callback. */ - err = AudioDeviceRemoveIOProc(ao->i_selected_dev, - (AudioDeviceIOProc)RenderCallbackSPDIF); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceRemoveIOProc failed: [%4.4s]\n", (char *)&err); - - if (ao->b_revert) - AudioStreamChangeFormat(ao->i_stream_id, ao->sfmt_revert); - - if (ao->b_changed_mixing && ao->sfmt_revert.mFormatID != kAudioFormat60958AC3) - { - int b_mix; - Boolean b_writeable; - /* Revert mixable to true if we are allowed to. */ - err = AudioDeviceGetPropertyInfo(ao->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, - &i_param_size, &b_writeable); - err = AudioDeviceGetProperty(ao->i_selected_dev, 0, FALSE, kAudioDevicePropertySupportsMixing, - &i_param_size, &b_mix); - if (err != noErr && b_writeable) - { - b_mix = 1; - err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertySupportsMixing, i_param_size, &b_mix); - } - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "failed to set mixmode: [%4.4s]\n", (char *)&err); - } - if (ao->i_hog_pid == getpid()) - { - ao->i_hog_pid = -1; - i_param_size = sizeof(ao->i_hog_pid); - err = AudioDeviceSetProperty(ao->i_selected_dev, 0, 0, FALSE, - kAudioDevicePropertyHogMode, i_param_size, &ao->i_hog_pid); - if (err != noErr) ao_msg(MSGT_AO, MSGL_WARN, "Could not release hogmode: [%4.4s]\n", (char *)&err); - } - } - - av_fifo_free(ao->buffer); - free(ao); - ao = NULL; -} - - -/* stop playing, keep buffers (for pause) */ -static void audio_pause(void) -{ - OSErr err=noErr; - - /* Stop callback. */ - if (!ao->b_digital) - { - err=AudioOutputUnitStop(ao->theOutputUnit); - if (err != noErr) - ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStop returned [%4.4s]\n", (char *)&err); - } - else - { - err = AudioDeviceStop(ao->i_selected_dev, (AudioDeviceIOProc)RenderCallbackSPDIF); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStop failed: [%4.4s]\n", (char *)&err); - } - ao->paused = 1; -} - - -/* resume playing, after audio_pause() */ -static void audio_resume(void) -{ - OSErr err=noErr; - - if (!ao->paused) - return; - - /* Start callback. */ - if (!ao->b_digital) - { - err = AudioOutputUnitStart(ao->theOutputUnit); - if (err != noErr) - ao_msg(MSGT_AO,MSGL_WARN, "AudioOutputUnitStart returned [%4.4s]\n", (char *)&err); - } - else - { - err = AudioDeviceStart(ao->i_selected_dev, (AudioDeviceIOProc)RenderCallbackSPDIF); - if (err != noErr) - ao_msg(MSGT_AO, MSGL_WARN, "AudioDeviceStart failed: [%4.4s]\n", (char *)&err); - } - ao->paused = 0; -} - -/***************************************************************************** - * StreamListener - *****************************************************************************/ -static OSStatus StreamListener( AudioStreamID inStream, - UInt32 inChannel, - AudioDevicePropertyID inPropertyID, - void * inClientData ) -{ - switch (inPropertyID) - { - case kAudioStreamPropertyPhysicalFormat: - ao_msg(MSGT_AO, MSGL_V, "got notify kAudioStreamPropertyPhysicalFormat changed.\n"); - if (inClientData) - *(volatile int *)inClientData = 1; - default: - break; - } - return noErr; -} - -static OSStatus DeviceListener( AudioDeviceID inDevice, - UInt32 inChannel, - Boolean isInput, - AudioDevicePropertyID inPropertyID, - void* inClientData ) -{ - switch (inPropertyID) - { - case kAudioDevicePropertyDeviceHasChanged: - ao_msg(MSGT_AO, MSGL_WARN, "got notify kAudioDevicePropertyDeviceHasChanged.\n"); - ao->b_stream_format_changed = 1; - default: - break; - } - return noErr; -} diff --git a/libao2/audio_out.c b/libao2/audio_out.c index 0e26e761fa..fc41a73e57 100644 --- a/libao2/audio_out.c +++ b/libao2/audio_out.c @@ -32,7 +32,7 @@ ao_data_t ao_data={0,0,0,0,OUTBURST,-1,0}; char *ao_subdevice = NULL; extern const ao_functions_t audio_out_oss; -extern const ao_functions_t audio_out_macosx; +extern const ao_functions_t audio_out_coreaudio; extern const ao_functions_t audio_out_arts; extern const ao_functions_t audio_out_esd; extern const ao_functions_t audio_out_pulse; @@ -68,7 +68,7 @@ const ao_functions_t* const audio_out_drivers[] = &audio_out_dart, #endif #ifdef CONFIG_COREAUDIO - &audio_out_macosx, + &audio_out_coreaudio, #endif #ifdef CONFIG_OSS_AUDIO &audio_out_oss, -- cgit v1.2.3 From d9ded9284c43a311b8c2bed6e85466be4d465c0c Mon Sep 17 00:00:00 2001 From: diego Date: Mon, 4 May 2009 17:35:26 +0000 Subject: Add missing 'void' to parameterless function declarations. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@29254 b3059339-0415-0410-9bf9-f77b7e298cf2 --- DOCS/tech/libao2.txt | 8 ++++---- get_path.c | 2 +- get_path.h | 2 +- input/ar.c | 2 +- liba52/test.c | 2 +- libao2/ao_coreaudio.c | 4 ++-- libmpcodecs/ad_qtaudio.c | 2 +- libmpcodecs/vqf.h | 18 +++++++++--------- libvo/mga_common.c | 2 +- libvo/vo_caca.c | 2 +- libvo/vo_directx.c | 12 ++++++------ libvo/vo_dxr2.c | 2 +- libvo/vo_quartz.c | 16 ++++++++-------- libvo/vo_tdfxfb.c | 2 +- loader/dmo/dmo.c | 2 +- loader/dshow/DS_Filter.c | 2 -- loader/registry.c | 2 +- loader/vfl.c | 2 +- loader/win32.c | 40 ++++++++++++++++++++-------------------- osdep/timer-darwin.c | 8 ++++---- osdep/timer.h | 2 +- vidix/sysdep/AsmMacros_powerpc.h | 2 +- vidix/sysdep/AsmMacros_x86.h | 4 ++-- vidix/sysdep/pci_win32.c | 2 +- 24 files changed, 70 insertions(+), 72 deletions(-) (limited to 'libao2') diff --git a/DOCS/tech/libao2.txt b/DOCS/tech/libao2.txt index e2a530050d..ba8317e056 100644 --- a/DOCS/tech/libao2.txt +++ b/DOCS/tech/libao2.txt @@ -12,16 +12,16 @@ static int init(int rate,int channels,int format,int flags); Sample format: usually AFMT_S16_LE or AFMT_U8, for more definitions see dec_audio.c and linux/soundcards.h files! -static void uninit(); +static void uninit(void); Guess what. Ok I help: closes the device, not (yet) called when exit. -static void reset(); +static void reset(void); Resets device. To be exact, it's for deleting buffers' contents, so after reset() the previously received stuff won't be output. (called if pause or seek) -static int get_space(); +static int get_space(void); Returns how many bytes can be written into the audio buffer without blocking (making caller process wait). MPlayer occasionally checks the remaining space and tries to fill the buffer with play() if there's free @@ -41,7 +41,7 @@ static int play(void* data,int len,int flags); rounded down to 0 or the data will never be played (as MPlayer will never call play() with a larger len). -static float get_delay(); +static float get_delay(void); Returns how long time it will take to play the data currently in the output buffer. Be exact, if possible, since the whole timing depends on this! In the worst case, return the maximum delay. diff --git a/get_path.c b/get_path.c index f5cf41354e..6ef074b869 100644 --- a/get_path.c +++ b/get_path.c @@ -140,7 +140,7 @@ char *get_path(const char *filename){ } #if (defined(__MINGW32__) || defined(__CYGWIN__)) && defined(CONFIG_WIN32DLL) -void set_path_env() +void set_path_env(void) { /*make our codec dirs available for LoadLibraryA()*/ char tmppath[MAX_PATH*2 + 1]; diff --git a/get_path.h b/get_path.h index 09eef7b933..2f1909b601 100644 --- a/get_path.h +++ b/get_path.h @@ -22,6 +22,6 @@ #define MPLAYER_GET_PATH_H char *get_path(const char *filename); -void set_path_env(); +void set_path_env(void); #endif /* MPLAYER_GET_PATH_H */ diff --git a/input/ar.c b/input/ar.c index 61a6de0c6d..e64c64d45b 100644 --- a/input/ar.c +++ b/input/ar.c @@ -303,7 +303,7 @@ mp_input_ar_init_error: return -1; } -int is_mplayer_front() +int is_mplayer_front(void) { ProcessSerialNumber myProc, frProc; Boolean sameProc; diff --git a/liba52/test.c b/liba52/test.c index f54ca5f836..2fb661011d 100644 --- a/liba52/test.c +++ b/liba52/test.c @@ -43,7 +43,7 @@ void mp_msg( int x, const char *format, ... ) // stub for cpudetect.c } #ifdef TIMING -static inline long long rdtsc() +static inline long long rdtsc(void) { long long l; __asm__ volatile("rdtsc\n\t" diff --git a/libao2/ao_coreaudio.c b/libao2/ao_coreaudio.c index 18a2fd7cf1..3ef6d3367f 100644 --- a/libao2/ao_coreaudio.c +++ b/libao2/ao_coreaudio.c @@ -215,7 +215,7 @@ static void print_format(int lev, const char* str, const AudioStreamBasicDescrip static int AudioDeviceSupportsDigital( AudioDeviceID i_dev_id ); static int AudioStreamSupportsDigital( AudioStreamID i_stream_id ); -static int OpenSPDIF(); +static int OpenSPDIF(void); static int AudioStreamChangeFormat( AudioStreamID i_stream_id, AudioStreamBasicDescription change_format ); static OSStatus RenderCallbackSPDIF( AudioDeviceID inDevice, const AudioTimeStamp * inNow, @@ -473,7 +473,7 @@ err_out: /***************************************************************************** * Setup a encoded digital stream (SPDIF) *****************************************************************************/ -static int OpenSPDIF() +static int OpenSPDIF(void) { OSStatus err = noErr; UInt32 i_param_size, b_mix = 0; diff --git a/libmpcodecs/ad_qtaudio.c b/libmpcodecs/ad_qtaudio.c index 856cb05601..b1662bb9f4 100644 --- a/libmpcodecs/ad_qtaudio.c +++ b/libmpcodecs/ad_qtaudio.c @@ -81,7 +81,7 @@ HMODULE WINAPI LoadLibraryA(LPCSTR); FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR); int WINAPI FreeLibrary(HMODULE); -static int loader_init() +static int loader_init(void) { #ifdef WIN32_LOADER diff --git a/libmpcodecs/vqf.h b/libmpcodecs/vqf.h index 85691f5568..118f7ea06f 100644 --- a/libmpcodecs/vqf.h +++ b/libmpcodecs/vqf.h @@ -193,7 +193,7 @@ typedef struct { //DllPort int TvqInitialize( headerInfo *setupInfo, INDEX *index, int dispErrorMessageBox ); //DllPort void TvqTerminate( INDEX *index ); //DllPort void TvqGetVectorInfo(int *bits0[], int *bits1[]); -//DllPort void TvqResetFrameCounter(); +//DllPort void TvqResetFrameCounter(void); // TwinVQ decoder function //DllPort void TvqDecodeFrame(INDEX *indexp, float out[]); @@ -205,19 +205,19 @@ typedef struct { //DllPort int TvqCheckVersion(char *versionID); //DllPort void TvqGetSetupInfo(headerInfo *setupInfo); // setup information //DllPort void TvqGetConfInfo(tvqConfInfo *cf); // configuration information -//DllPort int TvqGetFrameSize(); // frame size -//DllPort int TvqGetNumChannels(); // number of channels -//DllPort int TvqGetBitRate(); // total bitrate -//DllPort float TvqGetSamplingRate(); // sampling rate -//DllPort int TvqGetNumFixedBitsPerFrame(); // number of fixed bits per frame -//DllPort int TvqGetNumFrames(); // number of decoded frame +//DllPort int TvqGetFrameSize(void); // frame size +//DllPort int TvqGetNumChannels(void); // number of channels +//DllPort int TvqGetBitRate(void); // total bitrate +//DllPort float TvqGetSamplingRate(void); // sampling rate +//DllPort int TvqGetNumFixedBitsPerFrame(void); // number of fixed bits per frame +//DllPort int TvqGetNumFrames(void); // number of decoded frame //DllPort int TvqGetModuleVersion( char* versionString ); #ifdef V2PLUS_SUPPORT // TwinVQ FB coding tool control DllPort void TvqFbCountUsedBits(int nbit); // count number of used bits -DllPort float TvqGetFbCurrentBitrate(); // query average bitrate for the tool -DllPort int TvqGetFbTotalBits(); // query total number of used bits +DllPort float TvqGetFbCurrentBitrate(void); // query average bitrate for the tool +DllPort int TvqGetFbTotalBits(void); // query total number of used bits #endif #ifdef __cplusplus diff --git a/libvo/mga_common.c b/libvo/mga_common.c index 69c8f6322d..6981123eb8 100644 --- a/libvo/mga_common.c +++ b/libvo/mga_common.c @@ -454,7 +454,7 @@ static int mga_init(int width,int height,unsigned int format){ return 0; } -static int mga_uninit(){ +static int mga_uninit(void){ if(f>=0){ ioctl( f,MGA_VID_OFF,0 ); munmap(frames[0],mga_vid_config.frame_size*mga_vid_config.num_frames); diff --git a/libvo/vo_caca.c b/libvo/vo_caca.c index 36ceb03762..9181eed7de 100644 --- a/libvo/vo_caca.c +++ b/libvo/vo_caca.c @@ -140,7 +140,7 @@ static void osdpercent(int duration, int min, int max, int val, const char *desc posbar[screen_w] = '\0'; } -static int resize () +static int resize(void) { screen_w = caca_get_width(); screen_h = caca_get_height(); diff --git a/libvo/vo_directx.c b/libvo/vo_directx.c index 224af242c2..22ac04a9e5 100644 --- a/libvo/vo_directx.c +++ b/libvo/vo_directx.c @@ -200,7 +200,7 @@ query_format(uint32_t format) return 0; } -static uint32_t Directx_CreatePrimarySurface() +static uint32_t Directx_CreatePrimarySurface(void) { DDSURFACEDESC2 ddsd; //cleanup @@ -310,7 +310,7 @@ static uint32_t Directx_CreateOverlay(uint32_t imgfmt) return 0; } -static uint32_t Directx_CreateBackpuffer() +static uint32_t Directx_CreateBackpuffer(void) { DDSURFACEDESC2 ddsd; //cleanup @@ -416,7 +416,7 @@ static BOOL WINAPI EnumCallbackEx(GUID FAR *lpGUID, LPSTR lpDriverDescription, L return 1; // list all adapters } -static uint32_t Directx_InitDirectDraw() +static uint32_t Directx_InitDirectDraw(void) { HRESULT (WINAPI *OurDirectDrawCreateEx)(GUID *,LPVOID *, REFIID,IUnknown FAR *); DDSURFACEDESC2 ddsd; @@ -533,7 +533,7 @@ static void check_events(void) } } -static uint32_t Directx_ManageDisplay() +static uint32_t Directx_ManageDisplay(void) { HRESULT ddrval; DDCAPS capsDrv; @@ -763,7 +763,7 @@ static uint32_t Directx_ManageDisplay() } //find out supported overlay pixelformats -static uint32_t Directx_CheckOverlayPixelformats() +static uint32_t Directx_CheckOverlayPixelformats(void) { DDCAPS capsDrv; HRESULT ddrval; @@ -824,7 +824,7 @@ static uint32_t Directx_CheckOverlayPixelformats() } //find out the Pixelformat of the Primary Surface -static uint32_t Directx_CheckPrimaryPixelformat() +static uint32_t Directx_CheckPrimaryPixelformat(void) { uint32_t i=0; uint32_t formatcount = 0; diff --git a/libvo/vo_dxr2.c b/libvo/vo_dxr2.c index 0bf64f58d6..efb07c1b6c 100644 --- a/libvo/vo_dxr2.c +++ b/libvo/vo_dxr2.c @@ -203,7 +203,7 @@ int write_dxr2(const unsigned char *data, int len) return w; } -static void flush_dxr2() +static void flush_dxr2(void) { int w; while (dxr2bufpos) { diff --git a/libvo/vo_quartz.c b/libvo/vo_quartz.c index edc99ab445..f7a730a14d 100644 --- a/libvo/vo_quartz.c +++ b/libvo/vo_quartz.c @@ -151,10 +151,10 @@ enum static OSStatus KeyEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData); static OSStatus MouseEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData); static OSStatus WindowEventHandler(EventHandlerCallRef nextHandler, EventRef event, void *userData); -void window_resized(); -void window_ontop(); -void window_fullscreen(); -void window_panscan(); +void window_resized(void); +void window_ontop(void); +void window_fullscreen(void); +void window_panscan(void); static inline int convert_key(UInt32 key, UInt32 charcode) { @@ -1315,7 +1315,7 @@ static int control(uint32_t request, void *data, ...) return VO_NOTIMPL; } -void window_resized() +void window_resized(void) { float aspectX; float aspectY; @@ -1396,7 +1396,7 @@ void window_resized() QDEndCGContext(GetWindowPort(theWindow), &context); } -void window_ontop() +void window_ontop(void) { if (!vo_quartz_fs) { @@ -1408,7 +1408,7 @@ void window_ontop() SetWindowGroupLevel(winGroup, CGWindowLevelForKey(levelList[winLevel])); } -void window_fullscreen() +void window_fullscreen(void) { // go fullscreen if (vo_fs) @@ -1493,7 +1493,7 @@ void window_fullscreen() window_resized(); } -void window_panscan() +void window_panscan(void) { panscan_calc(); diff --git a/libvo/vo_tdfxfb.c b/libvo/vo_tdfxfb.c index 1b63147817..03f0513076 100644 --- a/libvo/vo_tdfxfb.c +++ b/libvo/vo_tdfxfb.c @@ -202,7 +202,7 @@ static void uninit(void) } } -static void clear_screen() +static void clear_screen(void) { /* There needs to be some sort of delay here or else things seriously * screw up. Causes the image to not be the right size on screen if diff --git a/loader/dmo/dmo.c b/loader/dmo/dmo.c index ee6ac27f3c..0e4d2a45e4 100644 --- a/loader/dmo/dmo.c +++ b/loader/dmo/dmo.c @@ -12,7 +12,7 @@ #include #include "win32.h" // printf macro -void trapbug(); +void trapbug(void); typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); void DMO_Filter_Destroy(DMO_Filter* This) diff --git a/loader/dshow/DS_Filter.c b/loader/dshow/DS_Filter.c index a1619702db..11dd11dee9 100644 --- a/loader/dshow/DS_Filter.c +++ b/loader/dshow/DS_Filter.c @@ -30,8 +30,6 @@ HRESULT STDCALL CoInitialize(LPVOID pvReserved); void STDCALL CoUninitialize(void); #endif -//void trapbug(); - static void DS_Filter_Start(DS_Filter* This) { HRESULT hr; diff --git a/loader/registry.c b/loader/registry.c index 01c6321ec5..c92321f4e0 100644 --- a/loader/registry.c +++ b/loader/registry.c @@ -216,7 +216,7 @@ static reg_handle_t* find_handle(int handle) } return 0; } -static int generate_handle() +static int generate_handle(void) { static unsigned int zz=249; zz++; diff --git a/loader/vfl.c b/loader/vfl.c index 54d1076fa4..7b0f10ea77 100644 --- a/loader/vfl.c +++ b/loader/vfl.c @@ -223,7 +223,7 @@ LRESULT VFWAPI ICClose(HIC hic) { return 0; } -int VFWAPI ICDoSomething() +int VFWAPI ICDoSomething(void) { return 0; } diff --git a/loader/win32.c b/loader/win32.c index 4287c5b0b1..bf0ad205b9 100644 --- a/loader/win32.c +++ b/loader/win32.c @@ -90,7 +90,7 @@ static void do_cpuid(unsigned int ax, unsigned int *regs) : "0" (ax), "S" (regs) ); } -static unsigned int c_localcount_tsc() +static unsigned int c_localcount_tsc(void) { int a; __asm__ volatile @@ -116,7 +116,7 @@ static void c_longcount_tsc(long long* z) :"edx" ); } -static unsigned int c_localcount_notsc() +static unsigned int c_localcount_notsc(void) { struct timeval tv; unsigned limit=~0; @@ -485,7 +485,7 @@ static void* my_realloc(void* memory, int size) * */ -static int WINAPI ext_unknown() +static int WINAPI ext_unknown(void) { printf("Unknown func called\n"); return 0; @@ -1134,7 +1134,7 @@ static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v) } -static long WINAPI expGetVersion() +static long WINAPI expGetVersion(void) { dbgprintf("GetVersion() => 0xC0000004\n"); return 0xC0000004;//Windows 95 @@ -1426,12 +1426,12 @@ static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c) #endif return; } -static int WINAPI expGetCurrentThreadId() +static int WINAPI expGetCurrentThreadId(void) { dbgprintf("GetCurrentThreadId() => %d\n", pthread_self()); return pthread_self(); } -static int WINAPI expGetCurrentProcess() +static int WINAPI expGetCurrentProcess(void) { dbgprintf("GetCurrentProcess() => %d\n", getpid()); return getpid(); @@ -1445,7 +1445,7 @@ extern void* fs_seg; //static int tls_count; static int tls_use_map[64]; -static int WINAPI expTlsAlloc() +static int WINAPI expTlsAlloc(void) { int i; for(i=0; i<64; i++) @@ -1496,7 +1496,7 @@ struct tls_s { struct tls_s* next; }; -static void* WINAPI expTlsAlloc() +static void* WINAPI expTlsAlloc(void) { if (g_tls == NULL) { @@ -1913,7 +1913,7 @@ static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_l /* * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo) */ -static double linux_cpuinfo_freq() +static double linux_cpuinfo_freq(void) { double freq=-1; FILE *f; @@ -1945,7 +1945,7 @@ static double linux_cpuinfo_freq() } -static double solaris_kstat_freq() +static double solaris_kstat_freq(void) { #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32) /* @@ -1988,7 +1988,7 @@ static double solaris_kstat_freq() /* * Measure CPU freq using the pentium's time stamp counter register (TSC) */ -static double tsc_freq() +static double tsc_freq(void) { static double ofreq=0.0; int i; @@ -2004,7 +2004,7 @@ static double tsc_freq() return ofreq; } -static double CPU_Freq() +static double CPU_Freq(void) { double freq; @@ -2023,7 +2023,7 @@ static long WINAPI expQueryPerformanceFrequency(long long* z) dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z); return 1; } -static long WINAPI exptimeGetTime() +static long WINAPI exptimeGetTime(void) { struct timeval t; long result; @@ -2116,13 +2116,13 @@ static int WINAPI expCloseHandle(long v1) return 1; } -static const char* WINAPI expGetCommandLineA() +static const char* WINAPI expGetCommandLineA(void) { dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n"); return "c:\\aviplay.exe"; } static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0}; -static LPWSTR WINAPI expGetEnvironmentStringsW() +static LPWSTR WINAPI expGetEnvironmentStringsW(void) { dbgprintf("GetEnvironmentStringsW() => 0\n", envs); return 0; @@ -2160,7 +2160,7 @@ static int WINAPI expFreeEnvironmentStringsA(char* strings) static const char ch_envs[]= "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n" "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n"; -static LPCSTR WINAPI expGetEnvironmentStrings() +static LPCSTR WINAPI expGetEnvironmentStrings(void) { dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs); return (LPCSTR)ch_envs; @@ -2818,7 +2818,7 @@ static int WINAPI expSizeofResource(int v1, int v2) return result; } -static int WINAPI expGetLastError() +static int WINAPI expGetLastError(void) { int result=GetLastError(); dbgprintf("GetLastError() => 0x%x\n", result); @@ -2914,7 +2914,7 @@ static int WINAPI expReleaseDC(int hwnd, int hdc) return 1; } -static int WINAPI expGetDesktopWindow() +static int WINAPI expGetDesktopWindow(void) { dbgprintf("GetDesktopWindow() => 0\n"); return 0; @@ -3581,7 +3581,7 @@ static UINT WINAPI expGetSystemDirectoryA( } /* static char sysdir[]="."; -static LPCSTR WINAPI expGetSystemDirectoryA() +static LPCSTR WINAPI expGetSystemDirectoryA(void) { dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir); return sysdir; @@ -4039,7 +4039,7 @@ static int exp_initterm_e(INITTERMFUNC *start, INITTERMFUNC *end) return 0; } -static void* exp__dllonexit() +static void* exp__dllonexit(void) { // FIXME extract from WINE return NULL; diff --git a/osdep/timer-darwin.c b/osdep/timer-darwin.c index 4eb973a0c7..9c49cd0fc8 100644 --- a/osdep/timer-darwin.c +++ b/osdep/timer-darwin.c @@ -52,19 +52,19 @@ int usec_sleep(int usec_delay) /* current time in microseconds */ -unsigned int GetTimer() +unsigned int GetTimer(void) { return (unsigned int)(uint64_t)(mach_absolute_time() * timebase_ratio * 1e6); } /* current time in milliseconds */ -unsigned int GetTimerMS() +unsigned int GetTimerMS(void) { return (unsigned int)(uint64_t)(mach_absolute_time() * timebase_ratio * 1e3); } /* time spent between now and last call in seconds */ -float GetRelativeTime() +float GetRelativeTime(void) { double last_time = relative_time; @@ -77,7 +77,7 @@ float GetRelativeTime() } /* initialize timer, must be called at least once at start */ -void InitTimer() +void InitTimer(void) { struct mach_timebase_info timebase; diff --git a/osdep/timer.h b/osdep/timer.h index b92fb46ca6..2e4f2fc8fe 100644 --- a/osdep/timer.h +++ b/osdep/timer.h @@ -24,7 +24,7 @@ extern const char *timer_name; void InitTimer(void); unsigned int GetTimer(void); unsigned int GetTimerMS(void); -//int uGetTimer(); +//int uGetTimer(void); float GetRelativeTime(void); int usec_sleep(int usec_delay); diff --git a/vidix/sysdep/AsmMacros_powerpc.h b/vidix/sysdep/AsmMacros_powerpc.h index 0ae2fd57d2..7688c6ad9f 100644 --- a/vidix/sysdep/AsmMacros_powerpc.h +++ b/vidix/sysdep/AsmMacros_powerpc.h @@ -66,7 +66,7 @@ extern unsigned char *ioBase; -static __inline__ volatile void eieio() +static __inline__ volatile void eieio(void) { __asm__ volatile ("eieio"); } diff --git a/vidix/sysdep/AsmMacros_x86.h b/vidix/sysdep/AsmMacros_x86.h index 6bebeaa505..88e71e275d 100644 --- a/vidix/sysdep/AsmMacros_x86.h +++ b/vidix/sysdep/AsmMacros_x86.h @@ -321,7 +321,7 @@ static __inline__ unsigned int inl(short port) return ret; } -static __inline__ void intr_disable() +static __inline__ void intr_disable(void) { #ifdef CONFIG_SVGAHELPER if (svgahelper_initialized == 1) @@ -330,7 +330,7 @@ static __inline__ void intr_disable() __asm__ volatile("cli"); } -static __inline__ void intr_enable() +static __inline__ void intr_enable(void) { #ifdef CONFIG_SVGAHELPER if (svgahelper_initialized == 1) diff --git a/vidix/sysdep/pci_win32.c b/vidix/sysdep/pci_win32.c index d01cdfd30e..bdaf5d53ff 100644 --- a/vidix/sysdep/pci_win32.c +++ b/vidix/sysdep/pci_win32.c @@ -31,7 +31,7 @@ #include "vidix/dhahelperwin/dhahelper.h" static HANDLE hDriver; -int IsWinNT(); +int IsWinNT(void); -- cgit v1.2.3