summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_out/audio_oss_out.c164
-rw-r--r--src/audio_out/resample.c149
-rw-r--r--src/libac3/ac3.h6
-rw-r--r--src/libac3/decode.c35
-rw-r--r--src/libac3/downmix.c255
-rw-r--r--src/libac3/downmix.h3
-rw-r--r--src/libac3/xine_decoder.c121
-rw-r--r--src/libmpeg2/decode.c3
-rw-r--r--src/libmpg123/Makefile.am37
-rw-r--r--src/libmpg123/interface.c30
-rw-r--r--src/libmpg123/layer1.c8
-rw-r--r--src/libmpg123/layer2.c10
-rw-r--r--src/libmpg123/layer3.c10
-rw-r--r--src/libmpg123/mpg123.h6
-rw-r--r--src/libmpg123/mpglib.h10
-rw-r--r--src/libmpg123/xine_decoder.c106
-rw-r--r--src/xine-engine/Makefile.am1
-rw-r--r--src/xine-engine/load_plugins.c37
-rw-r--r--src/xine-engine/metronom.c20
-rw-r--r--src/xine-engine/video_out.c3
20 files changed, 842 insertions, 172 deletions
diff --git a/src/audio_out/audio_oss_out.c b/src/audio_out/audio_oss_out.c
index 0bb47ffbb..e8a9eacca 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.6 2001/05/08 11:31:39 f1rmb Exp $
+ * $Id: audio_oss_out.c,v 1.7 2001/05/27 23:48:12 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -60,6 +60,10 @@
# endif
#endif
+#ifndef AFMT_AC3
+# define AFMT_AC3 0x00000400 /* Dolby Digital AC3 */
+#endif
+
#define AO_OUT_OSS_IFACE_VERSION 1
#define AUDIO_NUM_FRAGMENTS 15
@@ -82,6 +86,8 @@ typedef struct oss_functions_s {
char audio_dev[20];
int audio_fd;
+ int capabilities;
+ int mode;
int32_t output_sample_rate, input_sample_rate;
int32_t output_rate_correction;
@@ -111,23 +117,23 @@ static int ao_open(ao_functions_t *this_gen,
{
oss_functions_t *this = (oss_functions_t *) this_gen;
int tmp;
- int fsize;
printf ("audio_oss_out: ao_open rate=%d, mode=%d\n", rate, mode);
- if (((mode & AO_CAP_MODE_STEREO) == 0) && ((mode & AO_CAP_MODE_MONO) == 0)) {
- printf ("OSS Driver only supports mono/stereo output modes at the moment\n");
+ if ( (mode & this->capabilities) == 0 ) {
+ printf ("audio_oss_out: unsupported mode %08x\n", mode);
return -1;
}
if (this->audio_fd > -1) {
- if (rate == this->input_sample_rate)
+ if ( (mode == this->mode) && (rate == this->input_sample_rate) )
return 1;
close (this->audio_fd);
}
-
+
+ this->mode = mode;
this->input_sample_rate = rate;
this->bytes_in_buffer = 0;
this->last_vpts = 0;
@@ -157,8 +163,6 @@ static int ao_open(ao_functions_t *this_gen,
tmp = (mode & AO_CAP_MODE_STEREO) ? 1 : 0;
ioctl(this->audio_fd,SNDCTL_DSP_STEREO,&tmp);
- this->num_channels = tmp+1;
- xprintf (VERBOSE|AUDIO, "audio_oss_out: %d channels\n",this->num_channels);
tmp = bits;
ioctl(this->audio_fd,SNDCTL_DSP_SAMPLESIZE,&tmp);
@@ -170,12 +174,47 @@ static int ao_open(ao_functions_t *this_gen,
xprintf (VERBOSE|AUDIO, "audio_oss_out: audio rate : %d requested, %d provided by device/sec\n",
this->input_sample_rate, this->output_sample_rate);
+ /*
+ * set number of channels / ac3 throughput
+ */
+
+ switch (mode) {
+ case AO_CAP_MODE_MONO:
+ tmp = 1;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
+ break;
+ case AO_CAP_MODE_STEREO:
+ tmp = 2;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ tmp = 4;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
+ break;
+ case AO_CAP_MODE_5CHANNEL:
+ tmp = 5;
+ ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp);
+ this->num_channels = tmp;
+ break;
+ case AO_CAP_MODE_AC3:
+ tmp = AFMT_AC3;
+ ioctl(this->audio_fd,SNDCTL_DSP_SETFMT,&tmp);
+ this->num_channels = 2; /* FIXME: is this correct ? */
+ break;
+ }
+
+ printf ("audio_oss_out : %d channels output\n",this->num_channels);
+
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", this->audio_step);
+ printf ("audio_out : audio_step %d pts per 32768 samples\n", this->audio_step);
this->metronom->set_audio_rate(this->metronom, this->audio_step);
@@ -183,6 +222,7 @@ static int ao_open(ao_functions_t *this_gen,
* audio buffer size handling
*/
+ /* WARNING: let's hope for good defaults here...
tmp=0 ;
fsize = AUDIO_FRAGMENT_SIZE;
while (fsize>0) {
@@ -196,7 +236,7 @@ static int ao_open(ao_functions_t *this_gen,
xprintf (VERBOSE|AUDIO, "Audio buffer fragment info : %x\n",tmp);
ioctl(this->audio_fd,SNDCTL_DSP_SETFRAGMENT,&tmp);
-
+ */
return 1;
}
@@ -231,7 +271,7 @@ static void ao_fill_gap (oss_functions_t *this, uint32_t pts_len) {
int num_bytes = pts_len * this->bytes_per_kpts / 1024;
- num_bytes = (num_bytes / 4) * 4;
+ num_bytes = (num_bytes / (2*this->num_channels)) * (2*this->num_channels);
printf ("audio_oss_out: inserting %d 0-bytes to fill a gap of %d pts\n",num_bytes, pts_len);
@@ -263,11 +303,11 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
int bDropPackage;
uint16_t sample_buffer[8192];
-
+
if (this->audio_fd<0)
return;
- vpts = this->metronom->got_audio_samples (this->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, this->last_vpts);
@@ -306,6 +346,7 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
printf ("audio_oss_out: audio_vpts=%d <=> master_vpts=%d (diff=%d)\n",
audio_vpts, master_vpts, diff);
*/
+
/*
* method 1 : resampling
*/
@@ -349,11 +390,34 @@ static void ao_write_audio_data(ao_functions_t *this_gen,
if (!bDropPackage) {
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,
+ switch (this->mode) {
+ case AO_CAP_MODE_MONO:
+ audio_out_resample_mono (output_samples, num_samples,
sample_buffer, num_output_samples);
-
- write(this->audio_fd, sample_buffer, num_output_samples * 2 * this->num_channels);
+ write(this->audio_fd, sample_buffer, num_output_samples * 2);
+ break;
+ case AO_CAP_MODE_STEREO:
+ audio_out_resample_stereo (output_samples, num_samples,
+ sample_buffer, num_output_samples);
+ write(this->audio_fd, sample_buffer, num_output_samples * 4);
+ break;
+ case AO_CAP_MODE_4CHANNEL:
+ audio_out_resample_4channel (output_samples, num_samples,
+ sample_buffer, num_output_samples);
+ write(this->audio_fd, sample_buffer, num_output_samples * 8);
+ break;
+ case AO_CAP_MODE_5CHANNEL:
+ audio_out_resample_5channel (output_samples, num_samples,
+ sample_buffer, num_output_samples);
+ write(this->audio_fd, sample_buffer, num_output_samples * 10);
+ break;
+ case AO_CAP_MODE_AC3:
+
+ write(this->audio_fd, sample_buffer, num_output_samples * 2);
+ num_output_samples = num_samples;
+
+ break;
+ }
xprintf (AUDIO|VERBOSE, "audio_oss_out :audio package written\n");
@@ -386,8 +450,9 @@ static void ao_close(ao_functions_t *this_gen)
this->audio_fd = -1;
}
-static uint32_t ao_get_capabilities (ao_functions_t *this) {
- return AO_CAP_MODE_STEREO | AO_CAP_MODE_MONO;
+static uint32_t ao_get_capabilities (ao_functions_t *this_gen) {
+ oss_functions_t *this = (oss_functions_t *) this_gen;
+ return this->capabilities;
}
static void ao_connect (ao_functions_t *this_gen, metronom_t *metronom) {
@@ -457,6 +522,7 @@ ao_functions_t *init_audio_out_plugin (config_values_t *config) {
int rate ;
int devnum;
int audio_fd;
+ int num_channels, status, arg;
this = (oss_functions_t *) malloc (sizeof (oss_functions_t));
@@ -505,6 +571,19 @@ ao_functions_t *init_audio_out_plugin (config_values_t *config) {
} else
xprintf (VERBOSE|AUDIO, " %s\n", this->audio_dev);
+ /*
+ * set up driver to reasonable values for capabilities tests
+ */
+
+ arg = AFMT_S16_NE;
+ status = ioctl(audio_fd, SOUND_PCM_SETFMT, &arg);
+ arg = 44100;
+ status = ioctl(audio_fd, SOUND_PCM_WRITE_RATE, &arg);
+
+ /*
+ * get capabilities
+ */
+
ioctl (audio_fd, SNDCTL_DSP_GETCAPS, &caps);
if ((caps & DSP_CAP_REALTIME) > 0) {
@@ -513,13 +592,50 @@ ao_functions_t *init_audio_out_plugin (config_values_t *config) {
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");
+ this->capabilities = 0;
+
+ printf ("audio_oss_out : supported modes are ");
+ num_channels = 1;
+ status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
+ if ( (status != -1) && (num_channels==1) ) {
+ this->capabilities |= AO_CAP_MODE_MONO;
+ printf ("mono ");
}
- */
+ num_channels = 2;
+ status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
+ if ( (status != -1) && (num_channels==2) ) {
+ this->capabilities |= AO_CAP_MODE_STEREO;
+ printf ("stereo ");
+ }
+ num_channels = 4;
+ status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
+ if ( (status != -1) && (num_channels==4) ) {
+ if (config->lookup_int (config, "four_channel", 0)) {
+ this->capabilities |= AO_CAP_MODE_4CHANNEL;
+ printf ("4-channel ");
+ } else
+ printf ("(4-channel not enabled in .xinerc) " );
+ }
+ num_channels = 5;
+ status = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &num_channels);
+ if ( (status != -1) && (num_channels==5) ) {
+ if (config->lookup_int (config, "five_channel", 0)) {
+ this->capabilities |= AO_CAP_MODE_5CHANNEL;
+ printf ("5-channel ");
+ } else
+ printf ("(5-channel not enabled in .xinerc) " );
+ }
+
+ ioctl(audio_fd,SNDCTL_DSP_GETFMTS,&caps);
+ if (caps & AFMT_AC3) {
+ if (config->lookup_int (config, "ac3_pass_through", 0)) {
+ this->capabilities |= AO_CAP_MODE_AC3;
+ printf ("ac3-pass-through ");
+ } else
+ printf ("(ac3-pass-through not enabled in .xinerc)");
+ }
+
+ printf ("\n");
close (audio_fd);
diff --git a/src/audio_out/resample.c b/src/audio_out/resample.c
index 9f464b276..158b17c59 100644
--- a/src/audio_out/resample.c
+++ b/src/audio_out/resample.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: resample.c,v 1.1 2001/04/24 20:53:00 f1rmb Exp $
+ * $Id: resample.c,v 1.2 2001/05/27 23:48:12 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -28,6 +28,37 @@
/* contributed by paul flinders */
+void audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples,
+ int16_t* output_samples, uint32_t out_samples)
+{
+ int osample;
+ /* 16+16 fixed point math */
+ uint32_t isample = 0;
+ uint32_t istep = (in_samples << 16)/out_samples;
+
+#ifdef VERBOSE
+ printf ("Audio : resample %d samples to %d\n",
+ in_samples, out_samples);
+#endif
+
+ for (osample = 0; osample < out_samples - 1; osample++) {
+ int s1;
+ int s2;
+ int16_t os;
+ uint32_t t = isample&0xffff;
+
+ /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */
+ s1 = input_samples[(isample >> 16)];
+ s2 = input_samples[(isample >> 16)+1];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[osample] = os;
+
+ isample += istep;
+ }
+ output_samples[out_samples-1] = input_samples[in_samples-1];
+}
+
void audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples,
int16_t* output_samples, uint32_t out_samples)
{
@@ -65,3 +96,119 @@ void audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples,
output_samples[out_samples*2-1] = input_samples[in_samples*2-1];
}
+
+void audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples,
+ int16_t* output_samples, uint32_t out_samples)
+{
+ int osample;
+ /* 16+16 fixed point math */
+ uint32_t isample = 0;
+ uint32_t istep = (in_samples << 16)/out_samples;
+
+#ifdef VERBOSE
+ printf ("Audio : resample %d samples to %d\n",
+ in_samples, out_samples);
+#endif
+
+ for (osample = 0; osample < out_samples - 1; osample++) {
+ int s1;
+ int s2;
+ int16_t os;
+ uint32_t t = isample&0xffff;
+
+ /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */
+ s1 = input_samples[(isample >> 16)*4];
+ s2 = input_samples[(isample >> 16)*4+4];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[osample * 4] = os;
+
+ s1 = input_samples[(isample >> 16)*4+1];
+ s2 = input_samples[(isample >> 16)*4+5];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[(osample * 4 )+1] = os;
+
+ s1 = input_samples[(isample >> 16)*4+2];
+ s2 = input_samples[(isample >> 16)*4+6];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[(osample * 4 )+2] = os;
+
+ s1 = input_samples[(isample >> 16)*4+3];
+ s2 = input_samples[(isample >> 16)*4+7];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[(osample * 4 )+3] = os;
+
+ isample += istep;
+ }
+ output_samples[out_samples*4-4] = input_samples[in_samples*4-4];
+ output_samples[out_samples*4-3] = input_samples[in_samples*4-3];
+ output_samples[out_samples*4-2] = input_samples[in_samples*4-2];
+ output_samples[out_samples*4-1] = input_samples[in_samples*4-1];
+
+}
+
+
+void audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples,
+ int16_t* output_samples, uint32_t out_samples)
+{
+ int osample;
+ /* 16+16 fixed point math */
+ uint32_t isample = 0;
+ uint32_t istep = (in_samples << 16)/out_samples;
+
+#ifdef VERBOSE
+ printf ("Audio : resample %d samples to %d\n",
+ in_samples, out_samples);
+#endif
+
+ for (osample = 0; osample < out_samples - 1; osample++) {
+ int s1;
+ int s2;
+ int16_t os;
+ uint32_t t = isample&0xffff;
+
+ /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */
+ s1 = input_samples[(isample >> 16)*5];
+ s2 = input_samples[(isample >> 16)*5+5];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[osample * 5] = os;
+
+ s1 = input_samples[(isample >> 16)*5+1];
+ s2 = input_samples[(isample >> 16)*5+6];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[(osample * 5 )+1] = os;
+
+ s1 = input_samples[(isample >> 16)*5+2];
+ s2 = input_samples[(isample >> 16)*5+7];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[(osample * 5 )+2] = os;
+
+ s1 = input_samples[(isample >> 16)*5+3];
+ s2 = input_samples[(isample >> 16)*5+8];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[(osample * 5 )+3] = os;
+
+ s1 = input_samples[(isample >> 16)*5+4];
+ s2 = input_samples[(isample >> 16)*5+9];
+
+ os = (s1 * (0x10000-t)+ s2 * t) >> 16;
+ output_samples[(osample * 5 )+4] = os;
+
+ isample += istep;
+ }
+
+ output_samples[out_samples*5-5] = input_samples[in_samples*5-5];
+ output_samples[out_samples*5-4] = input_samples[in_samples*5-4];
+ output_samples[out_samples*5-3] = input_samples[in_samples*5-3];
+ output_samples[out_samples*5-2] = input_samples[in_samples*5-2];
+ output_samples[out_samples*5-1] = input_samples[in_samples*5-1];
+}
+
+
diff --git a/src/libac3/ac3.h b/src/libac3/ac3.h
index 07f41c0a0..69c11b9ed 100644
--- a/src/libac3/ac3.h
+++ b/src/libac3/ac3.h
@@ -40,10 +40,12 @@ typedef struct ac3_config_s
typedef struct ac3_frame_s
{
- uint32_t sampling_rate;
+ uint32_t sampling_rate;
int16_t * audio_data;
+ int num_channels;
} ac3_frame_t;
void ac3_init(void);
int ac3_frame_length(uint8_t * buf);
-ac3_frame_t* ac3_decode_frame(uint8_t * buf);
+int ac3_sampling_rate(uint8_t * buf);
+ac3_frame_t* ac3_decode_frame(uint8_t * buf, int max_num_channels);
diff --git a/src/libac3/decode.c b/src/libac3/decode.c
index db0068b8d..c859525e8 100644
--- a/src/libac3/decode.c
+++ b/src/libac3/decode.c
@@ -53,9 +53,9 @@ static ac3_frame_t frame;
//the floating point samples for one audblk
static stream_samples_t samples;
-//the integer samples for the entire frame (with enough space for 2 ch out)
+//the integer samples for the entire frame (with enough space for 5 ch out)
//if this size change, be sure to change the size when muting
-static int16_t s16_samples[2 * 6 * 256];
+static int16_t s16_samples[5 * 6 * 256];
void
ac3_init(void)
@@ -73,11 +73,20 @@ int ac3_frame_length(uint8_t * buf)
return parse_syncinfo (buf, &dummy, &dummy);
}
+int ac3_sampling_rate(uint8_t * buf)
+{
+ int dummy, rate;
+
+ parse_syncinfo (buf, &rate, &dummy);
+ return rate;
+}
+
ac3_frame_t*
-ac3_decode_frame(uint8_t * buf)
+ac3_decode_frame(uint8_t * buf, int max_num_channels)
{
uint32_t i;
int dummy;
+ int num_channels;
if (!parse_syncinfo (buf, &frame.sampling_rate, &dummy))
goto error;
@@ -87,6 +96,22 @@ ac3_decode_frame(uint8_t * buf)
if (parse_bsi (&state, buf))
goto error;
+ switch (state.acmod) {
+ case 7 :
+ case 5 :
+ /* case 3 : FIXME : implement downmix functions*/
+ num_channels = (max_num_channels<5) ? max_num_channels : 5;
+ break;
+ case 4 :
+ case 6 :
+ num_channels = (max_num_channels<4) ? max_num_channels : 4;
+ break;
+ default:
+ num_channels = 2;
+ }
+
+ frame.num_channels = num_channels;
+
if (!done_banner) {
stats_print_banner (&state);
done_banner = 1;
@@ -118,13 +143,15 @@ ac3_decode_frame(uint8_t * buf)
// Downmix into the requested number of channels
// and convert floating point to int16_t
- downmix(&state,samples,&s16_samples[i * 2 * 256]);
+ downmix(&state,samples,&s16_samples[i * num_channels * 256],
+ num_channels);
sanity_check(&state,&audblk);
if(error_flag)
goto error;
}
+
return &frame;
error:
diff --git a/src/libac3/downmix.c b/src/libac3/downmix.c
index a50b045be..fd801308d 100644
--- a/src/libac3/downmix.c
+++ b/src/libac3/downmix.c
@@ -42,6 +42,54 @@ static float cmixlev_lut[4] = { 0.2928, 0.2468, 0.2071, 0.2468 };
static float smixlev_lut[4] = { 0.2928, 0.2071, 0.0 , 0.2071 };
static void
+downmix_3f_2r_to_5ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+{
+ uint32_t j;
+ float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
+
+ left = samples[0];
+ centre = samples[1];
+ right = samples[2];
+ left_sur = samples[3];
+ right_sur = samples[4];
+
+ for (j = 0; j < 256; j++)
+ {
+ s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f);
+ s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f);
+ s16_samples[j * 5 + 2] = (int16_t) (*left_sur++ * 32767.0f);
+ s16_samples[j * 5 + 3] = (int16_t) (*right_sur++ * 32767.0f);
+ s16_samples[j * 5 + 4] = (int16_t) (*centre++ * 32767.0f);
+ }
+}
+
+static void
+downmix_3f_2r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+{
+ uint32_t j;
+ float right_tmp;
+ float left_tmp;
+ float *centre = 0, *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
+
+ left = samples[0];
+ centre = samples[1];
+ right = samples[2];
+ left_sur = samples[3];
+ right_sur = samples[4];
+
+ for (j = 0; j < 256; j++)
+ {
+ left_tmp = 0.5000f * *left++ + 0.500f * *centre ;
+ right_tmp= 0.5000f * *right++ + 0.500f * *centre++ ;
+
+ s16_samples[j * 4 ] = (int16_t) (left_tmp * 32767.0f);
+ s16_samples[j * 4 + 1] = (int16_t) (right_tmp * 32767.0f);
+ s16_samples[j * 4 + 2] = (int16_t) (*left_sur++ * 32767.0f);
+ s16_samples[j * 4 + 3] = (int16_t) (*right_sur++ * 32767.0f);
+ }
+}
+
+static void
downmix_3f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
{
uint32_t j;
@@ -70,6 +118,29 @@ downmix_3f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_
}
static void
+downmix_2f_2r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+{
+ uint32_t j;
+ float slev;
+ float *left = 0, *right = 0, *left_sur = 0, *right_sur = 0;
+
+ left = samples[0];
+ right = samples[1];
+ left_sur = samples[2];
+ right_sur = samples[3];
+
+ slev = smixlev_lut[state->surmixlev];
+
+ for (j = 0; j < 256; j++)
+ {
+ s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f);
+ s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f);
+ s16_samples[j * 5 + 2] = (int16_t) (*left_sur++ * 32767.0f);
+ s16_samples[j * 5 + 3] = (int16_t) (*right_sur++ * 32767.0f);
+ }
+}
+
+static void
downmix_2f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
{
uint32_t j;
@@ -96,6 +167,58 @@ downmix_2f_2r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_
}
static void
+downmix_3f_1r_to_5ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+{
+ uint32_t j;
+ float *centre = 0, *left = 0, *right = 0, *sur = 0;
+
+ left = samples[0];
+ centre = samples[1];
+ right = samples[2];
+ //Mono surround
+ sur = samples[3];
+
+ for (j = 0; j < 256; j++)
+ {
+ s16_samples[j * 5 ] = (int16_t) (*left++ * 32767.0f);
+ s16_samples[j * 5 + 1] = (int16_t) (*right++ * 32767.0f);
+ s16_samples[j * 5 + 2] = (int16_t) (*sur * 32767.0f);
+ s16_samples[j * 5 + 3] = (int16_t) (*sur++ * 32767.0f);
+ s16_samples[j * 5 + 4] = (int16_t) (*centre++ * 32767.0f);
+ }
+}
+
+static void
+downmix_3f_1r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+{
+ uint32_t j;
+ float right_tmp;
+ float left_tmp;
+ float clev,slev;
+ float *centre = 0, *left = 0, *right = 0, *sur = 0;
+
+ left = samples[0];
+ centre = samples[1];
+ right = samples[2];
+ //Mono surround
+ sur = samples[3];
+
+ clev = cmixlev_lut[state->cmixlev];
+ slev = smixlev_lut[state->surmixlev];
+
+ for (j = 0; j < 256; j++)
+ {
+ left_tmp = 0.5000f * *left++ + 0.500f * *centre ;
+ right_tmp= 0.5000f * *right++ + 0.500f * *centre++ ;
+
+ s16_samples[j * 4 ] = (int16_t) (left_tmp * 32767.0f);
+ s16_samples[j * 4 + 1] = (int16_t) (right_tmp * 32767.0f);
+ s16_samples[j * 4 + 2] = (int16_t) (*sur * 32767.0f);
+ s16_samples[j * 4 + 3] = (int16_t) (*sur++ * 32767.0f);
+ }
+}
+
+static void
downmix_3f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
{
uint32_t j;
@@ -125,6 +248,26 @@ downmix_3f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_
static void
+downmix_2f_1r_to_4ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+{
+ uint32_t j;
+ float *left = 0, *right = 0, *sur = 0;
+
+ left = samples[0];
+ right = samples[1];
+ //Mono surround
+ sur = samples[2];
+
+ for (j = 0; j < 256; j++)
+ {
+ s16_samples[j * 4 ] = (int16_t) (*left++ * 32767.0f);
+ s16_samples[j * 4 + 1] = (int16_t) (*right++ * 32767.0f);
+ s16_samples[j * 4 + 2] = (int16_t) (*sur * 32767.0f);
+ s16_samples[j * 4 + 3] = (int16_t) (*sur++ * 32767.0f);
+ }
+}
+
+static void
downmix_2f_1r_to_2ch(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
{
uint32_t j;
@@ -208,19 +351,19 @@ downmix_1f_0r_to_2ch(float *centre,int16_t *s16_samples)
}
//
-// Downmix into 2 or 4 channels (4 ch isn't in quite yet)
+// Downmix into 2 or 4 or 5 channels (4 ch isn't in quite yet)
//
// The downmix function names have the following format
//
-// downmix_Xf_Yr_to_[2|4]ch[_dolby]
+// downmix_Xf_Yr_to_[2|4|5]ch[_dolby]
//
// where X = number of front channels
// Y = number of rear channels
-// [2|4] = number of output channels
+// [2|4|5] = number of output channels
// [_dolby] = with or without dolby surround mix
//
-void downmix(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
+void downmix(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples, int num_channels)
{
if(state->acmod > 7)
dprintf("(downmix) invalid acmod number\n");
@@ -239,46 +382,74 @@ void downmix(ac3_state_t * state, stream_samples_t samples,int16_t *s16_samples)
//Non-Dolby surround downmixes
switch(state->acmod)
{
- // 3/2
- case 7:
- downmix_3f_2r_to_2ch(state, samples,s16_samples);
- break;
-
- // 2/2
- case 6:
- downmix_2f_2r_to_2ch(state, samples,s16_samples);
- break;
-
- // 3/1
- case 5:
- downmix_3f_1r_to_2ch(state, samples,s16_samples);
- break;
-
- // 2/1
- case 4:
- downmix_2f_1r_to_2ch(state, samples,s16_samples);
- break;
-
- // 3/0
- case 3:
- downmix_3f_0r_to_2ch(state, samples,s16_samples);
- break;
-
- case 2:
- downmix_2f_0r_to_2ch(state, samples,s16_samples);
- break;
-
- // 1/0
- case 1:
- downmix_1f_0r_to_2ch(samples[0],s16_samples);
- break;
-
- // 1+1
- case 0:
+ // 3/2
+ case 7:
+ switch (num_channels) {
+ case 5:
+ downmix_3f_2r_to_5ch(state, samples,s16_samples);
+ break;
+ case 4:
+ downmix_3f_2r_to_4ch(state, samples,s16_samples);
+ break;
+ case 2:
+ downmix_3f_2r_to_2ch(state, samples,s16_samples);
+ break;
+ }
+ break;
+
+ // 2/2
+ case 6:
+ if (num_channels == 4)
+ downmix_2f_2r_to_4ch(state, samples,s16_samples);
+ else
+ downmix_2f_2r_to_2ch(state, samples,s16_samples);
+ break;
+
+ // 3/1
+ case 5:
+
+ switch (num_channels) {
+ case 5:
+ downmix_3f_1r_to_5ch(state, samples,s16_samples);
+ break;
+ case 4:
+ downmix_3f_1r_to_4ch(state, samples,s16_samples);
+ break;
+ case 2:
+ downmix_3f_1r_to_2ch(state, samples,s16_samples);
+ break;
+ }
+
+ break;
+
+ // 2/1
+ case 4:
+ if (num_channels == 4)
+ downmix_2f_1r_to_4ch(state, samples,s16_samples);
+ else
+ downmix_2f_1r_to_2ch(state, samples,s16_samples);
+ break;
+
+ // 3/0
+ case 3:
+ downmix_3f_0r_to_2ch(state, samples,s16_samples);
+ break;
+
+ case 2:
+ downmix_2f_0r_to_2ch(state, samples,s16_samples);
+ break;
+
+ // 1/0
+ case 1:
+ downmix_1f_0r_to_2ch(samples[0],s16_samples);
+ break;
+
+ // 1+1
+ case 0:
#if 0
- downmix_1f_0r_to_2ch(samples[ac3_config.dual_mono_ch_sel],s16_samples);
+ downmix_1f_0r_to_2ch(samples[ac3_config.dual_mono_ch_sel],s16_samples);
#endif
- break;
+ break;
}
}
diff --git a/src/libac3/downmix.h b/src/libac3/downmix.h
index 525980afb..28c6aea15 100644
--- a/src/libac3/downmix.h
+++ b/src/libac3/downmix.h
@@ -25,4 +25,5 @@
*
*/
-void downmix(ac3_state_t * state, stream_samples_t stream_samples,int16_t *s16_samples);
+void downmix(ac3_state_t * state, stream_samples_t stream_samples,int16_t *s16_samples,
+ int num_channels);
diff --git a/src/libac3/xine_decoder.c b/src/libac3/xine_decoder.c
index b11987299..5b9ab7ef6 100644
--- a/src/libac3/xine_decoder.c
+++ b/src/libac3/xine_decoder.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_decoder.c,v 1.2 2001/05/26 15:07:18 guenter Exp $
+ * $Id: xine_decoder.c,v 1.3 2001/05/27 23:48:12 guenter Exp $
*
* stuff needed to turn libac3 into a xine decoder plugin
*/
@@ -48,8 +48,12 @@ typedef struct ac3dec_decoder_s {
uint16_t syncword;
ao_functions_t *audio_out;
+ int audio_caps;
+ int bypass_mode;
+ int max_num_channels;
int output_sampling_rate;
int output_open;
+ int output_mode;
} ac3dec_decoder_t;
@@ -62,11 +66,36 @@ void ac3dec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) {
ac3dec_decoder_t *this = (ac3dec_decoder_t *) this_gen;
- this->audio_out = audio_out;
- ac3_init ();
+ this->audio_out = audio_out;
+ this->audio_caps = audio_out->get_capabilities(audio_out);
this->syncword = 0;
this->sync_todo = 6;
this->output_open = 0;
+
+ ac3_init ();
+
+ /*
+ * find out if this driver supports ac3 output
+ * or, if not, how many channels we've got
+ */
+
+ if (this->audio_caps & AO_CAP_MODE_AC3)
+ this->bypass_mode = 1;
+ else {
+ this->bypass_mode = 0;
+
+ /* find best mode */
+ if (this->audio_caps & AO_CAP_MODE_5CHANNEL)
+ this->max_num_channels = 5;
+ else if (this->audio_caps & AO_CAP_MODE_4CHANNEL)
+ this->max_num_channels = 4;
+ else if (this->audio_caps & AO_CAP_MODE_STEREO)
+ this->max_num_channels = 2;
+ else {
+ printf ("HELP! a mono-only audio driver?!\n");
+ this->max_num_channels = 1;
+ }
+ }
}
void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
@@ -77,6 +106,7 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
uint8_t *end = buf->content + buf->size;
ac3_frame_t *ac3_frame;
int sampling_rate;
+ int output_mode;
uint8_t byte;
@@ -125,30 +155,79 @@ void ac3dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
return ;
}
- /* now, decode this frame */
+ /*
+ * do we want to decode this frame in software?
+ */
- ac3_frame = ac3_decode_frame (this->frame_buffer);
+ if (!this->bypass_mode) {
+
+ /* oki, decode this frame in software*/
+
+ ac3_frame = ac3_decode_frame (this->frame_buffer, this->max_num_channels);
+
+ /* determine output mode */
+ switch (ac3_frame->num_channels) {
+ case 1:
+ output_mode = AO_CAP_MODE_MONO;
+ break;
+ case 2:
+ output_mode = AO_CAP_MODE_STEREO;
+ break;
+ case 4:
+ output_mode = AO_CAP_MODE_4CHANNEL;
+ break;
+ case 5:
+ output_mode = AO_CAP_MODE_5CHANNEL;
+ break;
+ }
- /* output audio */
+ /* output decoded samples */
- if (!this->output_open
- || (ac3_frame->sampling_rate != this->output_sampling_rate) ) {
+ if (!this->output_open
+ || (ac3_frame->sampling_rate != this->output_sampling_rate)
+ || (output_mode != this->output_mode)) {
- if (this->output_open)
- this->audio_out->close (this->audio_out);
+ if (this->output_open)
+ this->audio_out->close (this->audio_out);
+
+
+ this->output_open = (this->audio_out->open (this->audio_out, 16,
+ ac3_frame->sampling_rate,
+ output_mode) == 1);
+ this->output_sampling_rate = ac3_frame->sampling_rate;
+ this->output_mode = output_mode;
+ }
+
+ if (this->output_open) {
+ this->audio_out->write_audio_data (this->audio_out,
+ ac3_frame->audio_data,
+ 256*6,
+ this->pts);
+ this->pts = 0;
+ }
+ } else {
+
+ /*
+ * loop through ac3 data
+ */
+
+ if (!this->output_open) {
+ this->output_open = (this->audio_out->open (this->audio_out, 16,
+ ac3_sampling_rate(this->frame_buffer),
+ AO_CAP_MODE_AC3) == 1);
+ this->output_mode - AO_CAP_MODE_AC3;
+ }
+
+
+ if (this->output_open) {
+ this->audio_out->write_audio_data (this->audio_out,
+ this->frame_buffer,
+ this->frame_length,
+ this->pts);
+ this->pts = 0;
+ }
- this->output_open = (this->audio_out->open (this->audio_out, 16,
- ac3_frame->sampling_rate,
- AO_CAP_MODE_STEREO) == 1);
- this->output_sampling_rate = ac3_frame->sampling_rate;
- }
- if (this->output_open) {
- this->audio_out->write_audio_data (this->audio_out,
- ac3_frame->audio_data,
- 256*6,
- this->pts);
- this->pts = 0;
}
/* done with frame, prepare for next one */
diff --git a/src/libmpeg2/decode.c b/src/libmpeg2/decode.c
index 044f235f3..847227ebb 100644
--- a/src/libmpeg2/decode.c
+++ b/src/libmpeg2/decode.c
@@ -93,6 +93,8 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
picture->current_frame->bFrameBad = mpeg2dec->drop_frame;
if (picture->picture_coding_type == B_TYPE) {
+ if (picture->mpeg1)
+ picture->current_frame->PTS = 0;
mpeg2dec->frames_to_drop = picture->current_frame->draw (picture->current_frame);
picture->current_frame->free (picture->current_frame);
picture->current_frame = NULL;
@@ -223,6 +225,7 @@ static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code,
}
picture->current_frame->PTS = mpeg2dec->pts;
mpeg2dec->pts = 0;
+
}
}
diff --git a/src/libmpg123/Makefile.am b/src/libmpg123/Makefile.am
index 854b992b1..04238af92 100644
--- a/src/libmpg123/Makefile.am
+++ b/src/libmpg123/Makefile.am
@@ -1,16 +1,41 @@
-CFLAGS = @BUILD_LIB_STATIC@ @GLOBAL_CFLAGS@
+CFLAGS = @GLOBAL_CFLAGS@
-EXTRA_DIST = main.c
+LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
-noinst_LTLIBRARIES = libmpg123.la
+libdir = $(XINE_PLUGINDIR)
-libmpg123_la_SOURCES = common.c decode_i386.c layer1.c layer3.c tabinit.c \
- dct64_i386.c interface.c layer2.c
-libmpg123_la_LIBADD = -lm
+lib_LTLIBRARIES = xineplug_decode_mpg123.la
+xineplug_decode_mpg123_la_SOURCES = common.c decode_i386.c layer1.c layer3.c tabinit.c \
+ dct64_i386.c interface.c layer2.c xine_decoder.c
+xineplug_decode_mpg123_la_LDFLAGS = -avoid-version -module
noinst_HEADERS = huffman.h mpg123.h mpglib.h l2tables.h
+
+##
+## Install header files (default=$includedir/xine)
+##
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)/xine
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
+##
+## Remove them
+##
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/xine/$$p; \
+ done
+
+
debug:
$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
diff --git a/src/libmpg123/interface.c b/src/libmpg123/interface.c
index f02bca63b..199c89479 100644
--- a/src/libmpg123/interface.c
+++ b/src/libmpg123/interface.c
@@ -18,7 +18,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: interface.c,v 1.3 2001/05/06 16:56:01 guenter Exp $
+ * $Id: interface.c,v 1.4 2001/05/27 23:48:12 guenter Exp $
*/
#include <stdlib.h>
@@ -53,9 +53,17 @@ mpgaudio_t *mpg_audio_init (ao_functions_t *ao_output)
mp->ao_output = ao_output;
+ mpg_audio_reset (mp);
+
return mp;
}
+void mpg_audio_close (mpgaudio_t *mpg) {
+
+ free (mpg);
+
+}
+
int head_check(struct mpstr *mp)
{
if( (mp->header & 0xffe00000) != 0xffe00000)
@@ -69,16 +77,10 @@ int head_check(struct mpstr *mp)
return 1;
}
-void mpg_audio_decode_data (metronom_t *metronom,
- mpgaudio_t *mp, uint8_t *data, uint8_t *data_end,
+void mpg_audio_decode_data (mpgaudio_t *mp, uint8_t *data, uint8_t *data_end,
uint32_t pts)
{
- /* printf ("mpg123: decoding package\n"); */
-
- uint32_t pts_for_package = 0;
- /* pts = 0; */
-
while (1) {
/* sync */
if(mp->framesize == 0) {
@@ -103,12 +105,10 @@ void mpg_audio_decode_data (metronom_t *metronom,
mpg123_wordpointer = mp->bsspace[mp->bsnum] + 512;
mp->bsnum = (mp->bsnum + 1) & 0x1;
mpg123_bitindex = 0;
- pts_for_package = pts;
+ mp->pts = pts;
pts = 0;
}
-
- /* printf ("mpg123: copying data\n"); */
/* copy data to bsspace */
while (mp->bsize<mp->framesize) {
@@ -123,23 +123,21 @@ void mpg_audio_decode_data (metronom_t *metronom,
if(mp->fr.error_protection)
getbits(16);
- /* printf ("layer : %d\n",mp->fr.lay); */
switch(mp->fr.lay) {
case 1:
- do_layer1(metronom, mp, pts_for_package);
+ do_layer1(mp);
break;
case 2:
- do_layer2(metronom, mp, pts_for_package);
+ do_layer2(mp);
break;
case 3:
- do_layer3(metronom, mp, pts_for_package);
+ do_layer3(mp);
break;
}
mp->framesize_old = mp->framesize;
mp->framesize = 0;
mp->header = 0;
- pts_for_package = 0;
}
}
diff --git a/src/libmpg123/layer1.c b/src/libmpg123/layer1.c
index b10c938fd..4db905947 100644
--- a/src/libmpg123/layer1.c
+++ b/src/libmpg123/layer1.c
@@ -10,8 +10,6 @@
#include "mpg123.h"
-#include "metronom.h"
-
void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT],struct frame *fr)
{
unsigned int *ba=balloc;
@@ -113,7 +111,7 @@ void I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2*SBLIMIT],
}
}
-void do_layer1(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts)
+void do_layer1(mpgaudio_t *mp)
{
int clip=0;
struct frame *fr = &mp->fr;
@@ -159,7 +157,9 @@ void do_layer1(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts)
printf ("layer1\n");
}
- mp->ao_output->write_audio_data (mp->ao_output, (int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2), pts);
+ mp->ao_output->write_audio_data (mp->ao_output, (int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2),
+ mp->pts);
+ mp->pts = 0;
}
diff --git a/src/libmpg123/layer2.c b/src/libmpg123/layer2.c
index ee5a95cef..c4230ad5d 100644
--- a/src/libmpg123/layer2.c
+++ b/src/libmpg123/layer2.c
@@ -8,8 +8,6 @@
#include "mpg123.h"
#include "l2tables.h"
-#include "metronom.h"
-
static int grp_3tab[32 * 3] = { 0, }; /* used: 27 */
static int grp_5tab[128 * 3] = { 0, }; /* used: 125 */
static int grp_9tab[1024 * 3] = { 0, }; /* used: 729 */
@@ -249,7 +247,7 @@ static void II_select_table(struct frame *fr)
fr->II_sblimit = sblim;
}
-void do_layer2(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts)
+void do_layer2(mpgaudio_t *mp)
{
int clip=0;
int i,j;
@@ -295,11 +293,11 @@ void do_layer2(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts)
stereo-1 ? AO_CAP_MODE_STEREO: AO_CAP_MODE_MONO);
mp->is_output_initialized = 1;
mp->sample_rate_device = fr->sample_rate;
-
- printf ("layer2\n");
}
- mp->ao_output->write_audio_data (mp->ao_output, (int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2), pts);
+ mp->ao_output->write_audio_data (mp->ao_output, (int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2),
+ mp->pts);
+ mp->pts = 0;
}
diff --git a/src/libmpg123/layer3.c b/src/libmpg123/layer3.c
index 89b11776d..54eacdb01 100644
--- a/src/libmpg123/layer3.c
+++ b/src/libmpg123/layer3.c
@@ -10,8 +10,6 @@
#include "mpglib.h"
#include "huffman.h"
-#include "metronom.h"
-
#define MPEG1
@@ -1448,7 +1446,7 @@ static void III_hybrid(mpgaudio_t *mp,
/*
* main layer3 handler
*/
-void do_layer3(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts)
+void do_layer3(mpgaudio_t *mp)
{
int gr, ch, ss,clip=0;
struct frame *fr = &mp->fr;
@@ -1596,6 +1594,8 @@ void do_layer3(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts)
}
}
+ printf ("audio output...mp3\n");
+
if ((!mp->is_output_initialized) || (mp->sample_rate_device != fr->sample_rate)) {
if (mp->is_output_initialized)
@@ -1609,5 +1609,7 @@ void do_layer3(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts)
printf ("layer3\n");
}
- mp->ao_output->write_audio_data (mp->ao_output, (int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2), pts);
+ mp->ao_output->write_audio_data (mp->ao_output, (int16_t*)mp->osspace, num_bytes/(stereo-1 ? 4:2),
+ mp->pts);
+ mp->pts = 0;
}
diff --git a/src/libmpg123/mpg123.h b/src/libmpg123/mpg123.h
index fc7709201..61166e85e 100644
--- a/src/libmpg123/mpg123.h
+++ b/src/libmpg123/mpg123.h
@@ -110,9 +110,9 @@ extern unsigned char *mpg123_wordpointer;
extern int mpg123_bitindex;
extern void make_decode_tables(long scaleval);
-extern void do_layer3(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts);
-extern void do_layer2(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts);
-extern void do_layer1(metronom_t *metronom, mpgaudio_t *mp, uint32_t pts);
+extern void do_layer3(mpgaudio_t *mp);
+extern void do_layer2(mpgaudio_t *mp);
+extern void do_layer1(mpgaudio_t *mp);
extern int decode_header(struct frame *fr,unsigned long newhead);
diff --git a/src/libmpg123/mpglib.h b/src/libmpg123/mpglib.h
index 961851235..94d412893 100644
--- a/src/libmpg123/mpglib.h
+++ b/src/libmpg123/mpglib.h
@@ -18,7 +18,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: mpglib.h,v 1.3 2001/05/06 16:56:01 guenter Exp $
+ * $Id: mpglib.h,v 1.4 2001/05/27 23:48:12 guenter Exp $
*/
#ifndef HAVE_MPGLIB_H
@@ -27,7 +27,6 @@
#include <inttypes.h>
#include "audio_out.h"
-#include "metronom.h"
typedef struct mpstr {
unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
@@ -47,6 +46,8 @@ typedef struct mpstr {
int sample_rate_device;
ao_functions_t *ao_output;
unsigned char osspace[8192];
+
+ uint32_t pts;
} mpgaudio_t;
#ifndef BOOL
@@ -61,10 +62,11 @@ mpgaudio_t *mpg_audio_init (ao_functions_t *ao_output);
void mpg_audio_reset (mpgaudio_t *mp);
-void mpg_audio_decode_data (metronom_t *metronom,
- mpgaudio_t *mp, uint8_t *data, uint8_t *data_end,
+void mpg_audio_decode_data (mpgaudio_t *mp, uint8_t *data, uint8_t *data_end,
uint32_t pts);
+void mpg_audio_close (mpgaudio_t *mp);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/libmpg123/xine_decoder.c b/src/libmpg123/xine_decoder.c
new file mode 100644
index 000000000..8508dcd24
--- /dev/null
+++ b/src/libmpg123/xine_decoder.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2000-2001 the xine project
+ *
+ * This file is part of xine, a unix video player.
+ *
+ * xine 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.
+ *
+ * xine is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ *
+ * $Id: xine_decoder.c,v 1.1 2001/05/27 23:48:12 guenter Exp $
+ *
+ * stuff needed to turn libmpg123 into a xine decoder plugin
+ */
+
+/*
+ * FIXME: libmpg123 uses global variables (that are written to)
+ */
+
+
+#include <stdlib.h>
+
+#include "audio_out.h"
+#include "mpg123.h"
+#include "mpglib.h"
+#include "buffer.h"
+#include "xine_internal.h"
+
+#define FRAME_SIZE 4096
+
+typedef struct mpgdec_decoder_s {
+ audio_decoder_t audio_decoder;
+
+ uint32_t pts;
+
+ mpgaudio_t *mpg;
+
+ ao_functions_t *audio_out;
+ int output_sampling_rate;
+ int output_open;
+
+} mpgdec_decoder_t;
+
+int mpgdec_can_handle (audio_decoder_t *this_gen, int buf_type) {
+ return ((buf_type & 0xFFFF0000) == BUF_AUDIO_MPEG) ;
+}
+
+
+void mpgdec_init (audio_decoder_t *this_gen, ao_functions_t *audio_out) {
+
+ mpgdec_decoder_t *this = (mpgdec_decoder_t *) this_gen;
+
+ this->audio_out = audio_out;
+ this->mpg = mpg_audio_init (audio_out);
+}
+
+void mpgdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) {
+
+ mpgdec_decoder_t *this = (mpgdec_decoder_t *) this_gen;
+
+ mpg_audio_decode_data (this->mpg, buf->content, buf->content + buf->size,
+ buf->PTS);
+}
+
+void mpgdec_close (audio_decoder_t *this_gen) {
+
+ mpgdec_decoder_t *this = (mpgdec_decoder_t *) this_gen;
+
+ mpg_audio_close (this->mpg);
+
+ if (this->output_open)
+ this->audio_out->close (this->audio_out);
+}
+
+static char *mpgdec_get_id(void) {
+ return "mpgdec";
+}
+
+audio_decoder_t *init_audio_decoder_plugin (int iface_version, config_values_t *cfg) {
+
+ mpgdec_decoder_t *this ;
+
+ if (iface_version != 1)
+ return NULL;
+
+ this = (mpgdec_decoder_t *) malloc (sizeof (mpgdec_decoder_t));
+
+ this->audio_decoder.interface_version = 1;
+ this->audio_decoder.can_handle = mpgdec_can_handle;
+ this->audio_decoder.init = mpgdec_init;
+ this->audio_decoder.decode_data = mpgdec_decode_data;
+ this->audio_decoder.close = mpgdec_close;
+ this->audio_decoder.get_identifier = mpgdec_get_id;
+
+ return (audio_decoder_t *) this;
+}
+
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
index 915e33677..b2442c571 100644
--- a/src/xine-engine/Makefile.am
+++ b/src/xine-engine/Makefile.am
@@ -11,7 +11,6 @@ libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c monitor.c \
audio_decoder.c video_out.c
libxine_la_DEPENDENCIES = libsdeps
libxine_la_LIBADD = \
- $(top_srcdir)/src/libmpg123/libmpg123.la \
## $(top_srcdir)/src/libspudec/libspudec.la \
$(THREAD_LIBS) \
$(DYNAMIC_LD_LIBS)
diff --git a/src/xine-engine/load_plugins.c b/src/xine-engine/load_plugins.c
index 79e7486ae..0b073881a 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.18 2001/05/03 00:02:42 f1rmb Exp $
+ * $Id: load_plugins.c,v 1.19 2001/05/27 23:48:12 guenter Exp $
*
*
* Load input/demux/audio_out/video_out/codec plugins
@@ -87,8 +87,8 @@ void load_demux_plugins (xine_t *this,
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());
+ fprintf(stderr, "load_plugins: cannot open demux plugin %s:\n%s\n",
+ str, dlerror());
exit(1);
}
else {
@@ -100,10 +100,8 @@ void load_demux_plugins (xine_t *this,
dxp = (demux_plugin_t *) initplug(iface_version, config);
this->demuxer_plugins[this->num_demuxer_plugins] = dxp;
- printf("demux plugin found : %s(ID: %s, iface: %d)\n",
- str,
- this->demuxer_plugins[this->num_demuxer_plugins]->get_identifier(),
- this->demuxer_plugins[this->num_demuxer_plugins]->interface_version);
+ printf("load_plugins: demux plugin found : %s\n",
+ this->demuxer_plugins[this->num_demuxer_plugins]->get_identifier());
this->num_demuxer_plugins++;
}
@@ -164,10 +162,8 @@ void load_input_plugins (xine_t *this,
sprintf (str, "%s/%s", XINE_PLUGINDIR, pEntry->d_name);
- printf ("load_plugins: trying to load input plugin >%s<\n",str);
-
if(!(plugin = dlopen (str, RTLD_LAZY))) {
- printf("load_plugins: cannot open input plugin %s: %s\n",
+ printf("load_plugins: cannot open input plugin %s:\n%s\n",
str, dlerror());
} else {
void *(*initplug) (int, config_values_t *);
@@ -178,10 +174,8 @@ void load_input_plugins (xine_t *this,
ip = (input_plugin_t *) initplug(iface_version, config);
this->input_plugins[this->num_input_plugins] = ip;
- printf("load_plugins: input plugin found : %s(ID: %s, iface: %d)\n",
- str,
- this->input_plugins[this->num_input_plugins]->get_identifier(this->input_plugins[this->num_input_plugins]),
- this->input_plugins[this->num_input_plugins]->interface_version);
+ printf("load_plugins: input plugin found : %s\n",
+ this->input_plugins[this->num_input_plugins]->get_identifier(this->input_plugins[this->num_input_plugins]));
this->num_input_plugins++;
} else {
@@ -435,9 +429,8 @@ void load_decoder_plugins (xine_t *this,
this->video_decoder_plugins[streamtype] = vdp;
}
- printf("video decoder plugin found : %s (ID: %s, iface: %d)\n",
- pEntry->d_name, vdp->get_identifier(),
- vdp->interface_version);
+ printf("video decoder plugin found : %s\n",
+ vdp->get_identifier());
}
@@ -514,8 +507,8 @@ char **xine_list_video_output_plugins (int visual_type) {
if(!(plugin = dlopen (str, RTLD_LAZY))) {
- /* printf("load_plugins: cannot load plugin %s (%s)\n",
- str, dlerror()); */
+ printf("load_plugins: cannot load plugin %s:\n%s\n",
+ str, dlerror());
} else {
@@ -585,7 +578,7 @@ vo_driver_t *xine_load_video_output_plugin(config_values_t *config,
sprintf (str, "%s/%s", XINE_PLUGINDIR, dir_entry->d_name);
if(!(plugin = dlopen (str, RTLD_LAZY))) {
- printf("load_plugins: video output plugin %s failed to link: %s\n",
+ printf("load_plugins: video output plugin %s failed to link:\n%s\n",
str, dlerror());
return NULL;
} else {
@@ -604,7 +597,7 @@ vo_driver_t *xine_load_video_output_plugin(config_values_t *config,
if (vod)
printf("load_plugins: video output plugin %s successfully"
- " loaded.\n", str);
+ " loaded.\n", id);
else
printf("load_plugins: video output plugin %s: "
"init_video_out_plugin failed.\n", str);
@@ -750,7 +743,7 @@ ao_functions_t *xine_load_audio_output_plugin(config_values_t *config,
if (aod)
printf("load_plugins: audio output plugin %s successfully"
- " loaded.\n", str);
+ " loaded.\n", id);
else
printf("load_plugins: audio output plugin %s: "
"init_audio_out_plugin failed.\n", str);
diff --git a/src/xine-engine/metronom.c b/src/xine-engine/metronom.c
index bcb4b80fd..24adfba3f 100644
--- a/src/xine-engine/metronom.c
+++ b/src/xine-engine/metronom.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: metronom.c,v 1.5 2001/05/24 21:41:28 guenter Exp $
+ * $Id: metronom.c,v 1.6 2001/05/27 23:48:12 guenter Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -36,9 +36,9 @@
#include "metronom.h"
#include "utils.h"
-#define MAX_PTS_TOLERANCE 5000
-#define MAX_VIDEO_DELTA 1600
-#define AUDIO_SAMPLE_NUM 32768
+#define MAX_PTS_TOLERANCE 5000
+#define MAX_VIDEO_DELTA 1600
+#define AUDIO_SAMPLE_NUM 32768
#define MAX_WRAP_TOLERANCE 180000
static void metronom_reset (metronom_t *this) {
@@ -106,6 +106,8 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {
pthread_mutex_lock (&this->lock);
+ /* pts = 0; */
+
if (pts) {
/*
@@ -142,7 +144,6 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {
this->video_pts_delta = 0;
this->num_video_vpts_guessed = 0;
- /* printf ("delta: %d\n", this->video_pts_delta); */
}
/*
@@ -163,11 +164,12 @@ static uint32_t metronom_got_video_frame (metronom_t *this, uint32_t pts) {
this->video_vpts, synced_vpts, vpts_diff, this->video_pts_delta);
if (abs(vpts_diff)>MAX_PTS_TOLERANCE) {
- if (synced_vpts>this->video_vpts) {
+ if ( synced_vpts>this->video_vpts ) {
this->video_vpts = synced_vpts;
}
- } else
+ } else {
xprintf (METRONOM | VERBOSE, "metronom: video tolerating diff\n");
+ }
} else
xprintf (METRONOM | VERBOSE, "metronom: video not synced on this one\n");
@@ -314,7 +316,7 @@ static uint32_t metronom_get_current_time (metronom_t *this) {
pts += this->start_pts;
if (this->stopped || (this->last_pts > pts)) {
- //printf("tm_current_pts(): timer STOPPED!\n");
+ /* printf("metronom: get_current_time(): timer STOPPED!\n"); */
pts = this->last_pts;
}
@@ -355,7 +357,7 @@ static void metronom_adjust_clock(metronom_t *this, uint32_t desired_pts)
delta = desired_pts;
delta -= current_time;
this->start_pts += delta;
- /* printf("adjusting start_pts to %d\n", this->start_pts); */
+ printf("adjusting start_pts to %d\n", this->start_pts);
pthread_mutex_unlock (&this->lock);
}
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index 543e141fb..ce6092a0d 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_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: video_out.c,v 1.9 2001/05/26 00:48:47 guenter Exp $
+ * $Id: video_out.c,v 1.10 2001/05/27 23:48:12 guenter Exp $
*
*/
@@ -360,7 +360,6 @@ static int vo_frame_draw (vo_frame_t *img) {
xprintf (VERBOSE|VIDEO,"video_out: got image. vpts for picture is %d\n", pic_vpts);
- /* printf ("video_out: got image. vpts for picture is %d\n", pic_vpts); */
cur_vpts = this->metronom->get_current_time(this->metronom);