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(-) 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 50b0a0157709ed4a418012883793bf7ea9ddac13 Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Sun, 12 Aug 2007 18:23:03 +0100 Subject: Build .debs with freetype support. --- debian/rules | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/rules b/debian/rules index 75dd344ea..4e1595043 100755 --- a/debian/rules +++ b/debian/rules @@ -64,6 +64,7 @@ CONFIGURE_FLAGS := --prefix=/usr \ --with-external-libmad \ --with-external-a52dec \ --with-external-libdts \ + --with-freetype \ --with-wavpack \ $(DEB_BUILD_CONFIG_OPTIONS) \ CFLAGS="$(CFLAGS)" -- 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. --- ChangeLog | 2 ++ configure.ac | 6 +++--- include/xine.h.in | 10 ++++++++++ src/xine-engine/configfile.c | 39 +++++++++++++++++++++++++-------------- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3cc2f4b93..e1a6fe964 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,8 @@ xine-lib (1.1.8) (Unreleased) capable boxes it's probably worse than our own code). * Rename endianness-reading macros so that they don't collide with Solaris system macros. BE_/LE_ are now _X_BE_ and _X_LE_. + * Add an extra function to allow front ends to rename their old, + badly-named configuration items. xine-lib (1.1.7) * Support libdca (new name for libdts) by shuffling around the dts.h file. diff --git a/configure.ac b/configure.ac index 3d08dd44b..224f45773 100644 --- a/configure.ac +++ b/configure.ac @@ -49,9 +49,9 @@ dnl are platform dependent dnl * in Linux, the library will be named dnl libname.so.(XINE_LT_CURRENT - XINE_LT_AGE).XINE_LT_AGE.XINE_LT_REVISION -XINE_LT_CURRENT=18 -XINE_LT_REVISION=2 -XINE_LT_AGE=17 +XINE_LT_CURRENT=19 +XINE_LT_REVISION=0 +XINE_LT_AGE=18 dnl for a release tarball do "rm .cvsversion" before "make dist" if test -f "${srcdir-.}/.cvsversion"; then diff --git a/include/xine.h.in b/include/xine.h.in index f25038796..58507e6f1 100644 --- a/include/xine.h.in +++ b/include/xine.h.in @@ -1532,6 +1532,16 @@ int xine_config_lookup_entry (xine_t *self, const char *key, void xine_config_update_entry (xine_t *self, const xine_cfg_entry_t *entry) XINE_PROTECTED; +/* + * translation of old configuration entry names + */ +typedef struct { + const char *old; + const char *new; +} xine_config_entry_translation_t; + +void xine_config_set_translation_user (const xine_config_entry_translation_t *) XINE_PROTECTED; + /* * load/save config data from/to afile (e.g. $HOME/.xine/config) */ 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(-) 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(-) 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 db2b02f772d0e0c4e22427b1a1acd806aa88558a Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Sun, 12 Aug 2007 21:41:51 +0100 Subject: Changelog updates. --- ChangeLog | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e1a6fe964..c73a1131d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,7 +8,14 @@ xine-lib (1.1.8) (Unreleased) system macros. BE_/LE_ are now _X_BE_ and _X_LE_. * Add an extra function to allow front ends to rename their old, badly-named configuration items. - + * Various build fixes and cleanups for Solaris, plugin dependencies etc. + * Fix some memory leaks in the Vorbis decoder and video overlays. + * Fix a problem with the goom plugin which could cause it to stop working. + * Clean up "%" unescaping in MRLs; correctly handle "%" in DVD MRLs. + * Fix a crash with "dvb:/". + * DVB subtitle fixes: deadlock prevention, thread leakage, spec compliance. + * Allow the DVB input plugin to timeout if it is receiving no signal. + xine-lib (1.1.7) * Support libdca (new name for libdts) by shuffling around the dts.h file. * Add support for MDHD version 1 atom in demux_qt. [bug #1679398] -- cgit v1.2.3 From 785bcfc32ab60c1eeb504e7d391d85a4939a19d9 Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Sun, 10 Jun 2007 03:45:27 +0100 Subject: Add an alternative build-dep on libjack-dev. --HG-- extra : transplant_source : %B9%3C%C1%06%8C%00%E4%3C%9Fl%C4%EA/%CA%E0%F4%9DaG%93 --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 059d22d57..c72d259a5 100644 --- a/debian/control +++ b/debian/control @@ -14,7 +14,7 @@ Build-Depends: debhelper (>= 5.0.1), binutils (>= 2.12.90.0.9), pkg-config, libogg-dev, libvorbis-dev, libtheora-dev, libesd0-dev, libgnomevfs2-dev, zlib1g-dev, libartsc0-dev, - liblircclient-dev, libjack0.100.0-dev, + liblircclient-dev, libjack0.100.0-dev | libjack-dev, libdirectfb-dev, libgtk2.0-dev, libflac-dev, libpulse-dev, libsdl1.2-dev, libwavpack-dev, libsmbclient-dev, libspeex-dev, libmng-dev, -- cgit v1.2.3 From 96bf2935a326e17d8a922aa0d91757af20d040cd Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Tue, 14 Aug 2007 15:04:17 +0100 Subject: Bump package version no. --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2a9e42e9b..997d81729 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ -xine-lib (1.1.7~hg-0) unstable; urgency=low +xine-lib (1.1.8~hg-0) unstable; urgency=low * Hg snapshot. - -- Darren Salt <linux@youmustbejoking.demon.co.uk> Thu, 07 Jun 2007 02:48:13 +0100 + -- Darren Salt <linux@youmustbejoking.demon.co.uk> Tue, 14 Aug 2007 15:03:49 +0100 xine-lib (1.1.5~cvs-0) unstable; urgency=low -- cgit v1.2.3 From e7a5aa54e5ea14c8f6ed16b1850f48f32324cb0b Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Tue, 14 Aug 2007 17:04:11 +0100 Subject: Update TODO. --- TODO | 1 + 1 file changed, 1 insertion(+) diff --git a/TODO b/TODO index 61fa0efe7..02703d8c3 100644 --- a/TODO +++ b/TODO @@ -6,6 +6,7 @@ known bugs - dvdnav time search function does not use the time table, but interpolates only cell times - crash with RV10 streams +- apparently, dvb:// (but not dvb://CHANNEL) is broken for ATSC requested/planned features -- cgit v1.2.3 From bb297c93a3655f3458a526630578c8f15087d19a Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Tue, 14 Aug 2007 17:06:02 +0100 Subject: Ignore debian/libxine1-doc. --- .hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgignore b/.hgignore index c9d403171..18e56d5d4 100644 --- a/.hgignore +++ b/.hgignore @@ -36,6 +36,7 @@ debian/files debian/libxine-dev debian/libxine1 debian/libxine1-dbg +debian/libxine1-doc debian/tmp debian/*.debhelper debian/*.substvars -- cgit v1.2.3 From 27aeb069aa930c0c8fa0e0f41885bbedc69d0bcb Mon Sep 17 00:00:00 2001 From: Darren Salt <linux@youmustbejoking.demon.co.uk> Date: Tue, 14 Aug 2007 19:40:33 +0100 Subject: Update and reformat the DVB README. Remove the DVB driver installation instructions in favour of a pointer to the "getting started" section of the LinuxTV wiki. Add a pointer to the scan documentation (same site). Mention the requirement for membership of group "video". --- doc/README.dvb | 169 +++++++++++++++++++++++++++------------------------------ 1 file changed, 81 insertions(+), 88 deletions(-) diff --git a/doc/README.dvb b/doc/README.dvb index c04013330..38ea6613d 100644 --- a/doc/README.dvb +++ b/doc/README.dvb @@ -4,52 +4,54 @@ xine Digital TV (DVB) xine can be used to watch digital television. -xine supports Digital TV (Digital Video Broadcasting - DVB) cards -using the Linux DVB driver from Convergence (http://www.linuxtv.org). -DVB-S (direct satellite reception), DVB-C (Cable) and DVB-T (Teresstrical) -cards should be supported (e.g. the Hauppauge WinTV Nova DVB-S card). +xine supports Digital TV (Digital Video Broadcasting - DVB) cards using the +Linux DVB drivers in your kernel or from http://www.linuxtv.org/. + +Many DVB-S (direct satellite reception), DVB-C (Cable) and DVB-T and ATSC +(Terrestrial) devices are supported via these drivers. -driver download and installation --------------------------------- -Download and install the drivers from http://www.linuxtv.org, the 1.0.0 or later release -should work fine. +Driver download and installation +-------------------------------- -You will need kernel sources configured for your configuration for -a successfull build, preferably in /usr/src/linux plus a link to them in -/lib/modules/<kernel-version>/build. Once you have that you should be ready -to compile the driver +You may need to download and install drivers for recent hardware. See the +"Getting Started" section at http://www.linuxtv.org/wiki/index.php/ . -# cd linuxtv-dvb-1.0.0/driver -# make +You will probably need to add yourself to group "video". With a DVB device +installed and recognised: -if that doesn't fail, do a + $ ls -l /deb/dvb/adapter0 + total 0 + crw-rw---- 1 root video 212, 4 2007-08-07 15:33 demux0 + crw-rw---- 1 root video 212, 5 2007-08-07 15:33 dvr0 + crw-rw---- 1 root video 212, 3 2007-08-07 15:33 frontend0 + crw-rw---- 1 root video 212, 7 2007-08-07 15:33 net0 -# make insmod +This shows that you need to be either root or in group "video" to be able to +use the DVB device. -UPDATE: the latest 2.6 kernels include the necessary drivers for most - cards, check on the linuxtv.org website for information about supported - cards, or read the documentation available in the linux kernel - sources (linux/Documentation/dvb/*). +You can find out if you're already in this group by using the "groups" +command in a terminal. If you aren't, then trying to use the DVB plugin will +cause a "no input plugin" error: this is somewhat misleading because the DVB +plugin was actually found but it failed because it couldn't open the device +nodes. -to load the generated modules into your running kernel. If everything went -fine, you should have something like +Adding yourself to group "video" is the best way; one of -DVB: registering new adapter (TT-Budget/WinTV-NOVA-S PCI). -PCI: Found IRQ 10 for device 00:0d.0 -PCI: Sharing IRQ 10 with 00:0c.0 -DVB: registering frontend 0:0 (stv0299 based (e.g. Alps BSRU6 or LG TDQB-S00x))... + # adduser fred video + $ sudo adduser fred video -in your dmesg. +will do the job for a user named "fred". Note that the change won't take +effect until after fred has logged out if he's currently logged in. -install a channel list +Install a channel list ---------------------- -xine's dvb input plugin needs a channel/transponder list that fits your -dvb equipment. xine now uses the channels.conf format of szap, czap and -tzap as appropriate for DVB-S, DVB-C and DVB-T. it will search the channel -list file in ~/.xine/channels.conf +xine-lib's dvb input plugin needs a channel/transponder list that fits your +dvb equipment. xine-lib uses the channels.conf format of szap, czap and tzap +as appropriate for DVB-S, DVB-C and DVB-T. It will search the channel list +file in ~/.xine/channels.conf. channel list format for DVB-S: (satellite) ------------------------------------------- @@ -64,80 +66,71 @@ WINSA :557500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64: \ station name:frequency:config options go on seemingly forever ... :vpid:apid:serviceid ------------------------------------------- -you automatically scan for all available channels using the scan utility -which comes with the dvb package. compile it using something like - -# cd linuxtv-dvb-1.0.0/apps/scan -# make - -then start scanning +You scan for all available channels using the scan utility which comes with +the dvb-apps package (also known as dvb-utils). See +http://www.linuxtv.org/wiki/index.php/Scan for more information. -# scan >~/.xine/channels.conf + $ scan /usr/share/doc/dvb-utils/examples/scan/dvb-t/uk-PontopPike >~/.xine/channels.conf + $ scan Hotbird-13.0 >~/.xine/channels.conf -newer versions of scan (after July 2004) are called dvbscan, but you can use it much the same way: +This can take a while. In a DiSEqC environment, use the -s N switch to +select different satellites to scan and paste the results in one big +channels.conf file. As always, please be sure to read the man page for the +version of the tool you are using. -# dvbscan Hotbird-13.0 >~/.xine/channels.conf +HINT: you might want to manually sort the channels.conf file to have your +favourite channels at the top and maybe remove any scrambled channels to +which you don't have access. -this can take a while. in a DiSEqC environment, use the -s N switch to select -different sattelites to scan and paste the results in one big channels.conf file. As always, -please be sure to read the man page for the version of the tool you are using. -HINT 1: you might want to manually sort the channels.conf file to have your favourite - channels at the top and maybe remove scrambled channels which you don't have access to. - - - ************************ If the dvb plugin doesn't seem to work for you ****************** -* if xine doesn't seem to work for you, double check to make sure that the channels.conf * -* file is _NOT_ in vdr format, which looks something like this: * -* WINSA:557500:I999B7C23D0M64T8G8Y0:T:27500:33:36:47:0:1:0:0:0 * - ****************************************************************************************** - -using xine to watch digital television +Using xine to watch digital television -------------------------------------- -make sure you have a recent libxine and frontend installed (latest CVS as of -this writing). then simply start something like +Make sure you have a recent libxine and front end installed, then simply +start something like -$ gxine dvb:// + $ gxine dvb:// -or click on the DVB button in xine-ui. you should be able to zap around using -the NumPad-9 / NumPad-3 keys, the xine playlist, or using the next/previous chapter -buttons in your gui. +or, perhaps, click on the DVB button in xine-ui. You should be able to zap +around using the NumPad-9 / NumPad-3 keys, the xine playlist, or using the +next/previous chapter buttons in your gui. -An OSD menu is available too. Press NumPad-8 / NumPad-2 to scroll -through the channels, then press NumPad-Enter to switch to the channel -you have selected. As of 06-12-2004, the channel list can be brought up and scrolled -through via the wheel on many mouses. Use the left mouse button to switch to -the channel you've selected. The side buttons (6 & 7) can be used to rapidly switch -to previous/next channels, if they are available on your mouse. +An OSD menu is available too. Press NumPad-8 / NumPad-2 to scroll through +the channels, then press NumPad-Enter to switch to the channel you have +selected. The channel list can be brought up and scrolled through via the +mouse wheel. Use the left mouse button to switch to the channel you've +selected. The side buttons (6 & 7) can be used to rapidly switch to +previous/next channels, if they are available on your mouse. -You can use MENU3 (F2 in xine-ui, F3 in gxine) to zoom into the centre of a videostream. -This will allow you to view 4:3 content that has been embedded into a -16:9 stream in fullscreen (no more black borders). Press the key again -to return to normal viewing. There is also an option in the xine +You can use MENU3 (F2 in xine-ui, F3 in gxine) to zoom into the centre of a +videostream. This will allow you to view 4:3 content that has been embedded +into a 16:9 stream in fullscreen (no more black borders). Press the key +again to return to normal viewing. There is also an option in the xine preferences to zoom automatically when using xine to view DVB. -MENU7 (F6 in xine-ui or F7 in gxine) will toggle viewing of the current channels' -Electronic Program Guide (information on the current/next program) on the OSD, if available. +MENU7 (F6 in xine-ui or F7 in gxine) will toggle viewing of the current +channel's Electronic Program Guide (information on the current/next program) +on the OSD, if available. -HINT: if audio or video is stuttering, pause (space key) shortly -to give xine a chance to fill up it's buffers. If watching a large HDTV stream, you -may need to increase the xine video & audio buffer size - increasing audio buffers to -300 and video buffers to 700 has been known to work with streams up to 1920x1088 in size. +HINT: if audio or video is stuttering, pause (space key) shortly to give +xine-lib a chance to fill its buffers. If watching a large HDTV stream, you +may need to increase the xine video & audio buffer size - increasing audio +buffers to 300 and video buffers to 700 has been known to work with streams +up to 1920x1088 in size. -recording digital television +Recording digital television ---------------------------- -there is a very simple vcr-like feature built into the xine engine. just press -MENU2 (that is F2 in gxine, or F1 in xine-ui for example) to start/stop recording -the currently displayed program to your local disc. a small osd in the upper -left corner of your screen will tell you the file name the recorded stream is -written to. You can select the directory to save to in the xine configuration under -the MISC tab, otherwise the plugin will record to your home directory. You can -pause the recording at any time by pressing MENU4 (F3 in xine-ui, F4 in gxine). -An OSD in the top left hand corner will notify you of the status of the recording. +There is a very simple VCR-like feature built into the xine engine. just +press MENU2 (that is F2 in gxine, or F1 in xine-ui for example) to +start/stop recording the currently displayed program to your local disc. A +small OSD message in the upper left corner of your screen will tell you the +file name the recorded stream is being written to. You can select the +directory to save to in the xine configuration under the MISC tab, otherwise +the plugin will record to your home directory. You can pause the recording +at any time by pressing MENU4 (F3 in xine-ui, F4 in gxine). An OSD in the +top left hand corner will notify you of the status of the recording. Pressing MENU4 again will resume recording. Have fun. - -- 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. --- ChangeLog | 1 + 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 +++++-- 5 files changed, 121 insertions(+), 52 deletions(-) diff --git a/ChangeLog b/ChangeLog index c73a1131d..680dba142 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,7 @@ xine-lib (1.1.8) (Unreleased) * Fix a crash with "dvb:/". * DVB subtitle fixes: deadlock prevention, thread leakage, spec compliance. * Allow the DVB input plugin to timeout if it is receiving no signal. + * Fix an audio resampling problem which was causing regular clicking. xine-lib (1.1.7) * Support libdca (new name for libdts) by shuffling around the dts.h file. 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