From a8419890b93e08fbe1973d0d4a8673fbace2cca9 Mon Sep 17 00:00:00 2001 From: Darren Salt Date: Wed, 8 Aug 2007 22:44:03 +0100 Subject: Fix an attempted free of static data, e.g. when using "dvd:/" (not "dvd://"). --- src/input/input_dvd.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index 9f8aa6a25..34729e8c2 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -1477,7 +1477,7 @@ static int dvd_plugin_open (input_plugin_t *this_gen) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; dvd_input_class_t *class = (dvd_input_class_t*)this_gen->input_class; - char *locator; + char *locator, *locator_orig; char *title_part; xine_event_t event; xine_cfg_entry_t region_entry, lang_entry, cfg_entry; @@ -1485,7 +1485,7 @@ static int dvd_plugin_open (input_plugin_t *this_gen) { trace_print("Called\n"); /* we already checked the "dvd:/" MRL before */ - locator = strdup (this->mrl + (sizeof("dvd:") - 1)); + locator_orig = locator = strdup (this->mrl + (sizeof("dvd:") - 1)); /* FIXME: call a generic xine-lib MRL parser here to pre-parse * the MRL for ?title=&part=<part> stuff and to expand @@ -1501,11 +1501,11 @@ static int dvd_plugin_open (input_plugin_t *this_gen) { _x_message(this->stream, XINE_MSG_READ_ERROR, /* FIXME: see FIXME in dvd_parse_try_open() */ (strlen(locator) && !(locator[0] == '/' && locator[1] == '\0')) ? locator : class->dvd_device, NULL); - free (locator); + free (locator_orig); return 0; } - free (locator); + free (locator_orig); dvdnav_get_title_string(this->dvdnav, &this->dvd_name); if(this->dvd_name) -- cgit v1.2.3 From 90bfed2c4c86e943ad850a023a28df31c558d75f Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Sun, 12 Aug 2007 20:54:03 +0100 Subject: Extend config key translation to allow front ends to provide an additional list. Intent is to allow front ends to rename their old, badly-named, config items. --- src/xine-engine/configfile.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/xine-engine/configfile.c b/src/xine-engine/configfile.c index ec5f5c856..67c8ef909 100644 --- a/src/xine-engine/configfile.c +++ b/src/xine-engine/configfile.c @@ -45,13 +45,8 @@ #include "xineutils.h" #include "xine_internal.h" - -typedef struct { - const char *old; - const char *new; -} config_entry_translation_t; - -static const config_entry_translation_t config_entry_translation[] = { +static const xine_config_entry_translation_t *config_entry_translation_user = NULL; +static const xine_config_entry_translation_t config_entry_translation[] = { { "audio.a52_pass_through", "" }, { "audio.alsa_a52_device", "audio.device.alsa_passthrough_device" }, { "audio.alsa_default_device", "audio.device.alsa_default_device" }, @@ -209,7 +204,8 @@ static const config_entry_translation_t config_entry_translation[] = { { "video.xv_colorkey", "video.device.xv_colorkey" }, { "video.xv_pitch_alignment", "video.device.xv_pitch_alignment" }, { "video.xvmc_more_frames", "video.device.xvmc_more_frames" }, - { "video.xvmc_nvidia_color_fix", "video.device.xvmc_nvidia_color_fix" } + { "video.xvmc_nvidia_color_fix", "video.device.xvmc_nvidia_color_fix" }, + {} }; @@ -354,6 +350,15 @@ static void config_remove(config_values_t *this, cfg_entry_t *entry, cfg_entry_t prev->next = entry->next; } +static const char *config_xlate_internal (const char *key, const xine_config_entry_translation_t *trans) +{ + --trans; + while ((++trans)->old) + if (trans->new[0] && strcmp(key, trans->old) == 0) + return trans->new; + return NULL; +} + static const char *config_translate_key (const char *key) { /* Returns translated key or, if no translation found, NULL. * Translated key may be in a static buffer allocated within this function. @@ -373,13 +378,11 @@ static const char *config_translate_key (const char *key) { } /* search the translation table... */ - for (trans = 0; - trans < sizeof(config_entry_translation) / sizeof(config_entry_translation[0]); - trans++) - if (config_entry_translation[trans].new[0] && strcmp(key, config_entry_translation[trans].old) == 0) - return config_entry_translation[trans].new; + newkey = config_xlate_internal (key, config_entry_translation); + if (!newkey && config_entry_translation_user) + newkey = config_xlate_internal (key, config_entry_translation_user); - return NULL; + return newkey; } static void config_lookup_entry_int (config_values_t *this, const char *key, @@ -894,6 +897,14 @@ static void config_update_string (config_values_t *this, pthread_mutex_unlock(&this->config_lock); } +/* + * front end config translation handling + */ +void xine_config_set_translation_user (const xine_config_entry_translation_t *xlate) +{ + config_entry_translation_user = xlate; +} + /* * load/save config data from/to afile (e.g. $HOME/.xine/config) */ -- cgit v1.2.3 From 3954c82f0a91fc5f4a0c43441177ac2ace1f4f05 Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Sun, 12 Aug 2007 20:54:53 +0100 Subject: Add a few missing "\n"s. --- src/video_out/video_out_xcbxv.c | 2 +- src/video_out/video_out_xv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c index 717f54fae..81c78a71f 100644 --- a/src/video_out/video_out_xcbxv.c +++ b/src/video_out/video_out_xcbxv.c @@ -1411,7 +1411,7 @@ static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *vis if(!strcmp(xcb_xv_attribute_info_name(attribute_it.data), "XV_HUE")) { if (!strncmp(xcb_xv_adaptor_info_name(adaptor_it.data), "NV", 2)) { - xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_xcbxv: ignoring broken XV_HUE settings on NVidia cards"); + xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_xcbxv: ignoring broken XV_HUE settings on NVidia cards\n"); } else { xv_check_capability (this, VO_PROP_HUE, attribute_it.data, adaptor_it.data->base_id, diff --git a/src/video_out/video_out_xv.c b/src/video_out/video_out_xv.c index 95a847c2c..4c3db95a6 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -1469,7 +1469,7 @@ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void * if(!strcmp(attr[k].name, "XV_HUE")) { if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) { - xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_xv: ignoring broken XV_HUE settings on NVidia cards"); + xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_xv: ignoring broken XV_HUE settings on NVidia cards\n"); } else { xv_check_capability (this, VO_PROP_HUE, attr[k], adaptor_info[adaptor_num].base_id, -- cgit v1.2.3 From 446e1487e45af46a62f00ce0165b830081073cda Mon Sep 17 00:00:00 2001 From: Maxim Levitsky <maximlevitsky@gmail.com> Date: Sun, 12 Aug 2007 18:31:37 +0100 Subject: Fix goom visualization plug-in I noticed that goom visualization plug-in doesn't work / freezes at some combination of bit rates and its FPS. Digging through it I found that algorithm that dispatches sound data to goom is buggy, and so I have rewrote/cleaned it a lot. Let me explain what is wrong: I am talking about goom_port_put_buffer in /xine-lib-1.1.7/src/post/goom/xine_goom.c The counter this->skip_frame is supposed to hold count of frames that goom should skip because of _video render unable to render video_. But that algorithm also skips frames on its own, and still decrements that counter. So it goes negative, and no frames are displayed. Basically to fix that you need to add if (this->skip_frame > 0) before this->skip_frame--; But since I want to fix that properly I decided to learn why goom skips frames on its own, and I now understand that whole algorithm is buggy. Thus I reimplemented it properly. I tested it , and it works with all my sound files, also I added lot of debug printfs to test whenever it works as expected, and it does. --HG-- extra : transplant_source : %B6%0C%09%D6%93%B8%00cj%3B8%C7%B5%0B%DB%21%08%92%3E%7B --- src/post/goom/xine_goom.c | 112 ++++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/post/goom/xine_goom.c b/src/post/goom/xine_goom.c index 5871618e0..7c2939105 100644 --- a/src/post/goom/xine_goom.c +++ b/src/post/goom/xine_goom.c @@ -82,13 +82,12 @@ struct post_plugin_goom_s { /* goom context */ PluginInfo *goom; - int data_idx; + int data_idx; gint16 data [2][NUMSAMPLES]; audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */ int channels; int sample_rate; - int sample_counter; int samples_per_frame; int width, height; int width_back, height_back; @@ -96,6 +95,11 @@ struct post_plugin_goom_s { int fps; int csc_method; + + int do_samples_skip; /* true = skipping samples, false reading samples*/ + int left_to_read; /* data to read before switching modes*/ + + yuv_planes_t yuv; /* frame skipping */ @@ -282,7 +286,6 @@ static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs, this->ratio = (double)this->width_back/(double)this->height_back; - this->sample_counter = 0; this->buf.mem = NULL; this->buf.mem_size = 0; @@ -386,9 +389,11 @@ static int goom_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, this->sample_rate = rate; this->samples_per_frame = rate / this->fps; this->data_idx = 0; - this->sample_counter = 0; init_yuv_planes(&this->yuv, this->width, this->height); this->skip_frame = 0; + + this->do_samples_skip = 0; + this->left_to_read = NUMSAMPLES; this->vo_port->open(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); @@ -422,11 +427,12 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen, uint8_t *goom_frame, *goom_frame_end; int16_t *data; int8_t *data8; - int samples_used = 0; int64_t pts = buf->vpts; int i, j; uint8_t *dest_ptr; int width, height; + + int current_sample = 0; /* make a copy of buf data for private use */ if( this->buf.mem_size < buf->mem_size ) { @@ -444,59 +450,73 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen, * to the fifo of free audio buffers. just use our private copy instead. */ buf = &this->buf; - - this->sample_counter += buf->num_frames; j = (this->channels >= 2) ? 1 : 0; - do { - + + while (current_sample < buf->num_frames) { + + if (this->do_samples_skip) { + if (current_sample + this->left_to_read > buf->num_frames) { + this->left_to_read -= (buf->num_frames-current_sample); + break; + } else { + current_sample+=this->left_to_read; + this->left_to_read = NUMSAMPLES; + this->do_samples_skip = 0; + + } + } else { + if( port->bits == 8 ) { data8 = (int8_t *)buf->mem; - data8 += samples_used * this->channels; + data8 += current_sample * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ - for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; - i++, this->data_idx++, data8 += this->channels ) { + for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames; + i++, this->data_idx++,data8 += this->channels) { + this->data[0][this->data_idx] = ((int16_t)data8[0] << 8) - 0x8000; this->data[1][this->data_idx] = ((int16_t)data8[j] << 8) - 0x8000; } } else { data = buf->mem; - data += samples_used * this->channels; - - for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; - i++, this->data_idx++, data += this->channels ) { + data += current_sample * this->channels; + + for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames; + i++, this->data_idx++,data += this->channels) { + this->data[0][this->data_idx] = data[0]; this->data[1][this->data_idx] = data[j]; } } - - if( this->sample_counter >= this->samples_per_frame ) { - - samples_used += this->samples_per_frame; + + if (this->data_idx < NUMSAMPLES) { + this->left_to_read = NUMSAMPLES - this->data_idx; + break; + } else { + _x_assert(this->data_idx == NUMSAMPLES); + this->data_idx = 0; + + if (this->samples_per_frame > NUMSAMPLES) { + current_sample += NUMSAMPLES; + this->do_samples_skip = 1; + this->left_to_read = this->samples_per_frame - NUMSAMPLES; + } else { + current_sample += this->samples_per_frame; + this->left_to_read = NUMSAMPLES; + } frame = this->vo_port->get_frame (this->vo_port, this->width_back, this->height_back, - this->ratio, XINE_IMGFMT_YUY2, - VO_BOTH_FIELDS); + this->ratio, XINE_IMGFMT_YUY2, + VO_BOTH_FIELDS); frame->extra_info->invalid = 1; - /* frame is marked as bad if we don't have enough samples for - * updating the viz plugin (calculations may be skipped). - * we must keep the framerate though. */ - if( this->data_idx == NUMSAMPLES ) { - frame->bad_frame = 0; - this->data_idx = 0; - } else { - frame->bad_frame = 1; - } frame->duration = 90000 * this->samples_per_frame / this->sample_rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); - this->sample_counter -= this->samples_per_frame; - - if (!this->skip_frame && !frame->bad_frame) { + if (!this->skip_frame) { /* Try to be fast */ goom_frame = (uint8_t *)goom_update (this->goom, this->data, 0, 0, NULL, NULL); @@ -561,21 +581,25 @@ static void goom_port_put_buffer (xine_audio_port_t *port_gen, } else { frame->bad_frame = 1; frame->draw(frame, XINE_ANON_STREAM); - this->skip_frame--; + + _x_assert(this->skip_frame>0); + this->skip_frame--; } + frame->free(frame); width = this->width; height = this->height; if ((width != this->width_back) || (height != this->height_back)) { - goom_close(this->goom); - this->goom = goom_init (this->width, this->height); - this->width_back = width; - this->height_back = height; - this->ratio = (double)width/(double)height; - free_yuv_planes(&this->yuv); - init_yuv_planes(&this->yuv, this->width, this->height); - } + goom_close(this->goom); + this->goom = goom_init (this->width, this->height); + this->width_back = width; + this->height_back = height; + this->ratio = (double)width/(double)height; + free_yuv_planes(&this->yuv); + init_yuv_planes(&this->yuv, this->width, this->height); + } } - } while( this->sample_counter >= this->samples_per_frame ); + } + } } -- cgit v1.2.3 From 7047d9e5acf97c91a523c99ccc4b008a35a3e094 Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Wed, 15 Aug 2007 13:42:38 +0100 Subject: Fix an audio resampling problem which was causing regular clicking. The cause was that the resampling code was using only the samples in the buffer but not really handling the transition between two buffers (which it would handle completely independently). The new code remembers the last sample from the previous buffer and uses it in the resampling. We therefore end up one sample behind and without the clicks. --- src/post/audio/stretch.c | 10 +++- src/xine-engine/audio_out.c | 30 ++++++++++-- src/xine-engine/resample.c | 115 ++++++++++++++++++++++++++++---------------- src/xine-engine/resample.h | 17 +++++-- 4 files changed, 120 insertions(+), 52 deletions(-) (limited to 'src') diff --git a/src/post/audio/stretch.c b/src/post/audio/stretch.c index a1e921e03..054468517 100644 --- a/src/post/audio/stretch.c +++ b/src/post/audio/stretch.c @@ -225,6 +225,8 @@ struct post_plugin_stretch_s { int frames_per_frag; int frames_per_outfrag; int num_frames; /* current # of frames on audiofrag */ + + int16_t last_sample[RESAMPLE_MAX_CHANNELS]; int64_t pts; /* pts for audiofrag */ @@ -353,12 +355,16 @@ static void stretch_process_fragment( post_audio_port_t *port, if( !this->params.preserve_pitch ) { if( this->channels == 2 ) - _x_audio_out_resample_stereo(this->audiofrag, num_frames_in, + _x_audio_out_resample_stereo(this->last_sample, this->audiofrag, num_frames_in, this->outfrag, num_frames_out); else if( this->channels == 1 ) - _x_audio_out_resample_mono(this->audiofrag, num_frames_in, + _x_audio_out_resample_mono(this->last_sample, this->audiofrag, num_frames_in, this->outfrag, num_frames_out); } else { + if (this->channels == 2) + memcpy (this->last_sample, &this->audiofrag[(num_frames_in - 1) * 2], 2 * sizeof (this->last_sample[0])); + else if (this->channels == 1) + memcpy (this->last_sample, &this->audiofrag[num_frames_in - 1], sizeof (this->last_sample[0])); if( num_frames_in > num_frames_out ) { /* diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 6f5351986..93768224b 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -251,6 +251,7 @@ typedef struct { * sure nobody will change speed without going through xine.c:set_speed_internal */ int slow_fast_audio; /* play audio even on slow/fast speeds */ + int16_t last_sample[RESAMPLE_MAX_CHANNELS]; audio_buffer_t *frame_buf[2]; /* two buffers for "stackable" conversions */ int16_t *zero_space; @@ -746,19 +747,19 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) { switch (this->input.mode) { case AO_CAP_MODE_MONO: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3), num_output_frames); - _x_audio_out_resample_mono (buf->mem, buf->num_frames, + _x_audio_out_resample_mono (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_STEREO: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*2, num_output_frames); - _x_audio_out_resample_stereo (buf->mem, buf->num_frames, + _x_audio_out_resample_stereo (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_4CHANNEL: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*4, num_output_frames); - _x_audio_out_resample_4channel (buf->mem, buf->num_frames, + _x_audio_out_resample_4channel (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; @@ -766,7 +767,7 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) { case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*6, num_output_frames); - _x_audio_out_resample_6channel (buf->mem, buf->num_frames, + _x_audio_out_resample_6channel (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; @@ -775,6 +776,25 @@ static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) { /* pass-through modes: no resampling */ break; } + } else { + /* maintain last_sample in case we need it */ + switch (this->input.mode) { + case AO_CAP_MODE_MONO: + memcpy (this->last_sample, &buf->mem[buf->num_frames - 1], sizeof (this->last_sample[0])); + break; + case AO_CAP_MODE_STEREO: + memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 2], 2 * sizeof (this->last_sample[0])); + break; + case AO_CAP_MODE_4CHANNEL: + memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 4], 4 * sizeof (this->last_sample[0])); + break; + case AO_CAP_MODE_4_1CHANNEL: + case AO_CAP_MODE_5CHANNEL: + case AO_CAP_MODE_5_1CHANNEL: + memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 6], 6 * sizeof (this->last_sample[0])); + break; + default:; + } } /* mode conversion */ @@ -2160,6 +2180,8 @@ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, fifo_append (this->free_fifo, buf); } + + memset (this->last_sample, 0, sizeof (this->last_sample)); /* buffers used for audio conversions */ for (i=0; i<2; i++) { diff --git a/src/xine-engine/resample.c b/src/xine-engine/resample.c index a7b16917c..1bc9dfaf9 100644 --- a/src/xine-engine/resample.c +++ b/src/xine-engine/resample.c @@ -24,26 +24,34 @@ #include "config.h" #endif +#include <string.h> #include <inttypes.h> #include "attributes.h" #include "resample.h" /* contributed by paul flinders */ -void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_mono(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -58,23 +66,31 @@ void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, isample += istep; } - output_samples[out_samples-1] = input_samples[in_samples-1]; + last_sample[0] = input_samples[in_samples - 1]; } -void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_stereo(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*2 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*2+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -94,25 +110,34 @@ void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, output_samples[(osample * 2 )+1] = os; isample += istep; } - output_samples[out_samples*2-2] = input_samples[in_samples*2-2]; - output_samples[out_samples*2-1] = input_samples[in_samples*2-1]; + memcpy (last_sample, &input_samples[in_samples*2-2], 2 * sizeof (last_sample[0])); } -void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_4channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*4 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*4+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*4+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*4+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -145,28 +170,35 @@ void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, 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]; - + memcpy (last_sample, &input_samples[in_samples*4-4], 4 * sizeof (last_sample[0])); } -void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_5channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*5 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*5+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*5+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*5+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + output_samples[osample*5+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -205,29 +237,36 @@ void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, 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]; + memcpy (last_sample, &input_samples[in_samples*5-5], 5 * sizeof (last_sample[0])); } -void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_6channel(int16_t *last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ - uint32_t isample = 0; - uint32_t istep = ((in_samples-2) << 16)/(out_samples-2); + uint32_t isample = 0xFFFF0000U; + uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif - for (osample = 0; osample < out_samples - 1; osample++) { + for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { + uint32_t t = isample&0xffff; + output_samples[osample*6 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; + output_samples[osample*6+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; + output_samples[osample*6+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; + output_samples[osample*6+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; + output_samples[osample*6+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; + output_samples[osample*6+5] = (last_sample[5] * (0x10000-t) + input_samples[5] * t) >> 16; + isample += istep; + } + + for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; @@ -272,13 +311,7 @@ void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, isample += istep; } - - output_samples[out_samples*6-6] = input_samples[in_samples*6-6]; - output_samples[out_samples*6-5] = input_samples[in_samples*6-5]; - output_samples[out_samples*6-4] = input_samples[in_samples*6-4]; - output_samples[out_samples*6-3] = input_samples[in_samples*6-3]; - output_samples[out_samples*6-2] = input_samples[in_samples*6-2]; - output_samples[out_samples*6-1] = input_samples[in_samples*6-1]; + memcpy (last_sample, &input_samples[in_samples*6-6], 6 * sizeof (last_sample[0])); } void _x_audio_out_resample_8to16(int8_t* input_samples, diff --git a/src/xine-engine/resample.h b/src/xine-engine/resample.h index e5aad1afa..1fd478d06 100644 --- a/src/xine-engine/resample.h +++ b/src/xine-engine/resample.h @@ -27,19 +27,26 @@ #ifndef HAVE_RESAMPLE_H #define HAVE_RESAMPLE_H -void _x_audio_out_resample_stereo(int16_t* input_samples, uint32_t in_samples, +#define RESAMPLE_MAX_CHANNELS 6 + +void _x_audio_out_resample_stereo(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_mono(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_mono(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_4channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_4channel(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_5channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_5channel(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; -void _x_audio_out_resample_6channel(int16_t* input_samples, uint32_t in_samples, +void _x_audio_out_resample_6channel(int16_t* last_sample, + int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; void _x_audio_out_resample_8to16(int8_t* input_samples, -- cgit v1.2.3