summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2001-04-28 19:47:41 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2001-04-28 19:47:41 +0000
commit12d67b2b0a4fd1a0bbaea2eb2bb5e5969fef0a54 (patch)
treeba751a49d2220661b167b56df8b72b12836fa7fb /src
parent77489362597b81f0a4e8771281f4cf94801c3976 (diff)
downloadxine-lib-12d67b2b0a4fd1a0bbaea2eb2bb5e5969fef0a54.tar.gz
xine-lib-12d67b2b0a4fd1a0bbaea2eb2bb5e5969fef0a54.tar.bz2
bugfix in video_out_xv, sorted out audio output plugin handling/code
CVS patchset: 39 CVS date: 2001/04/28 19:47:41
Diffstat (limited to 'src')
-rw-r--r--src/audio_out/audio_oss_out.c245
-rw-r--r--src/libac3/decode.c16
-rw-r--r--src/video_out/video_out_xv.c4
-rw-r--r--src/xine-engine/audio_out.h94
-rw-r--r--src/xine-engine/load_plugins.c118
-rw-r--r--src/xine-engine/video_out.h15
-rw-r--r--src/xine-engine/xine.c5
7 files changed, 304 insertions, 193 deletions
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c
index 795a2c8d3..8de699765 100644
--- a/src/audio_out/audio_oss_out.c
+++ b/src/audio_out/audio_oss_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_oss_out.c,v 1.2 2001/04/27 10:42:38 f1rmb Exp $
+ * $Id: audio_oss_out.c,v 1.3 2001/04/28 19:47:41 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -28,6 +28,7 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
+#include <stdlib.h>
#include <fcntl.h>
#include <math.h>
#if defined(__OpenBSD__)
@@ -45,9 +46,7 @@
#include "audio_out.h"
#include "resample.h"
#include "metronom.h"
-#include "libac3/ac3.h"
#include "utils.h"
-#include "metronom.h"
#define AO_OUT_OSS_IFACE_VERSION 1
@@ -59,7 +58,11 @@
#define DSP_TEMPLATE "/dev/dsp%d"
-typedef struct _audio_oss_globals {
+typedef struct oss_functions_s {
+
+ ao_functions_t ao_functions;
+
+ metronom_t *metronom;
char audio_dev[20];
int audio_fd;
@@ -82,16 +85,15 @@ typedef struct _audio_oss_globals {
int audio_started;
-} audio_oss_globals_t;
-
-static audio_oss_globals_t gAudioOSS;
+} oss_functions_t;
/*
* open the audio device for writing to
*/
-static int ao_open(metronom_t *metronom,
+static int ao_open(ao_functions_t *this_gen,
uint32_t bits, uint32_t rate, int mode)
{
+ oss_functions_t *this = (oss_functions_t *) this_gen;
int tmp;
int fsize;
@@ -102,64 +104,64 @@ static int ao_open(metronom_t *metronom,
return -1;
}
- if (gAudioOSS.audio_fd > -1) {
+ if (this->audio_fd > -1) {
- if (rate == gAudioOSS.input_sample_rate)
+ if (rate == this->input_sample_rate)
return 1;
- close (gAudioOSS.audio_fd);
+ close (this->audio_fd);
}
- gAudioOSS.input_sample_rate = rate;
- gAudioOSS.bytes_in_buffer = 0;
- gAudioOSS.last_vpts = 0;
- gAudioOSS.output_rate_correction = 0;
- gAudioOSS.sync_vpts = 0;
- gAudioOSS.sync_bytes_in_buffer = 0;
- gAudioOSS.audio_started = 0;
+ this->input_sample_rate = rate;
+ this->bytes_in_buffer = 0;
+ this->last_vpts = 0;
+ this->output_rate_correction = 0;
+ this->sync_vpts = 0;
+ this->sync_bytes_in_buffer = 0;
+ this->audio_started = 0;
/*
* open audio device
*/
- gAudioOSS.audio_fd=open(gAudioOSS.audio_dev,O_WRONLY|O_NDELAY);
- if(gAudioOSS.audio_fd < 0) {
+ this->audio_fd=open(this->audio_dev,O_WRONLY|O_NDELAY);
+ if(this->audio_fd < 0) {
printf("audio_oss_out: Opening audio device %s: %s\n",
- gAudioOSS.audio_dev, strerror(errno));
+ this->audio_dev, strerror(errno));
return -1;
}
/* We wanted non blocking open but now put it back to normal */
- fcntl(gAudioOSS.audio_fd, F_SETFL, fcntl(gAudioOSS.audio_fd, F_GETFL)&~FNDELAY);
+ fcntl(this->audio_fd, F_SETFL, fcntl(this->audio_fd, F_GETFL)&~FNDELAY);
/*
* configure audio device
*/
tmp = (mode == AO_MODE_STEREO) ? 1 : 0;
- ioctl(gAudioOSS.audio_fd,SNDCTL_DSP_STEREO,&tmp);
+ ioctl(this->audio_fd,SNDCTL_DSP_STEREO,&tmp);
- gAudioOSS.num_channels = tmp+1;
- xprintf (VERBOSE|AUDIO, "audio_oss_out: %d channels\n",gAudioOSS.num_channels);
+ this->num_channels = tmp+1;
+ xprintf (VERBOSE|AUDIO, "audio_oss_out: %d channels\n",this->num_channels);
tmp = bits;
- ioctl(gAudioOSS.audio_fd,SNDCTL_DSP_SAMPLESIZE,&tmp);
+ ioctl(this->audio_fd,SNDCTL_DSP_SAMPLESIZE,&tmp);
- tmp = gAudioOSS.input_sample_rate;
- ioctl(gAudioOSS.audio_fd,SNDCTL_DSP_SPEED, &tmp);
- gAudioOSS.output_sample_rate = tmp;
+ tmp = this->input_sample_rate;
+ ioctl(this->audio_fd,SNDCTL_DSP_SPEED, &tmp);
+ this->output_sample_rate = tmp;
xprintf (VERBOSE|AUDIO, "audio_oss_out: audio rate : %d requested, %d provided by device/sec\n",
- gAudioOSS.input_sample_rate, gAudioOSS.output_sample_rate);
+ this->input_sample_rate, this->output_sample_rate);
- gAudioOSS.sample_rate_factor = (double) gAudioOSS.output_sample_rate / (double) gAudioOSS.input_sample_rate;
- gAudioOSS.audio_step = (uint32_t) 90000 * (uint32_t) 32768
- / gAudioOSS.input_sample_rate;
- gAudioOSS.bytes_per_kpts = gAudioOSS.output_sample_rate * gAudioOSS.num_channels * 2 * 1024 / 90000;
+ this->sample_rate_factor = (double) this->output_sample_rate / (double) this->input_sample_rate;
+ this->audio_step = (uint32_t) 90000 * (uint32_t) 32768
+ / this->input_sample_rate;
+ this->bytes_per_kpts = this->output_sample_rate * this->num_channels * 2 * 1024 / 90000;
- xprintf (VERBOSE|AUDIO, "audio_out : audio_step %d pts per 32768 samples\n", gAudioOSS.audio_step);
+ xprintf (VERBOSE|AUDIO, "audio_out : audio_step %d pts per 32768 samples\n", this->audio_step);
- metronom->set_audio_rate(metronom, gAudioOSS.audio_step);
+ this->metronom->set_audio_rate(this->metronom, this->audio_step);
/*
* audio buffer size handling
@@ -177,13 +179,13 @@ static int ao_open(metronom_t *metronom,
xprintf (VERBOSE|AUDIO, "Audio buffer fragment info : %x\n",tmp);
- ioctl(gAudioOSS.audio_fd,SNDCTL_DSP_SETFRAGMENT,&tmp);
+ ioctl(this->audio_fd,SNDCTL_DSP_SETFRAGMENT,&tmp);
return 1;
}
-static uint32_t ao_get_current_vpts (void) {
+static uint32_t ao_get_current_vpts (oss_functions_t *this) {
int pos ;
int32_t diff ;
@@ -191,52 +193,53 @@ static uint32_t ao_get_current_vpts (void) {
count_info info;
- if (gAudioOSS.audio_started) {
- ioctl (gAudioOSS.audio_fd, SNDCTL_DSP_GETOPTR, &info);
+ if (this->audio_started) {
+ ioctl (this->audio_fd, SNDCTL_DSP_GETOPTR, &info);
pos = info.bytes;
} else
pos = 0;
- diff = gAudioOSS.sync_bytes_in_buffer - pos;
+ diff = this->sync_bytes_in_buffer - pos;
- vpts = gAudioOSS.sync_vpts - diff * 1024 / gAudioOSS.bytes_per_kpts;
+ vpts = this->sync_vpts - diff * 1024 / this->bytes_per_kpts;
xprintf (AUDIO|VERBOSE,"audio_oss_out: get_current_vpts pos=%d diff=%d vpts=%d sync_vpts=%d\n",
- pos, diff, vpts, gAudioOSS.sync_vpts);
+ pos, diff, vpts, this->sync_vpts);
return vpts;
}
-static void ao_fill_gap (uint32_t pts_len) {
+static void ao_fill_gap (oss_functions_t *this, uint32_t pts_len) {
- int num_bytes = pts_len * gAudioOSS.bytes_per_kpts / 1024;
+ int num_bytes = pts_len * this->bytes_per_kpts / 1024;
num_bytes = (num_bytes / 4) * 4;
printf ("audio_oss_out: inserting %d 0-bytes to fill a gap of %d pts\n",num_bytes, pts_len);
- gAudioOSS.bytes_in_buffer += num_bytes;
+ this->bytes_in_buffer += num_bytes;
while (num_bytes>0) {
if (num_bytes>8192) {
- write(gAudioOSS.audio_fd, gAudioOSS.zero_space, 8192);
+ write(this->audio_fd, this->zero_space, 8192);
num_bytes -= 8192;
} else {
- write(gAudioOSS.audio_fd, gAudioOSS.zero_space, num_bytes);
+ write(this->audio_fd, this->zero_space, num_bytes);
num_bytes = 0;
}
}
- gAudioOSS.last_vpts += pts_len;
+ this->last_vpts += pts_len;
}
-static void ao_write_audio_data(metronom_t *metronom,
+static void ao_write_audio_data(ao_functions_t *this_gen,
int16_t* output_samples, uint32_t num_samples,
uint32_t pts_)
{
+ oss_functions_t *this = (oss_functions_t *) this_gen;
uint32_t vpts,
audio_vpts,
master_vpts;
@@ -245,30 +248,30 @@ static void ao_write_audio_data(metronom_t *metronom,
uint16_t sample_buffer[8192];
- if (gAudioOSS.audio_fd<0)
+ if (this->audio_fd<0)
return;
- vpts = metronom->got_audio_samples (metronom, pts_, num_samples);
+ vpts = this->metronom->got_audio_samples (this->metronom, pts_, num_samples);
xprintf (VERBOSE|AUDIO, "audio_oss_out: got %d samples, vpts=%d, last_vpts=%d\n",
- num_samples, vpts, gAudioOSS.last_vpts);
+ num_samples, vpts, this->last_vpts);
/*
* check if these samples "fit" in the audio output buffer
* or do we have an audio "gap" here?
*/
- gap = vpts - gAudioOSS.last_vpts ;
+ gap = vpts - this->last_vpts ;
/*
printf ("audio_oss_out: gap = %d - %d + %d = %d\n",
- vpts, gAudioOSS.last_vpts, diff, gap);
+ vpts, this->last_vpts, diff, gap);
*/
bDropPackage = 0;
if (gap>GAP_TOLERANCE) {
- ao_fill_gap (gap);
+ ao_fill_gap (this, gap);
} else if (gap<-GAP_TOLERANCE) {
bDropPackage = 1;
}
@@ -277,8 +280,8 @@ static void ao_write_audio_data(metronom_t *metronom,
* sync on master clock
*/
- audio_vpts = ao_get_current_vpts () ;
- master_vpts = metronom->get_current_time (metronom);
+ audio_vpts = ao_get_current_vpts (this) ;
+ master_vpts = this->metronom->get_current_time (this->metronom);
diff = audio_vpts - master_vpts;
xprintf (AUDIO|VERBOSE, "audio_oss_out: syncing on master clock: audio_vpts=%d master_vpts=%d\n",
@@ -301,14 +304,14 @@ static void ao_write_audio_data(metronom_t *metronom,
}
} else if (abs(diff)>1000) {
- gAudioOSS.output_rate_correction = diff/10 ;
+ this->output_rate_correction = diff/10 ;
- printf ("audio_oss_out: diff = %d => rate correction : %d\n", diff, gAudioOSS.output_rate_correction);
+ printf ("audio_oss_out: diff = %d => rate correction : %d\n", diff, this->output_rate_correction);
- if ( gAudioOSS.output_rate_correction < -500)
- gAudioOSS.output_rate_correction = -500;
- else if ( gAudioOSS.output_rate_correction > 500)
- gAudioOSS.output_rate_correction = 500;
+ if ( this->output_rate_correction < -500)
+ this->output_rate_correction = -500;
+ else if ( this->output_rate_correction > 500)
+ this->output_rate_correction = 500;
}
*/
@@ -319,7 +322,7 @@ static void ao_write_audio_data(metronom_t *metronom,
if (abs(diff)>MAX_MASTER_CLOCK_DIV) {
printf ("master clock adjust time %d -> %d (diff: %d)\n", master_vpts, audio_vpts, diff);
- metronom->adjust_clock (metronom, audio_vpts);
+ this->metronom->adjust_clock (this->metronom, audio_vpts);
}
@@ -328,13 +331,13 @@ static void ao_write_audio_data(metronom_t *metronom,
*/
if (!bDropPackage) {
- int num_output_samples = num_samples * (gAudioOSS.output_sample_rate + gAudioOSS.output_rate_correction) / gAudioOSS.input_sample_rate;
+ int num_output_samples = num_samples * (this->output_sample_rate + this->output_rate_correction) / this->input_sample_rate;
audio_out_resample_stereo (output_samples, num_samples,
sample_buffer, num_output_samples);
- write(gAudioOSS.audio_fd, sample_buffer, num_output_samples * 2 * gAudioOSS.num_channels);
+ write(this->audio_fd, sample_buffer, num_output_samples * 2 * this->num_channels);
xprintf (AUDIO|VERBOSE, "audio_oss_out :audio package written\n");
@@ -342,64 +345,69 @@ static void ao_write_audio_data(metronom_t *metronom,
* remember vpts
*/
- gAudioOSS.sync_vpts = vpts;
- gAudioOSS.sync_bytes_in_buffer = gAudioOSS.bytes_in_buffer;
+ this->sync_vpts = vpts;
+ this->sync_bytes_in_buffer = this->bytes_in_buffer;
/*
* step values
*/
- gAudioOSS.bytes_in_buffer += num_output_samples * 2 * gAudioOSS.num_channels;
- gAudioOSS.audio_started = 1;
+ this->bytes_in_buffer += num_output_samples * 2 * this->num_channels;
+ this->audio_started = 1;
} else {
printf ("audio_oss_out: audio package (vpts = %d) dropped\n", vpts);
- gAudioOSS.sync_vpts = vpts;
+ this->sync_vpts = vpts;
}
- gAudioOSS.last_vpts = vpts + num_samples * 90000 / gAudioOSS.input_sample_rate ;
+ this->last_vpts = vpts + num_samples * 90000 / this->input_sample_rate ;
}
-static void ao_close(void)
+static void ao_close(ao_functions_t *this_gen)
{
- close(gAudioOSS.audio_fd);
- gAudioOSS.audio_fd = -1;
+ oss_functions_t *this = (oss_functions_t *) this_gen;
+ close(this->audio_fd);
+ this->audio_fd = -1;
}
-static int ao_is_mode_supported (int mode) {
- return ((mode == AO_MODE_STEREO) || (mode == AO_MODE_MONO));
+static uint32_t ao_get_supported_modes (ao_functions_t *this) {
+ return AO_MODE_STEREO | AO_MODE_MONO;
}
-static char *ao_get_ident(void) {
- return "OSS";
+static void ao_connect (ao_functions_t *this_gen, metronom_t *metronom) {
+ oss_functions_t *this = (oss_functions_t *) this_gen;
+
+ this->metronom = metronom;
}
-static ao_functions_t audio_ossout = {
- AO_OUT_OSS_IFACE_VERSION,
- ao_is_mode_supported,
- ao_open,
- ao_write_audio_data,
- ao_close,
- ao_get_ident
-};
+static void ao_exit(ao_functions_t *this_gen)
+{
+ oss_functions_t *this = (oss_functions_t *) this_gen;
+
+ if (this->audio_fd != -1)
+ close(this->audio_fd);
+ free (this->zero_space);
+ free (this);
+}
-ao_functions_t *init_audio_out_plugin (int iface, config_values_t *config) {
- int caps;
- char devname[] = "/dev/dsp\0\0\0";
- int best_rate;
- int rate ;
- int devnum;
- int audio_fd;
+ao_functions_t *init_audio_out_plugin (config_values_t *config) {
+ oss_functions_t *this;
+ int caps;
+ char devname[] = "/dev/dsp\0\0\0";
+ int best_rate;
+ int rate ;
+ int devnum;
+ int audio_fd;
- /* FIXME: add iface check */
+ this = (oss_functions_t *) malloc (sizeof (oss_functions_t));
/*
* find best device driver/channel
*/
- xprintf (VERBOSE|AUDIO, "Opening audio device...");
+ xprintf (VERBOSE|AUDIO, "audio_oss_out: Opening audio device...");
devnum = 0;
best_rate = 0;
while (devnum<16) {
@@ -412,7 +420,7 @@ ao_functions_t *init_audio_out_plugin (int iface, config_values_t *config) {
rate = 48000;
ioctl(audio_fd,SNDCTL_DSP_SPEED, &rate);
if (rate>best_rate) {
- strncpy (gAudioOSS.audio_dev, devname, 19);
+ strncpy (this->audio_dev, devname, 19);
best_rate = rate;
}
@@ -427,37 +435,60 @@ ao_functions_t *init_audio_out_plugin (int iface, config_values_t *config) {
* open that device
*/
- audio_fd=open(gAudioOSS.audio_dev, O_WRONLY|O_NDELAY);
+ audio_fd=open(this->audio_dev, O_WRONLY|O_NDELAY);
if(audio_fd < 0)
{
- xprintf(VERBOSE|AUDIO, "%s: Opening audio device %s\n",
- strerror(errno), gAudioOSS.audio_dev);
+ xprintf(VERBOSE|AUDIO, "audio_oss_out: %s: Opening audio device %s\n",
+ strerror(errno), this->audio_dev);
+ free (this);
return NULL;
} else
- xprintf (VERBOSE|AUDIO, " %s\n", gAudioOSS.audio_dev);
+ xprintf (VERBOSE|AUDIO, " %s\n", this->audio_dev);
ioctl (audio_fd, SNDCTL_DSP_GETCAPS, &caps);
if ((caps & DSP_CAP_REALTIME) > 0) {
- xprintf (VERBOSE|AUDIO, "audio_out : realtime check: passed :-)\n");
+ xprintf (VERBOSE|AUDIO, "audio_oss_out : realtime check: passed :-)\n");
} else {
- xprintf (VERBOSE|AUDIO, "audio_out : realtime check: *FAILED* :-(((((\n\n");
+ xprintf (VERBOSE|AUDIO, "audio_oss_out : realtime check: *FAILED* :-(((((\n\n");
}
+ /*
if ((caps & DSP_CAP_TRIGGER) > 0) {
xprintf (VERBOSE|AUDIO, "audio_out : trigger check : passed :-)\n");
} else {
xprintf (VERBOSE|AUDIO, "audio_out : trigger check : *FAILED* :-(((((\n");
}
+ */
close (audio_fd);
- gAudioOSS.output_sample_rate = 0;
+ this->output_sample_rate = 0;
+
+ this->zero_space = malloc (8192);
+ memset (this->zero_space, 0, 8192);
+
+ this->ao_functions.get_supported_modes = ao_get_supported_modes;
+ this->ao_functions.connect = ao_connect;
+ this->ao_functions.open = ao_open;
+ this->ao_functions.write_audio_data = ao_write_audio_data;
+ this->ao_functions.close = ao_close;
+ this->ao_functions.exit = ao_exit;
- gAudioOSS.zero_space = xmalloc (8192);
+ return &this->ao_functions;
+}
+
+static ao_info_t ao_info_oss = {
+ AUDIO_OUT_IFACE_VERSION,
+ "oss",
+ "xine audio output plugin using oss-compliant audio devices/drivers",
+ 5
+};
- return &audio_ossout;
+ao_info_t *get_audio_out_plugin_info() {
+ return &ao_info_oss;
}
+
diff --git a/src/libac3/decode.c b/src/libac3/decode.c
index fd004f3fe..5d1fd68b3 100644
--- a/src/libac3/decode.c
+++ b/src/libac3/decode.c
@@ -76,7 +76,7 @@ static int16_t s16_samples[2 * 6 * 256] __attribute__ ((aligned(16)));
/* output buffer for spdiv output */
static int16_t s16_samples_out[4 * 6 * 256] __attribute__ ((aligned(16)));
-static ao_functions_t ac3_output;
+static ao_functions_t *ac3_output;
// downmix stuff
static float cmixlev_lut[4] = { 0.707, 0.595, 0.500, 0.707 };
@@ -168,7 +168,7 @@ void inline decode_mute (void)
void ac3_init(ac3_config_t *config ,ao_functions_t *foo)
{
memcpy(&ac3_config,config,sizeof(ac3_config_t));
- ac3_output = *foo;
+ ac3_output = foo;
imdct_init ();
/* downmix_init (); */
@@ -286,18 +286,18 @@ size_t ac3_decode_data (metronom_t *metronom,
}
if (!is_output_initialized) {
- ac3_output.open (metronom, 16, syncinfo.sampling_rate,
- (ac3_config.flags & AO_MODE_AC3) ? AO_MODE_AC3 : AO_MODE_STEREO);
+ ac3_output->open (ac3_output, 16, syncinfo.sampling_rate,
+ (ac3_config.flags & AO_MODE_AC3) ? AO_MODE_AC3 : AO_MODE_STEREO);
is_output_initialized = 1;
}
if ((ac3_config.flags & AO_MODE_AC3) == 0) {
- ac3_output.write_audio_data(metronom,
- s16_samples, 256*6, pts_);
+ ac3_output->write_audio_data(ac3_output,
+ s16_samples, 256*6, pts_);
}
else {
- ac3_output.write_audio_data(metronom,
- s16_samples_out, 6 * 256, pts_);
+ ac3_output->write_audio_data(ac3_output,
+ s16_samples_out, 6 * 256, pts_);
}
pts_ = 0;
diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c
index 529b6c9a7..b32908e16 100644
--- a/src/video_out/video_out_xv.c
+++ b/src/video_out/video_out_xv.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out_xv.c,v 1.5 2001/04/27 23:51:52 guenter Exp $
+ * $Id: video_out_xv.c,v 1.6 2001/04/28 19:47:42 guenter Exp $
*
* video_out_xv.c, X11 video extension interface for xine
*
@@ -468,8 +468,10 @@ static void xv_setup_window (xv_driver_t *this) {
XFree(wm_hint);
}
+ /* FIXME
wm_delete_window = XInternAtom(this->display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(this->display, this->window, &wm_delete_window, 1);
+ */
/* Map window. */
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index 9b332e72d..98bbc4683 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.h,v 1.2 2001/04/27 10:42:38 f1rmb Exp $
+ * $Id: audio_out.h,v 1.3 2001/04/28 19:47:42 guenter Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -30,90 +30,96 @@
#endif
-#define AUDIO_OUT_PLUGIN_IFACE_VERSION 1
+#define AUDIO_OUT_IFACE_VERSION 1
/*
* audio output modes Used as Bitfield in AC3 decoder
*/
#define AO_MODE_AC3 1
-#define AO_MODE_MONO 2 /* 1 sample == 2 bytes */
-#define AO_MODE_STEREO 4 /* 1 sample == 4 bytes */
-#define AO_MODE_4CHANNEL 8 /* 1 sample == 8 bytes */
-#define AO_MODE_5CHANNEL 16 /* 1 sample == 10 bytes */
+#define AO_MODE_AC5 2
+#define AO_MODE_MONO 4 /* 1 sample == 2 bytes */
+#define AO_MODE_STEREO 8 /* 1 sample == 4 bytes */
+#define AO_MODE_4CHANNEL 16 /* 1 sample == 8 bytes */
+#define AO_MODE_5CHANNEL 32 /* 1 sample == 10 bytes */
-typedef struct ao_functions_s
-{
+/*
+ * ao_functions_s contains the functions every audio output
+ * driver plugin has to implement.
+ */
+
+typedef struct ao_functions_s ao_functions_t;
+
+struct ao_functions_s {
/*
- * plugin interface version, lower versions _may_ be supported
+ * find out what output modes are supported by this plugin
+ * (constants for the bit vector to return see above)
*/
- int interface_version;
+ uint32_t (*get_supported_modes) (ao_functions_t *this);
/*
- * find out if desired output mode is supported by
- * this driver
+ * connect this driver to the xine engine
*/
-
- int (*is_mode_supported) (int mode);
+ void (*connect) (ao_functions_t *this, metronom_t *metronom);
/*
- * init device - buffer will be flushed(!)
+ * open the driver and make it ready to receive audio data
+ * buffers may be flushed(!)
+ *
* return value: <=0 : failure, 1 : ok
*/
- int (*open)(metronom_t *metronom, uint32_t bits, uint32_t rate, int mode);
+ int (*open)(ao_functions_t *this, uint32_t bits, uint32_t rate, int mode);
/*
* write audio data to output buffer - may block
* audio driver must sync sample playback with metronom
*/
- void (*write_audio_data)(metronom_t *metronom,
+ void (*write_audio_data)(ao_functions_t *this,
int16_t* audio_data, uint32_t num_samples,
uint32_t pts);
/*
- * close the audio driver
+ * this is called when the decoder no longer uses the audio
+ * output driver - the driver should get ready to get opened() again
*/
- void (*close)(void);
+ void (*close)(ao_functions_t *this);
/*
- * return human readable identifier for this plugin
+ * shut down this audio output driver plugin and
+ * free all resources allocated
*/
- char* (*get_identifier) (void);
-
-} ao_functions_t;
+ void (*exit) (ao_functions_t *this);
-/*
- * available drivers:
- */
+} ;
-#define AO_DRIVER_UNSET -1
-#define AO_DRIVER_NULL 0
-#define AO_DRIVER_OSS 1
-#if defined(HAVE_ALSA)
-# define AO_DRIVER_ALSA 2
-# if defined(HAVE_ESD)
-# define AO_DRIVER_ESD 3
-# endif
-#else /* no ALSA */
-# if defined(HAVE_ESD)
-# define AO_DRIVER_ESD 2
-# endif
-#endif
/*
- * find right device driver, init it
+ * to build a dynamic audio output plugin,
+ * you have to implement these functions:
+ *
+ *
+ * ao_functions_t *init_audio_out_plugin (config_values_t *config)
+ *
+ * init this plugin, check if device is available
+ *
+ * ao_info_t *get_audio_out_plugin_info ()
+ *
+ * peek at some (static) information about the plugin without initializing it
+ *
*/
-//ao_functions_t *ao_init(char *driver_name) ;
-
-ao_functions_t *init_audio_out_plugin(int iface, config_values_t *cfg);
+typedef struct ao_info_s {
-char *ao_get_available_drivers ();
+ int interface_version;
+ char *id;
+ char *description;
+ int priority;
+} ao_info_t ;
#endif
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index fde565b03..7e35e4f6b 100644
--- a/src/xine-engine/load_plugins.c
+++ b/src/xine-engine/load_plugins.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: load_plugins.c,v 1.11 2001/04/27 23:51:52 guenter Exp $
+ * $Id: load_plugins.c,v 1.12 2001/04/28 19:47:42 guenter Exp $
*
*
* Load input/demux/audio_out/video_out/codec plugins
@@ -458,8 +458,77 @@ vo_driver_t *xine_load_video_output_plugin(config_values_t *config,
return NULL;
}
-ao_functions_t *xine_load_audio_output_plugin(config_values_t *config,
- char *id) {
+char **xine_list_audio_output_plugins() {
+
+ char **plugin_ids;
+ int num_plugins = 0;
+ DIR *dir;
+
+ plugin_ids = xmalloc (50 * sizeof (char *));
+ plugin_ids[0] = NULL;
+
+ dir = opendir (XINE_PLUGINDIR);
+
+ if (dir) {
+ struct dirent *dir_entry;
+
+ while ((dir_entry = readdir (dir)) != NULL) {
+ char str[1024];
+ void *plugin;
+ int nLen = strlen (dir_entry->d_name);
+
+ if ((strncasecmp(dir_entry->d_name,
+ XINE_AUDIO_OUT_PLUGIN_PREFIXNAME,
+ XINE_AUDIO_OUT_PLUGIN_PREFIXNAME_LENGTH) == 0) &&
+ ((dir_entry->d_name[nLen-3]=='.')
+ && (dir_entry->d_name[nLen-2]=='s')
+ && (dir_entry->d_name[nLen-1]=='o'))) {
+
+ sprintf (str, "%s/%s", XINE_PLUGINDIR, dir_entry->d_name);
+
+ /*
+ * now, see if we can open this plugin,
+ * and get it's id
+ */
+
+ if(!(plugin = dlopen (str, RTLD_LAZY))) {
+
+ /* printf("load_plugins: cannot load plugin %s (%s)\n",
+ str, dlerror()); */
+
+ } else {
+
+ ao_info_t* (*getinfo) ();
+ ao_info_t *ao_info;
+
+ if ((getinfo = dlsym(plugin, "get_audio_out_plugin_info")) != NULL) {
+ ao_info = getinfo();
+
+ if ( ao_info->interface_version == AUDIO_OUT_IFACE_VERSION) {
+
+ /* FIXME: sort the list by ao_info->priority */
+
+ plugin_ids[num_plugins] = ao_info->id;
+ num_plugins++;
+ plugin_ids[num_plugins] = NULL;
+ }
+ } else {
+
+ printf("load_plugins: %s seems to be an invalid plugin (lacks get_audio_out_plugin_info() function)\n", str);
+
+ }
+ }
+ }
+ }
+ } else {
+ perror ("load_plugins: get_available_audio_output_plugins - cannot access plugin dir:");
+ }
+
+ return plugin_ids;
+}
+
+ao_functions_t *xine_load_audio_output_plugin(config_values_t *config, char *id) {
+
DIR *dir;
ao_functions_t *aod = NULL;
@@ -486,23 +555,30 @@ ao_functions_t *xine_load_audio_output_plugin(config_values_t *config,
sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name);
if(!(plugin = dlopen (str, RTLD_LAZY))) {
- fprintf(stderr, "%s(%d): %s doesn't seem to be installed (%s)\n",
- __FILE__, __LINE__, str, dlerror());
- exit(1);
- }
- else {
- void *(*initplug) (int, config_values_t *);
+ printf("load_plugins: audio output plugin %s failed to link: %s\n",
+ str, dlerror());
+ return NULL;
+ } else {
+ void *(*initplug) (config_values_t *);
+ ao_info_t* (*getinfo) ();
+ ao_info_t *ao_info;
+
+ if ((getinfo = dlsym(plugin, "get_audio_out_plugin_info")) != NULL) {
+ ao_info = getinfo();
- if((initplug = dlsym(plugin, "init_audio_out_plugin")) != NULL) {
-
- aod = (ao_functions_t *) initplug(AUDIO_OUT_PLUGIN_IFACE_VERSION,
- config);
-
- printf("audio output plugin found : %s(ID: %s, iface: %d)\n",
- str, aod->get_identifier(), aod->interface_version);
+ if (!strcmp(id, ao_info->id)) {
- if(!strcasecmp(id, aod->get_identifier())) {
- return aod;
+ if((initplug = dlsym(plugin, "init_audio_out_plugin")) != NULL) {
+
+ aod = (ao_functions_t *) initplug(config);
+
+ if (aod)
+ printf("load_plugins: audio output plugin %s sucessfully loaded.\n", str);
+ else
+ printf("load_plugins: audio output plugin %s: init_audio_out_plugin failed.\n", str);
+
+ return aod;
+ }
}
}
}
@@ -512,9 +588,3 @@ ao_functions_t *xine_load_audio_output_plugin(config_values_t *config,
return NULL;
}
-char **xine_list_audio_output_plugins() {
-
- printf ("load_plugins: FIXME: list_audio_output_plugins not implemented yet\n");
-
- return NULL;
-}
diff --git a/src/xine-engine/video_out.h b/src/xine-engine/video_out.h
index 864132660..6998a7c26 100644
--- a/src/xine-engine/video_out.h
+++ b/src/xine-engine/video_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.h,v 1.3 2001/04/27 23:51:52 guenter Exp $
+ * $Id: video_out.h,v 1.4 2001/04/28 19:47:42 guenter Exp $
*
*
* xine version of video_out.h
@@ -205,7 +205,7 @@ struct vo_instance_s {
#define VO_CAP_COLORKEY 0x00000100 /* driver can set COLORKEY value */
/*
- * vo_driver_s contains the function every display driver
+ * vo_driver_s contains the functions every display driver
* has to implement. The vo_new_instance function (see below)
* should then be used to construct a vo_instance using this
* driver. Some of the function pointers will be copied
@@ -266,25 +266,26 @@ vo_instance_t *vo_new_instance (vo_driver_t *driver, metronom_t *metronom) ;
* you have to implement these functions:
*
*
- * init_video_out_plugin init and set up driver so it is fully operational
+ * vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual);
+ *
+ * init and set up driver so it is fully operational
*
* parameters: config - config object pointer
* visual - driver specific info (e.g. Display*)
*
* return value: video_driver_t* in case of success,
- * NULL on failure (e.g. wrong interface version, wrong visual type...)
+ * NULL on failure (e.g. wrong interface version,
+ * wrong visual type...)
*
- * vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual);
*
*
- * get_video_out_plugin_info
+ * vo_info_t *get_video_out_plugin_info ();
*
* peek at some (static) information about the plugin without initializing it
*
* parameters: none
*
* return value: vo_info_t* : some information about the plugin
- * vo_info_t *get_video_out_plugin_info ();
*/
typedef struct vo_info_s {
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 70f9bf8f2..32b40a33a 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine.c,v 1.7 2001/04/24 21:10:42 guenter Exp $
+ * $Id: xine.c,v 1.8 2001/04/28 19:47:42 guenter Exp $
*
* top-level xine functions
*
@@ -96,7 +96,7 @@ void xine_stop (xine_t *this) {
this->spu_fifo->clear(this->spu_fifo);
if (this->audio_out)
- this->audio_out->close ();
+ this->audio_out->close (this->audio_out);
this->metronom->reset(this->metronom);
this->metronom->stop_clock (this->metronom);
@@ -438,6 +438,7 @@ xine_t *xine_init (vo_driver_t *vo,
video_decoder_init (this);
this->audio_out = ao;
+ this->audio_out->connect (this->audio_out, this->metronom);
audio_decoder_init (this);
/*