diff options
author | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2007-08-16 16:29:26 +0100 |
---|---|---|
committer | Darren Salt <linux@youmustbejoking.demon.co.uk> | 2007-08-16 16:29:26 +0100 |
commit | d3e91bb09c694dc8a71b77f098ab251755763410 (patch) | |
tree | 1e2d82197a62813e8dd0b49e112e1b0f965fc5bd | |
parent | f43c0bf92a48824ed075473e9035d4c0dfe5cf33 (diff) | |
parent | 7047d9e5acf97c91a523c99ccc4b008a35a3e094 (diff) | |
download | xine-lib-d3e91bb09c694dc8a71b77f098ab251755763410.tar.gz xine-lib-d3e91bb09c694dc8a71b77f098ab251755763410.tar.bz2 |
Merge all but the open()/glibc workaround from 1.1.
-rw-r--r-- | .hgignore | 6 | ||||
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | TODO | 1 | ||||
-rwxr-xr-x | debian/rules | 1 | ||||
-rw-r--r-- | doc/README.dvb | 168 | ||||
-rw-r--r-- | include/xine.h.in | 10 | ||||
-rw-r--r-- | src/input/input_dvd.c | 8 | ||||
-rw-r--r-- | src/post/audio/stretch.c | 10 | ||||
-rw-r--r-- | src/post/goom/xine_goom.c | 112 | ||||
-rw-r--r-- | src/video_out/video_out_xcbxv.c | 2 | ||||
-rw-r--r-- | src/video_out/video_out_xv.c | 2 | ||||
-rw-r--r-- | src/xine-engine/audio_out.c | 30 | ||||
-rw-r--r-- | src/xine-engine/configfile.c | 39 | ||||
-rw-r--r-- | src/xine-engine/resample.c | 115 | ||||
-rw-r--r-- | src/xine-engine/resample.h | 17 |
15 files changed, 328 insertions, 203 deletions
@@ -43,6 +43,7 @@ debian/files debian/libxine-dev debian/libxine2 debian/libxine2-dbg +debian/libxine2-doc debian/tmp debian/*.debhelper debian/*.substvars @@ -80,3 +81,8 @@ po/insert-header.sed po/remove-potcdate.sed src/libffmpeg/ffmpeg_config.h +src/video_out/libdha/pci_dev_ids.c +src/video_out/libdha/pci_ids.h +src/video_out/libdha/pci_names.[ch] +src/video_out/libdha/pci_vendors.h + @@ -46,6 +46,16 @@ 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. + * 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. + * 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. @@ -28,6 +28,7 @@ known bugs - frame allocation problem with h264 streams using > 15 reference frames - dvdnav time search function does not use the time table, but interpolates only cell times +- apparently, dvb:// (but not dvb://CHANNEL) is broken for ATSC requested/planned features diff --git a/debian/rules b/debian/rules index fd9d1fafe..c6e8cbd8f 100755 --- a/debian/rules +++ b/debian/rules @@ -68,6 +68,7 @@ CONFIGURE_FLAGS := --prefix=/usr \ --with-external-libmad \ --with-external-a52dec \ --with-external-libdts \ + --with-freetype \ --with-wavpack \ $(DEB_BUILD_CONFIG_OPTIONS) \ CFLAGS="$(CFLAGS)" diff --git a/doc/README.dvb b/doc/README.dvb index 9de8295aa..055bc2cfa 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 ~/.config/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 ~/.config/xine/channels.conf. channel list format for DVB-S: (satellite) ------------------------------------------- @@ -64,79 +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 - -# scan >~/.config/xine/channels.conf - -newer versions of scan (after July 2004) are called dvbscan, but you can use it much the same way: - -# dvbscan Hotbird-13.0 >~/.config/xine/channels.conf +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. -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. + $ scan /usr/share/doc/dvb-utils/examples/scan/dvb-t/uk-PontopPike >~/.config/xine/channels.conf + $ scan Hotbird-13.0 >~/.config/xine/channels.conf -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. +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. +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. - ************************ 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. diff --git a/include/xine.h.in b/include/xine.h.in index 5f916bd5a..04f35f680 100644 --- a/include/xine.h.in +++ b/include/xine.h.in @@ -1533,6 +1533,16 @@ 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) */ void xine_config_load (xine_t *self, const char *cfg_filename) XINE_PROTECTED; diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c index c55ff8726..4f1fc3fb2 100644 --- a/src/input/input_dvd.c +++ b/src/input/input_dvd.c @@ -1482,14 +1482,14 @@ 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_cfg_entry_t region_entry, lang_entry, cfg_entry; 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=<title>&part=<part> stuff and to expand @@ -1505,11 +1505,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) 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/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 ); + } + } } diff --git a/src/video_out/video_out_xcbxv.c b/src/video_out/video_out_xcbxv.c index 21a8b6a39..4cb57156d 100644 --- a/src/video_out/video_out_xcbxv.c +++ b/src/video_out/video_out_xcbxv.c @@ -1245,7 +1245,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, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards"); + xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": 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 894192c6b..aca59e8d1 100644 --- a/src/video_out/video_out_xv.c +++ b/src/video_out/video_out_xv.c @@ -1298,7 +1298,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, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards"); + xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": 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, diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c index 75cef4ce6..376ceee0b 100644 --- a/src/xine-engine/audio_out.c +++ b/src/xine-engine/audio_out.c @@ -253,6 +253,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/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, @@ -895,6 +898,14 @@ static void config_update_string (config_values_t *this, } /* + * 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) */ void xine_config_load (xine_t *xine, const char *filename) { 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, |